diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md
index 6c1de31c1b2..6a22a1cca73 100644
--- a/.github/ISSUE_TEMPLATE/bug_report.md
+++ b/.github/ISSUE_TEMPLATE/bug_report.md
@@ -2,7 +2,7 @@
name: Bug report
about: Create a report to help us improve F#
title: ''
-labels: Bug
+labels: [Bug, Needs-Triage]
assignees: ''
---
diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml
deleted file mode 100644
index f10d1a55e5a..00000000000
--- a/.github/ISSUE_TEMPLATE/bug_report.yml
+++ /dev/null
@@ -1,69 +0,0 @@
-name: Bug report
-description: Create a report to help us improve F#
-title: "`Bug`: "
-labels: [Needs Triage]
-body:
-- type: checkboxes
- attributes:
- label: Is there an existing issue for this?
- description: Please search to see if an issue already exists for the bug you encountered.
- options:
- - label: I have searched the existing issues
- required: true
-- type: textarea
- attributes:
- label: Issue description
- description: Please provide a succinct description of the issue you're experiencing.
- validations:
- required: true
-- type: textarea
- attributes:
- label: Steps To Reproduce
- description: Provide the steps required to reproduce the problem.
- placeholder: |
- 1. Step A
- 2. Step B...
- validations:
- required: false
-- type: textarea
- attributes:
- label: Expected Behavior
- description: Provide a description of the expected behavior.
- validations:
- required: true
-- type: textarea
- attributes:
- label: Actual Behavior
- description: Provide a description of the actual behaviour observed.
- validations:
- required: true
-- type: textarea
- attributes:
- label: Known workarounds
- description: Provide a description of the actual behaviour observed.
- validations:
- required: false
-- type: textarea
- attributes:
- label: Related information
- description: |
- Provide any related information (optional), examples:
- - **OS**: Windows 11
- - **.NET Runtime Kind and version**: .NET Framework 4.8 and .NET 7
- - **Tooling**: Visual Studio 2022
- value: |
- - OS:
- - .NET Runtime Kind and version:
- - Tooling:
- render: markdown
- validations:
- required: false
-- type: textarea
- attributes:
- label: Anything else?
- description: |
- Links? References? Anything that will give us more context about the issue you are encountering!
-
- Tip: You can attach images or log files by clicking this area to highlight it and then dragging files in.
- validations:
- required: false
diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md
index 1397683d28c..9902369d951 100644
--- a/.github/ISSUE_TEMPLATE/feature_request.md
+++ b/.github/ISSUE_TEMPLATE/feature_request.md
@@ -2,7 +2,7 @@
name: Feature request
about: Suggest an idea for the F# tools or compiler
title: ''
-labels: Feature Request
+labels: [Feature Request, Needs-Triage]
assignees: ''
---
diff --git a/.github/ISSUE_TEMPLATE/other_issue.md b/.github/ISSUE_TEMPLATE/other_issue.md
new file mode 100644
index 00000000000..9f737b857bc
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/other_issue.md
@@ -0,0 +1,10 @@
+---
+name: Other issue
+about: Open an issue which does not belong to any categories above
+title: ''
+labels: [Needs-Triage]
+assignees: ''
+
+---
+
+
diff --git a/DEVGUIDE.md b/DEVGUIDE.md
index 2f7d899e329..da02c907c22 100644
--- a/DEVGUIDE.md
+++ b/DEVGUIDE.md
@@ -44,12 +44,12 @@ This will update your fork with the latest from `dotnet/fsharp` on your machine
## Developing on Windows
-Install the latest released [Visual Studio](https://www.visualstudio.com/downloads/), as that is what the `main` branch's tools are synced with. Select the following workloads:
+Install the latest released [Visual Studio](https://visualstudio.microsoft.com/vs/preview/) preview, as that is what the `main` branch's tools are synced with. Select the following workloads:
* .NET desktop development (also check F# desktop support, as this will install some legacy templates)
* Visual Studio extension development
-You will also need the latest .NET 6 SDK installed from [here](https://dotnet.microsoft.com/download/dotnet/6.0).
+You will also need the latest .NET 7 SDK installed from [here](https://dotnet.microsoft.com/download/dotnet/7.0).
Building is simple:
@@ -73,10 +73,10 @@ If you don't have everything installed yet, you'll get prompted by Visual Studio
If you are just developing the core compiler and library then building ``FSharp.sln`` will be enough.
-We recommend installing the latest released Visual Studio and using that if you are on Windows. However, if you prefer not to do that, you will need to install the following:
+We recommend installing the latest Visual Studio preview and using that if you are on Windows. However, if you prefer not to do that, you will need to install the following:
* [.NET Framework 4.7.2](https://dotnet.microsoft.com/download/dotnet-framework/net472)
-* [.NET 6](https://dotnet.microsoft.com/download/dotnet/6.0)
+* [.NET 7](https://dotnet.microsoft.com/download/dotnet/7.0)
You'll need to pass an additional flag to the build script:
diff --git a/README.md b/README.md
index 3107814f512..2026df28022 100644
--- a/README.md
+++ b/README.md
@@ -1,8 +1,11 @@
# The F# compiler, F# core library, and F# editor tools
+[](https://dev.azure.com/dnceng-public/public/_build/latest?definitionId=90&branchName=main)
+[](https://github.com/dotnet/runtime/labels/help%20wanted)
+
You're invited to contribute to future releases of the F# compiler, core library, and tools. Development of this repository can be done on any OS supported by [.NET](https://dotnet.microsoft.com/).
-You will also need the latest .NET 6 SDK installed from [here](https://dotnet.microsoft.com/download/dotnet/6.0).
+You will also need the latest .NET 7 SDK installed from [here](https://dotnet.microsoft.com/download/dotnet/7.0).
## Contributing
@@ -54,12 +57,6 @@ After it's finished, open `FSharp.sln` in your editor of choice.
Even if you find a single-character typo, we're happy to take the change! Although the codebase can feel daunting for beginners, we and other contributors are happy to help you along.
-## Build Status
-
-| Branch | Status |
-|:------:|:------:|
-|main|[](https://dev.azure.com/dnceng/public/_build/latest?definitionId=496&branchName=main)|
-
## Per-build NuGet packages
Per-build [versions](https://dev.azure.com/dnceng/public/_packaging?_a=package&feed=dotnet-tools&view=versions&package=FSharp.Compiler.Service&protocolType=NuGet) of our NuGet packages are available via this URL: `https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools/nuget/v3/index.json`
diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml
index 80e7ef74b8e..a129a95dffa 100644
--- a/eng/Version.Details.xml
+++ b/eng/Version.Details.xml
@@ -8,14 +8,14 @@
-
+ https://github.com/dotnet/arcade
- ba4d2568dd2e3e7538feeaba60215f7bcb99e89c
+ d2d39276af2db3da7816ee2dc543e120d7e5781e
-
+ https://github.com/dotnet/arcade
- ba4d2568dd2e3e7538feeaba60215f7bcb99e89c
+ d2d39276af2db3da7816ee2dc543e120d7e5781e
diff --git a/eng/common/cross/build-rootfs.sh b/eng/common/cross/build-rootfs.sh
index 5680980fa29..eddb4c380af 100755
--- a/eng/common/cross/build-rootfs.sh
+++ b/eng/common/cross/build-rootfs.sh
@@ -391,9 +391,9 @@ elif [[ "$__CodeName" == "illumos" ]]; then
--with-gnu-ld --disable-nls --disable-libgomp --disable-libquadmath --disable-libssp --disable-libvtv --disable-libcilkrts --disable-libada --disable-libsanitizer \
--disable-libquadmath-support --disable-shared --enable-tls
make -j "$JOBS" && make install && cd ..
- BaseUrl=https://pkgsrc.joyent.com
+ BaseUrl=https://pkgsrc.smartos.org
if [[ "$__UseMirror" == 1 ]]; then
- BaseUrl=http://pkgsrc.smartos.skylime.net
+ BaseUrl=https://pkgsrc.smartos.skylime.net
fi
BaseUrl="$BaseUrl/packages/SmartOS/trunk/${__illumosArch}/All"
echo "Downloading manifest"
@@ -402,7 +402,8 @@ elif [[ "$__CodeName" == "illumos" ]]; then
read -ra array <<<"$__IllumosPackages"
for package in "${array[@]}"; do
echo "Installing '$package'"
- package="$(grep ">$package-[0-9]" All | sed -En 's/.*href="(.*)\.tgz".*/\1/p')"
+ # find last occurrence of package in listing and extract its name
+ package="$(sed -En '/.*href="('"$package"'-[0-9].*).tgz".*/h;$!d;g;s//\1/p' All)"
echo "Resolved name '$package'"
wget "$BaseUrl"/"$package".tgz
ar -x "$package".tgz
diff --git a/eng/common/init-tools-native.ps1 b/eng/common/init-tools-native.ps1
index ac42f04a9d8..fbc67effc36 100644
--- a/eng/common/init-tools-native.ps1
+++ b/eng/common/init-tools-native.ps1
@@ -113,6 +113,7 @@ try {
$ToolPath = Convert-Path -Path $BinPath
Write-Host "Adding $ToolName to the path ($ToolPath)..."
Write-Host "##vso[task.prependpath]$ToolPath"
+ $env:PATH = "$ToolPath;$env:PATH"
$InstalledTools += @{ $ToolName = $ToolDirectory.FullName }
}
}
diff --git a/eng/common/templates/job/execute-sdl.yml b/eng/common/templates/job/execute-sdl.yml
index 781a41c9404..65f87b40c66 100644
--- a/eng/common/templates/job/execute-sdl.yml
+++ b/eng/common/templates/job/execute-sdl.yml
@@ -34,7 +34,7 @@ jobs:
- job: Run_SDL
dependsOn: ${{ parameters.dependsOn }}
displayName: Run SDL tool
- condition: eq( ${{ parameters.enable }}, 'true')
+ condition: and(succeededOrFailed(), eq( ${{ parameters.enable }}, 'true'))
variables:
- group: DotNet-VSTS-Bot
- name: AzDOProjectName
diff --git a/eng/common/templates/job/job.yml b/eng/common/templates/job/job.yml
index 459f3c4fcbb..9f55d3f4666 100644
--- a/eng/common/templates/job/job.yml
+++ b/eng/common/templates/job/job.yml
@@ -25,6 +25,7 @@ parameters:
enablePublishTestResults: false
enablePublishUsingPipelines: false
disableComponentGovernance: false
+ componentGovernanceIgnoreDirectories: ''
mergeTestResults: false
testRunTitle: ''
testResultsFormat: ''
@@ -146,6 +147,8 @@ jobs:
- ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest'), ne(parameters.disableComponentGovernance, 'true')) }}:
- task: ComponentGovernanceComponentDetection@0
continueOnError: true
+ inputs:
+ ignoreDirectories: ${{ parameters.componentGovernanceIgnoreDirectories }}
- ${{ if eq(parameters.enableMicrobuild, 'true') }}:
- ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}:
@@ -223,4 +226,5 @@ jobs:
parameters:
PackageVersion: ${{ parameters.packageVersion}}
BuildDropPath: ${{ parameters.buildDropPath }}
+ IgnoreDirectories: ${{ parameters.componentGovernanceIgnoreDirectories }}
diff --git a/eng/common/templates/jobs/source-build.yml b/eng/common/templates/jobs/source-build.yml
index 8dd2d355f22..bcd8279944b 100644
--- a/eng/common/templates/jobs/source-build.yml
+++ b/eng/common/templates/jobs/source-build.yml
@@ -14,7 +14,7 @@ parameters:
# This is the default platform provided by Arcade, intended for use by a managed-only repo.
defaultManagedPlatform:
name: 'Managed'
- container: 'mcr.microsoft.com/dotnet-buildtools/prereqs:centos-stream8-20220809204800-17a4aab'
+ container: 'mcr.microsoft.com/dotnet-buildtools/prereqs:centos-stream8-latest'
# Defines the platforms on which to run build jobs. One job is created for each platform, and the
# object in this array is sent to the job template as 'platform'. If no platforms are specified,
diff --git a/eng/common/templates/post-build/post-build.yml b/eng/common/templates/post-build/post-build.yml
index 87fcae940cf..258ed2d1108 100644
--- a/eng/common/templates/post-build/post-build.yml
+++ b/eng/common/templates/post-build/post-build.yml
@@ -98,7 +98,7 @@ stages:
jobs:
- job:
displayName: NuGet Validation
- condition: eq( ${{ parameters.enableNugetValidation }}, 'true')
+ condition: and(succeededOrFailed(), eq( ${{ parameters.enableNugetValidation }}, 'true'))
pool:
# We don't use the collection uri here because it might vary (.visualstudio.com vs. dev.azure.com)
${{ if eq(variables['System.TeamProject'], 'DevDiv') }}:
@@ -282,4 +282,4 @@ stages:
-MaestroToken '$(MaestroApiAccessToken)'
-WaitPublishingFinish true
-ArtifactsPublishingAdditionalParameters '${{ parameters.artifactsPublishingAdditionalParameters }}'
- -SymbolPublishingAdditionalParameters '${{ parameters.symbolPublishingAdditionalParameters }}'
\ No newline at end of file
+ -SymbolPublishingAdditionalParameters '${{ parameters.symbolPublishingAdditionalParameters }}'
diff --git a/eng/common/templates/steps/generate-sbom.yml b/eng/common/templates/steps/generate-sbom.yml
index 4cea8c33187..a06373f38fa 100644
--- a/eng/common/templates/steps/generate-sbom.yml
+++ b/eng/common/templates/steps/generate-sbom.yml
@@ -2,12 +2,14 @@
# PackageName - The name of the package this SBOM represents.
# PackageVersion - The version of the package this SBOM represents.
# ManifestDirPath - The path of the directory where the generated manifest files will be placed
+# IgnoreDirectories - Directories to ignore for SBOM generation. This will be passed through to the CG component detector.
parameters:
PackageVersion: 7.0.0
BuildDropPath: '$(Build.SourcesDirectory)/artifacts'
PackageName: '.NET'
ManifestDirPath: $(Build.ArtifactStagingDirectory)/sbom
+ IgnoreDirectories: ''
sbomContinueOnError: true
steps:
@@ -34,6 +36,8 @@ steps:
BuildDropPath: ${{ parameters.buildDropPath }}
PackageVersion: ${{ parameters.packageVersion }}
ManifestDirPath: ${{ parameters.manifestDirPath }}
+ ${{ if ne(parameters.IgnoreDirectories, '') }}:
+ AdditionalComponentDetectorArgs: '--IgnoreDirectories ${{ parameters.IgnoreDirectories }}'
- task: PublishPipelineArtifact@1
displayName: Publish SBOM manifest
diff --git a/eng/common/templates/steps/source-build.yml b/eng/common/templates/steps/source-build.yml
index 4ec5577d28a..a97a185a367 100644
--- a/eng/common/templates/steps/source-build.yml
+++ b/eng/common/templates/steps/source-build.yml
@@ -63,6 +63,11 @@ steps:
targetRidArgs='/p:TargetRid=${{ parameters.platform.targetRID }}'
fi
+ runtimeOsArgs=
+ if [ '${{ parameters.platform.runtimeOS }}' != '' ]; then
+ runtimeOsArgs='/p:RuntimeOS=${{ parameters.platform.runtimeOS }}'
+ fi
+
publishArgs=
if [ '${{ parameters.platform.skipPublishValidation }}' != 'true' ]; then
publishArgs='--publish'
@@ -80,6 +85,7 @@ steps:
$internalRuntimeDownloadArgs \
$internalRestoreArgs \
$targetRidArgs \
+ $runtimeOsArgs \
/p:SourceBuildNonPortable=${{ parameters.platform.nonPortable }} \
/p:ArcadeBuildFromSource=true \
/p:AssetManifestFileName=$assetManifestFileName
diff --git a/global.json b/global.json
index ed1a0361528..f44a501cf14 100644
--- a/global.json
+++ b/global.json
@@ -18,7 +18,7 @@
"perl": "5.32.1.1"
},
"msbuild-sdks": {
- "Microsoft.DotNet.Arcade.Sdk": "8.0.0-beta.22473.1",
- "Microsoft.DotNet.Helix.Sdk": "8.0.0-beta.22473.1"
+ "Microsoft.DotNet.Arcade.Sdk": "8.0.0-beta.22503.1",
+ "Microsoft.DotNet.Helix.Sdk": "8.0.0-beta.22503.1"
}
}
diff --git a/src/Compiler/Checking/AttributeChecking.fs b/src/Compiler/Checking/AttributeChecking.fs
index d1d50393523..de1aadfc803 100644
--- a/src/Compiler/Checking/AttributeChecking.fs
+++ b/src/Compiler/Checking/AttributeChecking.fs
@@ -412,6 +412,9 @@ let CheckEntityAttributes g (tcref: TyconRef) m =
CheckILAttributes g (isByrefLikeTyconRef g m tcref) tcref.ILTyconRawMetadata.CustomAttrs m
else
CheckFSharpAttributes g tcref.Attribs m
+
+let CheckILEventAttributes g (tcref: TyconRef) cattrs m =
+ CheckILAttributes g (isByrefLikeTyconRef g m tcref) cattrs m
/// Check the attributes associated with a method, returning warnings and errors as data.
let CheckMethInfoAttributes g m tyargsOpt (minfo: MethInfo) =
@@ -507,7 +510,8 @@ let CheckUnionCaseAttributes g (x:UnionCaseRef) m =
/// Check the attributes on a record field, returning errors and warnings as data.
let CheckRecdFieldAttributes g (x:RecdFieldRef) m =
CheckEntityAttributes g x.TyconRef m ++ (fun () ->
- CheckFSharpAttributes g x.PropertyAttribs m)
+ CheckFSharpAttributes g x.PropertyAttribs m) ++ (fun () ->
+ CheckFSharpAttributes g x.RecdField.FieldAttribs m)
/// Check the attributes on an F# value, returning errors and warnings as data.
let CheckValAttributes g (x:ValRef) m =
diff --git a/src/Compiler/Checking/AttributeChecking.fsi b/src/Compiler/Checking/AttributeChecking.fsi
index 3236d3bfdbe..622864eff4e 100644
--- a/src/Compiler/Checking/AttributeChecking.fsi
+++ b/src/Compiler/Checking/AttributeChecking.fsi
@@ -101,3 +101,5 @@ val IsSecurityAttribute:
val IsSecurityCriticalAttribute: g: TcGlobals -> Attrib -> bool
val IsAssemblyVersionAttribute: g: TcGlobals -> Attrib -> bool
+
+val CheckILEventAttributes: g: TcGlobals -> tcref: TyconRef -> cattrs: ILAttributes -> m: range -> OperationResult
diff --git a/src/Compiler/Checking/CheckDeclarations.fs b/src/Compiler/Checking/CheckDeclarations.fs
index 1081998708b..ac0080ca829 100644
--- a/src/Compiler/Checking/CheckDeclarations.fs
+++ b/src/Compiler/Checking/CheckDeclarations.fs
@@ -545,6 +545,7 @@ module TcRecdUnionAndEnumDeclarations =
let TcEnumDecl cenv env parent thisTy fieldTy (SynEnumCase(attributes=Attributes synAttrs; ident= SynIdent(id,_); value=v; xmlDoc=xmldoc; range=m)) =
let attrs = TcAttributes cenv env AttributeTargets.Field synAttrs
+
match v with
| SynConst.Bytes _
| SynConst.UInt16s _
diff --git a/src/Compiler/Checking/CheckExpressions.fs b/src/Compiler/Checking/CheckExpressions.fs
index 1b65421daba..bd675aba272 100644
--- a/src/Compiler/Checking/CheckExpressions.fs
+++ b/src/Compiler/Checking/CheckExpressions.fs
@@ -9095,7 +9095,9 @@ and TcEventItemThen (cenv: cenv) overallTy env tpenv mItem mExprAndItem objDetai
let (SigOfFunctionForDelegate(delInvokeMeth, delArgTys, _, _)) = GetSigOfFunctionForDelegate cenv.infoReader delTy mItem ad
let objArgs = Option.toList (Option.map fst objDetails)
MethInfoChecks g cenv.amap true None objArgs env.eAccessRights mItem delInvokeMeth
-
+
+ CheckILEventAttributes g einfo.DeclaringTyconRef (einfo.GetCustomAttrs()) mItem |> CommitOperationResult
+
// This checks for and drops the 'object' sender
let argsTy = ArgsTypeOfEventInfo cenv.infoReader mItem ad einfo
if not (slotSigHasVoidReturnTy (delInvokeMeth.GetSlotSig(cenv.amap, mItem))) then errorR (nonStandardEventError einfo.EventName mItem)
diff --git a/src/Compiler/Checking/CheckPatterns.fs b/src/Compiler/Checking/CheckPatterns.fs
index dccff65781b..70382723f92 100644
--- a/src/Compiler/Checking/CheckPatterns.fs
+++ b/src/Compiler/Checking/CheckPatterns.fs
@@ -289,6 +289,11 @@ and TcPat warnOnUpper (cenv: cenv) env valReprInfo vFlags (patEnv: TcPatLinearEn
| SynPat.Or (pat1, pat2, m, _) ->
TcPatOr warnOnUpper cenv env vFlags patEnv ty pat1 pat2 m
+ | SynPat.ListCons(pat1, pat2, m, trivia) ->
+ let longDotId = SynLongIdent((mkSynCaseName trivia.ColonColonRange opNameCons), [], [Some (FSharp.Compiler.SyntaxTrivia.IdentTrivia.OriginalNotation "::")])
+ let args = SynArgPats.Pats [ SynPat.Tuple(false, [ pat1; pat2 ], m) ]
+ TcPatLongIdent warnOnUpper cenv env ad valReprInfo vFlags patEnv ty (longDotId, None, args, None, m)
+
| SynPat.Ands (pats, m) ->
TcPatAnds warnOnUpper cenv env vFlags patEnv ty pats m
@@ -471,13 +476,13 @@ and TcNullPat cenv env patEnv ty m =
and CheckNoArgsForLiteral args m =
match args with
| SynArgPats.Pats []
- | SynArgPats.NamePatPairs ([], _) -> ()
+ | SynArgPats.NamePatPairs (pats = []) -> ()
| _ -> errorR (Error (FSComp.SR.tcLiteralDoesNotTakeArguments (), m))
and GetSynArgPatterns args =
match args with
| SynArgPats.Pats args -> args
- | SynArgPats.NamePatPairs (pairs, _) -> List.map (fun (_, _, pat) -> pat) pairs
+ | SynArgPats.NamePatPairs (pats = pairs) -> List.map (fun (_, _, pat) -> pat) pairs
and TcArgPats warnOnUpper (cenv: cenv) env vFlags patEnv args =
let g = cenv.g
@@ -565,7 +570,7 @@ and ApplyUnionCaseOrExn m (cenv: cenv) env overallTy item =
UnifyTypes cenv env m overallTy g.exn_ty
CheckTyconAccessible cenv.amap m ad ecref |> ignore
let mkf mArgs args = TPat_exnconstr(ecref, args, unionRanges m mArgs)
- mkf, recdFieldTysOfExnDefRef ecref, [ for f in (recdFieldsOfExnDefRef ecref) -> f.Id ]
+ mkf, recdFieldTysOfExnDefRef ecref, [ for f in (recdFieldsOfExnDefRef ecref) -> f ]
| Item.UnionCase(ucinfo, showDeprecated) ->
if showDeprecated then
@@ -582,7 +587,7 @@ and ApplyUnionCaseOrExn m (cenv: cenv) env overallTy item =
let inst = mkTyparInst ucref.TyconRef.TyparsNoRange ucinfo.TypeInst
UnifyTypes cenv env m overallTy resTy
let mkf mArgs args = TPat_unioncase(ucref, ucinfo.TypeInst, args, unionRanges m mArgs)
- mkf, actualTysOfUnionCaseFields inst ucref, [ for f in ucref.AllFieldsAsList -> f.Id ]
+ mkf, actualTysOfUnionCaseFields inst ucref, [ for f in ucref.AllFieldsAsList -> f]
| _ ->
invalidArg "item" "not a union case or exception reference"
@@ -600,7 +605,7 @@ and TcPatLongIdentUnionCaseOrExnCase warnOnUpper cenv env ad vFlags patEnv ty (m
let args, extraPatternsFromNames =
match args with
| SynArgPats.Pats args -> args, []
- | SynArgPats.NamePatPairs (pairs, m) ->
+ | SynArgPats.NamePatPairs (pairs, m, _) ->
// rewrite patterns from the form (name-N = pat-N; ...) to (..._, pat-N, _...)
// so type T = Case of name: int * value: int
// | Case(value = v)
@@ -610,7 +615,7 @@ and TcPatLongIdentUnionCaseOrExnCase warnOnUpper cenv env ad vFlags patEnv ty (m
let extraPatterns = List ()
for id, _, pat in pairs do
- match argNames |> List.tryFindIndex (fun id2 -> id.idText = id2.idText) with
+ match argNames |> List.tryFindIndex (fun id2 -> id.idText = id2.Id.idText) with
| None ->
extraPatterns.Add pat
match item with
@@ -678,7 +683,14 @@ and TcPatLongIdentUnionCaseOrExnCase warnOnUpper cenv env ad vFlags patEnv ty (m
elif numArgs < numArgTys then
if numArgTys > 1 then
// Expects tuple without enough args
- errorR (Error (FSComp.SR.tcUnionCaseExpectsTupledArguments numArgTys, m))
+ let printTy = NicePrint.minimalStringOfType env.DisplayEnv
+ let missingArgs =
+ argNames.[numArgs..numArgTys - 1]
+ |> List.map (fun id -> (if id.rfield_name_generated then "" else id.DisplayName + ": ") + printTy id.FormalType)
+ |> String.concat (Environment.NewLine + "\t")
+ |> fun s -> Environment.NewLine + "\t" + s
+
+ errorR (Error (FSComp.SR.tcUnionCaseExpectsTupledArguments(numArgTys, numArgs, missingArgs), m))
else
errorR (UnionCaseWrongArguments (env.DisplayEnv, numArgTys, numArgs, m))
args @ (List.init (numArgTys - numArgs) (fun _ -> SynPat.Wild (m.MakeSynthetic()))), extraPatterns
diff --git a/src/Compiler/Checking/PatternMatchCompilation.fs b/src/Compiler/Checking/PatternMatchCompilation.fs
index 0b0a5e0624f..2c53c73202e 100644
--- a/src/Compiler/Checking/PatternMatchCompilation.fs
+++ b/src/Compiler/Checking/PatternMatchCompilation.fs
@@ -143,7 +143,6 @@ let GetSubExprOfInput g (gtps, tyargs, tinst) (SubExpr(accessf, (ve2, v2))) =
// The ints record which choices taken, e.g. tuple/record fields.
type Path =
| PathQuery of Path * Unique
- | PathConj of Path * int
| PathTuple of Path * TypeInst * int
| PathRecd of Path * TyconRef * TypeInst * int
| PathUnionConstr of Path * UnionCaseRef * TypeInst * int
@@ -154,7 +153,6 @@ type Path =
let rec pathEq p1 p2 =
match p1, p2 with
| PathQuery(p1, n1), PathQuery(p2, n2) -> (n1 = n2) && pathEq p1 p2
- | PathConj(p1, n1), PathConj(p2, n2) -> (n1 = n2) && pathEq p1 p2
| PathTuple(p1, _, n1), PathTuple(p2, _, n2) -> (n1 = n2) && pathEq p1 p2
| PathRecd(p1, _, _, n1), PathRecd(p2, _, _, n2) -> (n1 = n2) && pathEq p1 p2
| PathUnionConstr(p1, _, _, n1), PathUnionConstr(p2, _, _, n2) -> (n1 = n2) && pathEq p1 p2
@@ -203,8 +201,6 @@ let RefuteDiscrimSet g m path discrims =
let rec go path tm =
match path with
| PathQuery _ -> raise CannotRefute
- | PathConj (p, _j) ->
- go p tm
| PathTuple (p, tys, j) ->
let k, eCoversVals = mkOneKnown tm j tys
go p (fun _ -> mkRefTupled g m k tys, eCoversVals)
@@ -391,8 +387,6 @@ type Frontier = Frontier of ClauseNumber * Actives * ValMap
type InvestigationPoint = Investigation of ClauseNumber * DecisionTreeTest * Path
// Note: actives must be a SortedDictionary
-// REVIEW: improve these data structures, though surprisingly these functions don't tend to show up
-// on profiling runs
let rec isMemOfActives p1 actives =
match actives with
| [] -> false
@@ -1624,7 +1618,7 @@ let CompilePatternBasic
subPats |> List.collect (fun subPat -> BindProjectionPattern (Active(inpPath, inpExpr, subPat)) activeState)
| TPat_conjs(subPats, _m) ->
- let newActives = List.mapi (mkSubActive (fun path j -> PathConj(path, j)) (fun _j -> inpAccess)) subPats
+ let newActives = List.mapi (mkSubActive (fun path _j -> path) (fun _j -> inpAccess)) subPats
BindProjectionPatterns newActives activeState
| TPat_range (c1, c2, m) ->
diff --git a/src/Compiler/Checking/infos.fs b/src/Compiler/Checking/infos.fs
index 1c0612eb611..68e844fa919 100644
--- a/src/Compiler/Checking/infos.fs
+++ b/src/Compiler/Checking/infos.fs
@@ -438,6 +438,11 @@ type ILTypeInfo =
member x.IsValueType = x.RawMetadata.IsStructOrEnum
+ /// Indicates if the type is marked with the [] attribute.
+ member x.IsReadOnly (g: TcGlobals) =
+ x.RawMetadata.CustomAttrs
+ |> TryFindILAttribute g.attrib_IsReadOnlyAttribute
+
member x.Instantiate inst =
let (ILTypeInfo(g, ty, tref, tdef)) = x
ILTypeInfo(g, instType inst ty, tref, tdef)
@@ -993,15 +998,22 @@ type MethInfo =
member x.IsStruct =
isStructTy x.TcGlobals x.ApparentEnclosingType
- /// Indicates if this method is read-only; usually by the [] attribute.
+ member x.IsOnReadOnlyType =
+ let g = x.TcGlobals
+ let typeInfo = ILTypeInfo.FromType g x.ApparentEnclosingType
+ typeInfo.IsReadOnly g
+
+ /// Indicates if this method is read-only; usually by the [] attribute on method or struct level.
/// Must be an instance method.
/// Receiver must be a struct type.
member x.IsReadOnly =
- // Perf Review: Is there a way we can cache this result?
+ // Perf Review: Is there a way we can cache this result?
+
x.IsInstance &&
x.IsStruct &&
match x with
- | ILMeth (g, ilMethInfo, _) -> ilMethInfo.IsReadOnly g
+ | ILMeth (g, ilMethInfo, _) ->
+ ilMethInfo.IsReadOnly g || x.IsOnReadOnlyType
| FSMeth _ -> false // F# defined methods not supported yet. Must be a language feature.
| _ -> false
@@ -2263,6 +2275,12 @@ type EventInfo =
| ProvidedEvent (_, ei, _) -> ProvidedEventInfo.TaintedGetHashCode ei
#endif
override x.ToString() = "event " + x.EventName
+
+ /// Get custom attributes for events (only applicable for IL events)
+ member x.GetCustomAttrs() =
+ match x with
+ | ILEvent(ILEventInfo(_, ilEventDef))-> ilEventDef.CustomAttrs
+ | _ -> ILAttributes.Empty
//-------------------------------------------------------------------------
// Helpers associated with getting and comparing method signatures
diff --git a/src/Compiler/Checking/infos.fsi b/src/Compiler/Checking/infos.fsi
index 63a24eb6502..550c7860b34 100644
--- a/src/Compiler/Checking/infos.fsi
+++ b/src/Compiler/Checking/infos.fsi
@@ -1009,6 +1009,9 @@ type EventInfo =
/// Get the delegate type associated with the event.
member GetDelegateType: amap: ImportMap * m: range -> TType
+ /// Get custom attributes for events (only applicable for IL events)
+ member GetCustomAttrs: unit -> ILAttributes
+
/// An exception type used to raise an error using the old error system.
///
/// Error text: "A definition to be compiled as a .NET event does not have the expected form. Only property members can be compiled as .NET events."
diff --git a/src/Compiler/Driver/CompilerConfig.fs b/src/Compiler/Driver/CompilerConfig.fs
index 08946b84f63..91a2e9fde3d 100644
--- a/src/Compiler/Driver/CompilerConfig.fs
+++ b/src/Compiler/Driver/CompilerConfig.fs
@@ -1405,14 +1405,13 @@ type TcConfig private (data: TcConfigBuilder, validate: bool) =
/// 'framework' reference set that is potentially shared across multiple compilations.
member tcConfig.IsSystemAssembly(fileName: string) =
try
+ let dirName = Path.GetDirectoryName fileName
+ let baseName = FileSystemUtils.fileNameWithoutExtension fileName
+
FileSystem.FileExistsShim fileName
- && ((tcConfig.GetTargetFrameworkDirectories()
- |> List.exists (fun clrRoot -> clrRoot = Path.GetDirectoryName fileName))
- || (tcConfig
- .FxResolver
- .GetSystemAssemblies()
- .Contains(FileSystemUtils.fileNameWithoutExtension fileName))
- || tcConfig.FxResolver.IsInReferenceAssemblyPackDirectory fileName)
+ && ((tcConfig.GetTargetFrameworkDirectories() |> List.contains dirName)
+ || FxResolver.GetSystemAssemblies().Contains baseName
+ || FxResolver.IsReferenceAssemblyPackDirectoryApprox dirName)
with _ ->
false
diff --git a/src/Compiler/Driver/FxResolver.fs b/src/Compiler/Driver/FxResolver.fs
index ae69346d689..a9ddac4a7ad 100644
--- a/src/Compiler/Driver/FxResolver.fs
+++ b/src/Compiler/Driver/FxResolver.fs
@@ -629,7 +629,7 @@ type internal FxResolver
// A set of assemblies to always consider to be system assemblies. A common set of these can be used a shared
// resources between projects in the compiler services. Also all assemblies where well-known system types exist
// referenced from TcGlobals must be listed here.
- let systemAssemblies =
+ static let systemAssemblies =
HashSet
[
// NOTE: duplicates are ok in this list
@@ -807,17 +807,10 @@ type internal FxResolver
"WindowsBase"
]
- member _.GetSystemAssemblies() = systemAssemblies
+ static member GetSystemAssemblies() = systemAssemblies
- member _.IsInReferenceAssemblyPackDirectory fileName =
- fxlock.AcquireLock(fun fxtok ->
- RequireFxResolverLock(fxtok, "assuming all member require lock")
-
- match tryGetNetCoreRefsPackDirectoryRoot () |> replayWarnings with
- | _, Some root ->
- let path = Path.GetDirectoryName(fileName)
- path.StartsWith(root, StringComparison.OrdinalIgnoreCase)
- | _ -> false)
+ static member IsReferenceAssemblyPackDirectoryApprox(dirName: string) =
+ dirName.Contains "Microsoft.NETCore.App.Ref"
member _.TryGetSdkDir() =
fxlock.AcquireLock(fun fxtok ->
diff --git a/src/Compiler/Driver/FxResolver.fsi b/src/Compiler/Driver/FxResolver.fsi
index 2bca0a75d8c..d740d2fc497 100644
--- a/src/Compiler/Driver/FxResolver.fsi
+++ b/src/Compiler/Driver/FxResolver.fsi
@@ -28,12 +28,14 @@ type internal FxResolver =
member GetFrameworkRefsPackDirectory: unit -> string option
- member GetSystemAssemblies: unit -> HashSet
+ static member GetSystemAssemblies: unit -> HashSet
/// Gets the selected target framework moniker, e.g netcore3.0, net472, and the running rid of the current machine
member GetTfmAndRid: unit -> string * string
- member IsInReferenceAssemblyPackDirectory: fileName: string -> bool
+ /// Determines if an assembly is in the core set of assemblies with high likelihood of
+ /// being shared amongst a set of common scripting references
+ static member IsReferenceAssemblyPackDirectoryApprox: dirName: string -> bool
member TryGetDesiredDotNetSdkVersionForDirectory: unit -> Result
diff --git a/src/Compiler/FSComp.txt b/src/Compiler/FSComp.txt
index 086d5279488..48b39055581 100644
--- a/src/Compiler/FSComp.txt
+++ b/src/Compiler/FSComp.txt
@@ -572,7 +572,7 @@ tcCouldNotFindIDisposable,"Couldn't find Dispose on IDisposable, or it was overl
724,tcInvalidIndexIntoActivePatternArray,"Internal error. Invalid index into active pattern array"
725,tcUnionCaseDoesNotTakeArguments,"This union case does not take arguments"
726,tcUnionCaseRequiresOneArgument,"This union case takes one argument"
-727,tcUnionCaseExpectsTupledArguments,"This union case expects %d arguments in tupled form"
+727,tcUnionCaseExpectsTupledArguments,"This union case expects %d arguments in tupled form, but was given %d. The missing field arguments may be any of:%s"
728,tcFieldIsNotStatic,"Field '%s' is not static"
729,tcFieldNotLiteralCannotBeUsedInPattern,"This field is not a literal and cannot be used in a pattern"
730,tcRequireVarConstRecogOrLiteral,"This is not a variable, constant, active recognizer or literal"
@@ -1653,3 +1653,5 @@ reprStateMachineInvalidForm,"The state machine has an unexpected form"
3536,tcUsingInterfaceWithStaticAbstractMethodAsType,"'%s' is normally used as a type constraint in generic code, e.g. \"'T when ISomeInterface<'T>\" or \"let f (x: #ISomeInterface<_>)\". See https://aka.ms/fsharp-iwsams for guidance. You can disable this warning by using '#nowarn \"3536\"' or '--nowarn:3536'."
3537,tcTraitHasMultipleSupportTypes,"The trait '%s' invoked by this call has multiple support types. This invocation syntax is not permitted for such traits. See https://aka.ms/fsharp-srtp for guidance."
3545,tcMissingRequiredMembers,"The following required properties have to be initalized:%s"
+3546,parsExpectingPatternInTuple,"Expecting pattern"
+3547,parsExpectedPatternAfterToken,"Expected a pattern after this point"
diff --git a/src/Compiler/Service/FSharpCheckerResults.fs b/src/Compiler/Service/FSharpCheckerResults.fs
index 2abbb49b4d2..70647f70d59 100644
--- a/src/Compiler/Service/FSharpCheckerResults.fs
+++ b/src/Compiler/Service/FSharpCheckerResults.fs
@@ -2652,9 +2652,9 @@ type FSharpCheckFileResults
ToolTipText.ToolTipText
[
for kw in names do
- match Tokenization.FSharpKeywords.KeywordsDescriptionLookup.TryGetValue kw with
- | false, _ -> ()
- | true, kwDescription ->
+ match Tokenization.FSharpKeywords.KeywordsDescriptionLookup kw with
+ | None -> ()
+ | Some kwDescription ->
let kwText = kw |> TaggedText.tagKeyword |> wordL |> LayoutRender.toArray
let kwTip = ToolTipElementData.Create(kwText, FSharpXmlDoc.None)
diff --git a/src/Compiler/Service/ServiceDeclarationLists.fs b/src/Compiler/Service/ServiceDeclarationLists.fs
index 17f8b27213d..399a3037eac 100644
--- a/src/Compiler/Service/ServiceDeclarationLists.fs
+++ b/src/Compiler/Service/ServiceDeclarationLists.fs
@@ -39,7 +39,7 @@ type ToolTipElementData =
Remarks: TaggedText[] option
ParamName : string option }
- static member Create(layout, xml, ?typeMapping, ?paramName, ?remarks) =
+ static member internal Create(layout, xml, ?typeMapping, ?paramName, ?remarks) =
{ MainDescription=layout; XmlDoc=xml; TypeMapping=defaultArg typeMapping []; ParamName=paramName; Remarks=remarks }
/// A single data tip display element
diff --git a/src/Compiler/Service/ServiceDeclarationLists.fsi b/src/Compiler/Service/ServiceDeclarationLists.fsi
index b67f53da34b..5bb8dcd9173 100644
--- a/src/Compiler/Service/ServiceDeclarationLists.fsi
+++ b/src/Compiler/Service/ServiceDeclarationLists.fsi
@@ -31,7 +31,7 @@ type public ToolTipElementData =
ParamName: string option
}
- static member Create: layout: TaggedText[] * xml: FSharpXmlDoc * ?typeMapping: TaggedText[] list * ?paramName: string * ?remarks: TaggedText[] -> ToolTipElementData
+ static member internal Create: layout: TaggedText[] * xml: FSharpXmlDoc * ?typeMapping: TaggedText[] list * ?paramName: string * ?remarks: TaggedText[] -> ToolTipElementData
/// A single tool tip display element
//
diff --git a/src/Compiler/Service/ServiceLexing.fs b/src/Compiler/Service/ServiceLexing.fs
index 6ee75eab602..80cfb38cc6c 100644
--- a/src/Compiler/Service/ServiceLexing.fs
+++ b/src/Compiler/Service/ServiceLexing.fs
@@ -1216,7 +1216,13 @@ module FSharpKeywords =
let KeywordsWithDescription = PrettyNaming.keywordsWithDescription
- let KeywordsDescriptionLookup = KeywordsWithDescription |> dict
+ let internal KeywordsDescriptionLookup =
+ let d = KeywordsWithDescription |> dict
+
+ fun kw ->
+ match d.TryGetValue kw with
+ | false, _ -> None
+ | true, desc -> Some desc
let KeywordNames = Lexhelp.Keywords.keywordNames
diff --git a/src/Compiler/Service/ServiceLexing.fsi b/src/Compiler/Service/ServiceLexing.fsi
index a53bba2669f..39b2febf315 100755
--- a/src/Compiler/Service/ServiceLexing.fsi
+++ b/src/Compiler/Service/ServiceLexing.fsi
@@ -345,7 +345,7 @@ module FSharpKeywords =
val KeywordsWithDescription: (string * string) list
/// A lookup from keywords to their descriptions
- val KeywordsDescriptionLookup: System.Collections.Generic.IDictionary
+ val internal KeywordsDescriptionLookup: (string -> string option)
/// All the keywords in the F# language
val KeywordNames: string list
diff --git a/src/Compiler/Service/ServiceParseTreeWalk.fs b/src/Compiler/Service/ServiceParseTreeWalk.fs
index 08c89d969f9..f3443fd95ff 100755
--- a/src/Compiler/Service/ServiceParseTreeWalk.fs
+++ b/src/Compiler/Service/ServiceParseTreeWalk.fs
@@ -789,7 +789,8 @@ module SyntaxTraversal =
match p with
| SynPat.Paren (p, _) -> traversePat path p
| SynPat.As (p1, p2, _)
- | SynPat.Or (p1, p2, _, _) -> [ p1; p2 ] |> List.tryPick (traversePat path)
+ | SynPat.Or (p1, p2, _, _)
+ | SynPat.ListCons (p1, p2, _, _) -> [ p1; p2 ] |> List.tryPick (traversePat path)
| SynPat.Ands (ps, _)
| SynPat.Tuple (_, ps, _)
| SynPat.ArrayOrList (_, ps, _) -> ps |> List.tryPick (traversePat path)
@@ -797,7 +798,7 @@ module SyntaxTraversal =
| SynPat.LongIdent (argPats = args) ->
match args with
| SynArgPats.Pats ps -> ps |> List.tryPick (traversePat path)
- | SynArgPats.NamePatPairs (ps, _) -> ps |> List.map (fun (_, _, pat) -> pat) |> List.tryPick (traversePat path)
+ | SynArgPats.NamePatPairs (pats = ps) -> ps |> List.map (fun (_, _, pat) -> pat) |> List.tryPick (traversePat path)
| SynPat.Typed (p, ty, _) ->
match traversePat path p with
| None -> traverseSynType path ty
diff --git a/src/Compiler/Service/ServiceParsedInputOps.fs b/src/Compiler/Service/ServiceParsedInputOps.fs
index 6b6a1c906f0..7d3c916bc8e 100644
--- a/src/Compiler/Service/ServiceParsedInputOps.fs
+++ b/src/Compiler/Service/ServiceParsedInputOps.fs
@@ -556,7 +556,7 @@ module ParsedInput =
let (|ConstructorPats|) pats =
match pats with
| SynArgPats.Pats ps -> ps
- | SynArgPats.NamePatPairs (xs, _) -> List.map (fun (_, _, pat) -> pat) xs
+ | SynArgPats.NamePatPairs (pats = xs) -> List.map (fun (_, _, pat) -> pat) xs
/// A recursive pattern that collect all sequential expressions to avoid StackOverflowException
let rec (|Sequentials|_|) expr =
@@ -581,7 +581,7 @@ module ParsedInput =
|> Option.orElseWith (fun () -> ifPosInRange r (fun _ -> List.tryPick (walkSynModuleDecl isTopLevel) decls))
and walkAttribute (attr: SynAttribute) =
- if isPosInRange attr.Range then
+ if isPosInRange attr.TypeName.Range then
Some EntityKind.Attribute
else
None
@@ -619,7 +619,8 @@ module ParsedInput =
| SynPat.As (pat1, pat2, _) -> List.tryPick walkPat [ pat1; pat2 ]
| SynPat.Typed (pat, t, _) -> walkPat pat |> Option.orElseWith (fun () -> walkType t)
| SynPat.Attrib (pat, Attributes attrs, _) -> walkPat pat |> Option.orElseWith (fun () -> List.tryPick walkAttribute attrs)
- | SynPat.Or (pat1, pat2, _, _) -> List.tryPick walkPat [ pat1; pat2 ]
+ | SynPat.Or (pat1, pat2, _, _)
+ | SynPat.ListCons (pat1, pat2, _, _) -> List.tryPick walkPat [ pat1; pat2 ]
| SynPat.LongIdent (typarDecls = typars; argPats = ConstructorPats pats; range = r) ->
ifPosInRange r (fun _ -> kind)
|> Option.orElseWith (fun () ->
@@ -1566,7 +1567,7 @@ module ParsedInput =
let (|ConstructorPats|) pats =
match pats with
| SynArgPats.Pats ps -> ps
- | SynArgPats.NamePatPairs (xs, _) -> List.map (fun (_, _, pat) -> pat) xs
+ | SynArgPats.NamePatPairs (pats = xs) -> List.map (fun (_, _, pat) -> pat) xs
/// Returns all `Ident`s and `LongIdent`s found in an untyped AST.
let getLongIdents (parsedInput: ParsedInput) : IDictionary =
@@ -1638,7 +1639,8 @@ module ParsedInput =
walkPat pat
List.iter walkAttribute attrs
| SynPat.As (pat1, pat2, _)
- | SynPat.Or (pat1, pat2, _, _) -> List.iter walkPat [ pat1; pat2 ]
+ | SynPat.Or (pat1, pat2, _, _)
+ | SynPat.ListCons (pat1, pat2, _, _) -> List.iter walkPat [ pat1; pat2 ]
| SynPat.LongIdent (longDotId = ident; typarDecls = typars; argPats = ConstructorPats pats) ->
addLongIdentWithDots ident
diff --git a/src/Compiler/Service/ServiceXmlDocParser.fs b/src/Compiler/Service/ServiceXmlDocParser.fs
index ae9217e8a02..4a7eca7868d 100644
--- a/src/Compiler/Service/ServiceXmlDocParser.fs
+++ b/src/Compiler/Service/ServiceXmlDocParser.fs
@@ -25,6 +25,7 @@ module XmlDocParsing =
| SynPat.Typed (pat, _type, _range) -> digNamesFrom pat
| SynPat.Attrib (pat, _attrs, _range) -> digNamesFrom pat
| SynPat.LongIdent(argPats = ConstructorPats pats) -> pats |> List.collect digNamesFrom
+ | SynPat.ListCons (p1, p2, _, _) -> List.collect digNamesFrom [ p1; p2 ]
| SynPat.Tuple (_, pats, _range) -> pats |> List.collect digNamesFrom
| SynPat.Paren (pat, _range) -> digNamesFrom pat
| SynPat.OptionalVal (id, _) -> [ id.idText ]
diff --git a/src/Compiler/Symbols/Symbols.fs b/src/Compiler/Symbols/Symbols.fs
index ec343ad2a8d..9adb5ffb1f9 100644
--- a/src/Compiler/Symbols/Symbols.fs
+++ b/src/Compiler/Symbols/Symbols.fs
@@ -266,7 +266,10 @@ type FSharpSymbol(cenv: SymbolEnv, item: unit -> Item, access: FSharpSymbol -> C
static member Create(cenv, item): FSharpSymbol =
let dflt() = FSharpSymbol(cenv, (fun () -> item), (fun _ _ _ -> true))
- match item with
+ match item with
+ | Item.Value v when v.Deref.IsClassConstructor ->
+ FSharpMemberOrFunctionOrValue(cenv, C (FSMeth(cenv.g, generalizeTyconRef cenv.g v.DeclaringEntity |> snd, v, None)), item) :> _
+
| Item.Value v -> FSharpMemberOrFunctionOrValue(cenv, V v, item) :> _
| Item.UnionCase (uinfo, _) -> FSharpUnionCase(cenv, uinfo.UnionCaseRef) :> _
| Item.ExnCase tcref -> FSharpEntity(cenv, tcref) :>_
@@ -632,8 +635,10 @@ type FSharpEntity(cenv: SymbolEnv, entity: EntityRef) =
protect <| fun () ->
([ let entityTy = generalizedTyconRef cenv.g entity
let createMember (minfo: MethInfo) =
- if minfo.IsConstructor then FSharpMemberOrFunctionOrValue(cenv, C minfo, Item.CtorGroup (minfo.DisplayName, [minfo]))
- else FSharpMemberOrFunctionOrValue(cenv, M minfo, Item.MethodGroup (minfo.DisplayName, [minfo], None))
+ if minfo.IsConstructor || minfo.IsClassConstructor then
+ FSharpMemberOrFunctionOrValue(cenv, C minfo, Item.CtorGroup (minfo.DisplayName, [minfo]))
+ else
+ FSharpMemberOrFunctionOrValue(cenv, M minfo, Item.MethodGroup (minfo.DisplayName, [minfo], None))
if x.IsFSharpAbbreviation then
()
elif x.IsFSharp then
diff --git a/src/Compiler/SyntaxTree/ParseHelpers.fs b/src/Compiler/SyntaxTree/ParseHelpers.fs
index f3e3fcdfdaf..6aa973d275e 100644
--- a/src/Compiler/SyntaxTree/ParseHelpers.fs
+++ b/src/Compiler/SyntaxTree/ParseHelpers.fs
@@ -468,6 +468,7 @@ let mkSynMemberDefnGetSet
{
LetKeyword = None
EqualsRange = mEquals
+ ExternKeyword = None
}
let binding =
@@ -542,6 +543,7 @@ let mkSynMemberDefnGetSet
{
LetKeyword = None
EqualsRange = mEquals
+ ExternKeyword = None
}
let binding =
@@ -629,6 +631,7 @@ let mkSynMemberDefnGetSet
{
LetKeyword = None
EqualsRange = mEquals
+ ExternKeyword = None
}
let bindingOuter =
diff --git a/src/Compiler/SyntaxTree/SyntaxTree.fs b/src/Compiler/SyntaxTree/SyntaxTree.fs
index 1845f463540..9412e8486ae 100644
--- a/src/Compiler/SyntaxTree/SyntaxTree.fs
+++ b/src/Compiler/SyntaxTree/SyntaxTree.fs
@@ -886,12 +886,12 @@ type SynSimplePats =
type SynArgPats =
| Pats of pats: SynPat list
- | NamePatPairs of pats: (Ident * range * SynPat) list * range: range
+ | NamePatPairs of pats: (Ident * range * SynPat) list * range: range * trivia: SynArgPatsNamePatPairsTrivia
member x.Patterns =
match x with
| Pats pats -> pats
- | NamePatPairs (pats, _) -> pats |> List.map (fun (_, _, pat) -> pat)
+ | NamePatPairs (pats = pats) -> pats |> List.map (fun (_, _, pat) -> pat)
[]
type SynPat =
@@ -908,6 +908,8 @@ type SynPat =
| Or of lhsPat: SynPat * rhsPat: SynPat * range: range * trivia: SynPatOrTrivia
+ | ListCons of lhsPat: SynPat * rhsPat: SynPat * range: range * trivia: SynPatListConsTrivia
+
| Ands of pats: SynPat list * range: range
| As of lhsPat: SynPat * rhsPat: SynPat * range: range
@@ -953,6 +955,7 @@ type SynPat =
| SynPat.Wild (range = m)
| SynPat.Named (range = m)
| SynPat.Or (range = m)
+ | SynPat.ListCons (range = m)
| SynPat.Ands (range = m)
| SynPat.As (range = m)
| SynPat.LongIdent (range = m)
diff --git a/src/Compiler/SyntaxTree/SyntaxTree.fsi b/src/Compiler/SyntaxTree/SyntaxTree.fsi
index b1538eaa489..1dfd44d2c0f 100644
--- a/src/Compiler/SyntaxTree/SyntaxTree.fsi
+++ b/src/Compiler/SyntaxTree/SyntaxTree.fsi
@@ -1024,7 +1024,7 @@ type SynSimplePats =
type SynArgPats =
| Pats of pats: SynPat list
- | NamePatPairs of pats: (Ident * range * SynPat) list * range: range
+ | NamePatPairs of pats: (Ident * range * SynPat) list * range: range * trivia: SynArgPatsNamePatPairsTrivia
member Patterns: SynPat list
@@ -1050,6 +1050,9 @@ type SynPat =
/// A disjunctive pattern 'pat1 | pat2'
| Or of lhsPat: SynPat * rhsPat: SynPat * range: range * trivia: SynPatOrTrivia
+ /// A conjunctive pattern 'pat1 :: pat2'
+ | ListCons of lhsPat: SynPat * rhsPat: SynPat * range: range * trivia: SynPatListConsTrivia
+
/// A conjunctive pattern 'pat1 & pat2'
| Ands of pats: SynPat list * range: range
diff --git a/src/Compiler/SyntaxTree/SyntaxTreeOps.fs b/src/Compiler/SyntaxTree/SyntaxTreeOps.fs
index ef3673fa44f..aefc238d10e 100644
--- a/src/Compiler/SyntaxTree/SyntaxTreeOps.fs
+++ b/src/Compiler/SyntaxTree/SyntaxTreeOps.fs
@@ -1031,6 +1031,13 @@ let rec normalizeTupleExpr exprs commas : SynExpr list * range list =
innerExprs @ rest, innerCommas @ commas
| _ -> exprs, commas
+let rec normalizeTuplePat pats : SynPat list =
+ match pats with
+ | SynPat.Tuple (false, innerPats, _) :: rest ->
+ let innerExprs = normalizeTuplePat (List.rev innerPats)
+ innerExprs @ rest
+ | _ -> pats
+
/// Remove all members that were captures as SynMemberDefn.GetSetMember
let rec desugarGetSetMembers (memberDefns: SynMemberDefns) =
memberDefns
diff --git a/src/Compiler/SyntaxTree/SyntaxTreeOps.fsi b/src/Compiler/SyntaxTree/SyntaxTreeOps.fsi
index 5af8180d05e..b78563d4bce 100644
--- a/src/Compiler/SyntaxTree/SyntaxTreeOps.fsi
+++ b/src/Compiler/SyntaxTree/SyntaxTreeOps.fsi
@@ -350,6 +350,8 @@ val mkDynamicArgExpr: expr: SynExpr -> SynExpr
val normalizeTupleExpr: exprs: SynExpr list -> commas: range list -> SynExpr list * range List
+val normalizeTuplePat: pats: SynPat list -> SynPat list
+
val desugarGetSetMembers: memberDefns: SynMemberDefns -> SynMemberDefns
val getTypeFromTuplePath: path: SynTupleTypeSegment list -> SynType list
diff --git a/src/Compiler/SyntaxTree/SyntaxTrivia.fs b/src/Compiler/SyntaxTree/SyntaxTrivia.fs
index 1b03d20b615..fa4ebc784c8 100644
--- a/src/Compiler/SyntaxTree/SyntaxTrivia.fs
+++ b/src/Compiler/SyntaxTree/SyntaxTrivia.fs
@@ -122,6 +122,9 @@ type SynUnionCaseTrivia = { BarRange: range option }
[]
type SynPatOrTrivia = { BarRange: range }
+[]
+type SynPatListConsTrivia = { ColonColonRange: range }
+
[]
type SynTypeDefnTrivia =
{
@@ -156,12 +159,14 @@ type SynTypeDefnSigTrivia =
type SynBindingTrivia =
{
LetKeyword: range option
+ ExternKeyword: range option
EqualsRange: range option
}
static member Zero: SynBindingTrivia =
{
LetKeyword = None
+ ExternKeyword = None
EqualsRange = None
}
@@ -257,3 +262,6 @@ type SynMemberGetSetTrivia =
AndKeyword: range option
SetKeyword: range option
}
+
+[]
+type SynArgPatsNamePatPairsTrivia = { ParenRange: range }
diff --git a/src/Compiler/SyntaxTree/SyntaxTrivia.fsi b/src/Compiler/SyntaxTree/SyntaxTrivia.fsi
index fbdf8ecf30e..b6f0532d73c 100644
--- a/src/Compiler/SyntaxTree/SyntaxTrivia.fsi
+++ b/src/Compiler/SyntaxTree/SyntaxTrivia.fsi
@@ -199,6 +199,14 @@ type SynPatOrTrivia =
BarRange: range
}
+/// Represents additional information for SynPat.Cons
+[]
+type SynPatListConsTrivia =
+ {
+ /// The syntax range of the `::` token.
+ ColonColonRange: range
+ }
+
/// Represents additional information for SynTypeDefn
[]
type SynTypeDefnTrivia =
@@ -238,6 +246,9 @@ type SynBindingTrivia =
/// The syntax range of the `let` keyword.
LetKeyword: range option
+ /// The syntax range of the `extern` keyword.
+ ExternKeyword: range option
+
/// The syntax range of the `=` token.
EqualsRange: range option
}
@@ -365,3 +376,11 @@ type SynMemberGetSetTrivia =
/// The syntax range of the `set` keyword
SetKeyword: range option
}
+
+/// Represents additional information for SynArgPats.NamePatPairs
+[]
+type SynArgPatsNamePatPairsTrivia =
+ {
+ /// The syntax range from the beginning of the `(` token till the end of the `)` token.
+ ParenRange: range
+ }
diff --git a/src/Compiler/TypedTree/TypedTree.fs b/src/Compiler/TypedTree/TypedTree.fs
index b3fcdd6c7d5..dfdc9640a0c 100644
--- a/src/Compiler/TypedTree/TypedTree.fs
+++ b/src/Compiler/TypedTree/TypedTree.fs
@@ -4156,7 +4156,7 @@ type TType =
(match anonInfo.TupInfo with
| TupInfo.Const false -> ""
| TupInfo.Const true -> "struct ")
- + "{|" + String.concat "," (Seq.map2 (fun nm ty -> nm + " " + string ty + ";") anonInfo.SortedNames tinst) + ")" + "|}"
+ + "{|" + String.concat "," (Seq.map2 (fun nm ty -> nm + " " + string ty + ";") anonInfo.SortedNames tinst) + "|}"
| TType_fun (domainTy, retTy, _) -> "(" + string domainTy + " -> " + string retTy + ")"
| TType_ucase (uc, tinst) -> "ucase " + uc.CaseName + (match tinst with [] -> "" | tys -> "<" + String.concat "," (List.map string tys) + ">")
| TType_var (tp, _) ->
diff --git a/src/Compiler/pars.fsy b/src/Compiler/pars.fsy
index d7bbdaaf68e..b732754d7fc 100644
--- a/src/Compiler/pars.fsy
+++ b/src/Compiler/pars.fsy
@@ -1561,18 +1561,23 @@ attributeListElements:
attribute:
/* A custom attribute */
| path opt_HIGH_PRECEDENCE_APP opt_atomicExprAfterType
- { let arg = match $3 with None -> mkSynUnit $1.Range | Some e -> e
- ({ TypeName=$1; ArgExpr=arg; Target=None; AppliesToGetterAndSetter=false; Range=$1.Range } : SynAttribute) }
+ { let arg = match $3 with None -> mkSynUnit $1.Range | Some e -> e
+ let m = unionRanges $1.Range arg.Range
+ ({ TypeName=$1; ArgExpr=arg; Target=None; AppliesToGetterAndSetter=false; Range=m } : SynAttribute) }
/* A custom attribute with an attribute target */
| attributeTarget path opt_HIGH_PRECEDENCE_APP opt_atomicExprAfterType
- { let arg = match $4 with None -> mkSynUnit $2.Range | Some e -> e
- ({ TypeName=$2; ArgExpr=arg; Target=$1; AppliesToGetterAndSetter=false; Range=$2.Range } : SynAttribute) }
+ { let arg = match $4 with None -> mkSynUnit $2.Range | Some e -> e
+ let startRange = match $1 with Some (ident:Ident) -> ident.idRange | None -> $2.Range
+ let m = unionRanges startRange arg.Range
+ ({ TypeName=$2; ArgExpr=arg; Target=$1; AppliesToGetterAndSetter=false; Range=m } : SynAttribute) }
/* A custom attribute with an attribute target */
| attributeTarget OBLOCKBEGIN path oblockend opt_HIGH_PRECEDENCE_APP opt_atomicExprAfterType
{ let arg = match $6 with None -> mkSynUnit $3.Range | Some e -> e
- ({ TypeName=$3; ArgExpr=arg; Target=$1; AppliesToGetterAndSetter=false; Range=$3.Range } : SynAttribute) }
+ let startRange = match $1 with Some ident -> ident.idRange | None -> $3.Range
+ let m = unionRanges startRange arg.Range
+ ({ TypeName=$3; ArgExpr=arg; Target=$1; AppliesToGetterAndSetter=false; Range=m } : SynAttribute) }
/* The target of a custom attribute */
@@ -1863,7 +1868,7 @@ memberCore:
let xmlDoc = grabXmlDocAtRangeStart(parseState, attrs, rangeStart)
let memberFlags = Some (memFlagsBuilder SynMemberKind.Member)
let mWholeBindLhs = (mBindLhs, attrs) ||> unionRangeWithListBy (fun (a: SynAttributeList) -> a.Range)
- let trivia: SynBindingTrivia = { LetKeyword = None; EqualsRange = Some mEquals }
+ let trivia: SynBindingTrivia = { LetKeyword = None; EqualsRange = Some mEquals; ExternKeyword = None }
let binding = mkSynBinding (xmlDoc, bindingPat) (vis, $1, false, mWholeBindLhs, DebugPointAtBinding.NoneAtInvisible, optReturnType, $5, mRhs, [], attrs, memberFlags, trivia)
let memberRange = unionRanges rangeStart mRhs |> unionRangeWithXmlDoc xmlDoc
[ SynMemberDefn.Member (binding, memberRange) ]) }
@@ -1980,7 +1985,7 @@ classDefnMember:
let declPat = SynPat.LongIdent (SynLongIdent([mkSynId (rhs parseState 3) "new"], [], [None]), None, Some noInferredTypars, SynArgPats.Pats [$4], vis, rhs parseState 3)
// Check that 'SynPatForConstructorDecl' matches this correctly
assert (match declPat with SynPatForConstructorDecl _ -> true | _ -> false)
- let synBindingTrivia: SynBindingTrivia = { LetKeyword = None; EqualsRange = Some mEquals }
+ let synBindingTrivia: SynBindingTrivia = { LetKeyword = None; EqualsRange = Some mEquals; ExternKeyword = None }
[ SynMemberDefn.Member(SynBinding (None, SynBindingKind.Normal, false, false, $1, xmlDoc, valSynData, declPat, None, expr, mWholeBindLhs, DebugPointAtBinding.NoneAtInvisible, synBindingTrivia), m) ] }
| opt_attributes opt_declVisibility STATIC typeKeyword tyconDefn
@@ -2738,7 +2743,8 @@ hardwhiteDefnBindingsTerminator:
/* An 'extern' DllImport function definition in C-style syntax */
cPrototype:
| EXTERN cRetType opt_access ident opt_HIGH_PRECEDENCE_APP LPAREN externArgs rparen
- { let rty, vis, nm, args = $2, $3, $4, $7
+ { let mExtern = rhs parseState 1
+ let rty, vis, nm, args = $2, $3, $4, $7
let nmm = rhs parseState 3
let argsm = rhs parseState 6
let mBindLhs = lhs parseState
@@ -2755,10 +2761,11 @@ cPrototype:
let bindingPat = SynPat.LongIdent (SynLongIdent([nm], [], [None]), None, Some noInferredTypars, SynArgPats.Pats [SynPat.Tuple(false, args, argsm)], vis, nmm)
let mWholeBindLhs = (mBindLhs, attrs) ||> unionRangeWithListBy (fun (a: SynAttributeList) -> a.Range)
let xmlDoc = grabXmlDoc(parseState, attrs, 1)
+ let trivia = { LetKeyword = None; ExternKeyword = Some mExtern; EqualsRange = None }
let binding =
mkSynBinding
(xmlDoc, bindingPat)
- (vis, false, false, mWholeBindLhs, DebugPointAtBinding.NoneAtInvisible, Some rty, rhsExpr, mRhs, [], attrs, None, SynBindingTrivia.Zero)
+ (vis, false, false, mWholeBindLhs, DebugPointAtBinding.NoneAtInvisible, Some rty, rhsExpr, mRhs, [], attrs, None, trivia)
[], [binding]) }
/* A list of arguments in an 'extern' DllImport function definition */
@@ -2877,7 +2884,7 @@ localBinding:
let mWhole = (unionRanges mLetKwd mRhs, attrs) ||> unionRangeWithListBy (fun (a: SynAttributeList) -> a.Range)
let spBind = if IsDebugPointBinding bindingPat expr then DebugPointAtBinding.Yes mWhole else DebugPointAtBinding.NoneAtLet
let mWholeBindLhs = (mBindLhs, attrs) ||> unionRangeWithListBy (fun (a: SynAttributeList) -> a.Range)
- let trivia: SynBindingTrivia = { LetKeyword = Some mLetKwd; EqualsRange = Some mEquals }
+ let trivia: SynBindingTrivia = { LetKeyword = Some mLetKwd; EqualsRange = Some mEquals; ExternKeyword = None }
mkSynBinding (xmlDoc, bindingPat) (vis, $1, $2, mWholeBindLhs, spBind, optReturnType, expr, mRhs, opts, attrs, None, trivia))
localBindingRange, localBindingBuilder }
@@ -2892,7 +2899,7 @@ localBinding:
let zeroWidthAtEnd = mEquals.EndRange
let rhsExpr = arbExpr("localBinding1", zeroWidthAtEnd)
let spBind = if IsDebugPointBinding bindingPat rhsExpr then DebugPointAtBinding.Yes mWhole else DebugPointAtBinding.NoneAtLet
- let trivia: SynBindingTrivia = { LetKeyword = Some mLetKwd; EqualsRange = Some mEquals }
+ let trivia: SynBindingTrivia = { LetKeyword = Some mLetKwd; EqualsRange = Some mEquals; ExternKeyword = None }
mkSynBinding (xmlDoc, bindingPat) (vis, $1, $2, mBindLhs, spBind, optReturnType, rhsExpr, mRhs, [], attrs, None, trivia))
mWhole, localBindingBuilder }
@@ -2905,7 +2912,7 @@ localBinding:
let localBindingBuilder =
(fun xmlDoc attrs vis mLetKwd ->
let spBind = DebugPointAtBinding.Yes (unionRanges mLetKwd mRhs)
- let trivia = { LetKeyword = Some mLetKwd; EqualsRange = None }
+ let trivia = { LetKeyword = Some mLetKwd; EqualsRange = None; ExternKeyword = None }
let rhsExpr = arbExpr("localBinding2", mRhs)
mkSynBinding (xmlDoc, bindingPat) (vis, $1, $2, mBindLhs, spBind, optReturnType, rhsExpr, mRhs, [], attrs, None, trivia))
mWhole, localBindingBuilder }
@@ -3124,10 +3131,13 @@ headBindingPattern:
SynPat.Or($1, $3, rhs2 parseState 1 3, { BarRange = mBar }) }
| headBindingPattern COLON_COLON headBindingPattern
- { SynPat.LongIdent (SynLongIdent(mkSynCaseName (rhs parseState 2) opNameCons, [], [ Some (IdentTrivia.OriginalNotation "::") ]), None, None, SynArgPats.Pats [SynPat.Tuple (false, [$1;$3], rhs2 parseState 1 3)], None, lhs parseState) }
+ { let mColonColon = rhs parseState 2
+ SynPat.ListCons($1, $3, rhs2 parseState 1 3, { ColonColonRange = mColonColon }) }
- | tuplePatternElements %prec pat_tuple
- { SynPat.Tuple(false, List.rev $1, lhs parseState) }
+ | tuplePatternElements %prec pat_tuple
+ { let pats = normalizeTuplePat $1
+ let m = (rhs parseState 1, pats) ||> unionRangeWithListBy (fun p -> p.Range)
+ SynPat.Tuple(false, List.rev pats, m) }
| conjPatternElements %prec pat_conj
{ SynPat.Ands(List.rev $1, lhs parseState) }
@@ -3135,12 +3145,37 @@ headBindingPattern:
| constrPattern
{ $1 }
-tuplePatternElements:
- | tuplePatternElements COMMA headBindingPattern
+tuplePatternElements:
+ | tuplePatternElements COMMA headBindingPattern
{ $3 :: $1 }
- | headBindingPattern COMMA headBindingPattern
- { $3 :: $1 :: [] }
+ | headBindingPattern COMMA headBindingPattern
+ { [$3; $1] }
+
+ | tuplePatternElements COMMA ends_coming_soon_or_recover
+ { let commaRange = rhs parseState 2
+ reportParseErrorAt commaRange (FSComp.SR.parsExpectingPatternInTuple ())
+ let pat2 = SynPat.Wild(commaRange.EndRange)
+ pat2 :: $1 }
+
+ | headBindingPattern COMMA ends_coming_soon_or_recover
+ { let commaRange = rhs parseState 2
+ reportParseErrorAt commaRange (FSComp.SR.parsExpectingPatternInTuple ())
+ let pat2 = SynPat.Wild(commaRange.EndRange)
+ [pat2; $1] }
+
+ | COMMA headBindingPattern
+ { let commaRange = rhs parseState 1
+ reportParseErrorAt commaRange (FSComp.SR.parsExpectingPatternInTuple ())
+ let pat1 = SynPat.Wild(commaRange.StartRange)
+ [$2; pat1] }
+
+ | COMMA ends_coming_soon_or_recover
+ { let commaRange = rhs parseState 1
+ if not $2 then reportParseErrorAt commaRange (FSComp.SR.parsExpectedPatternAfterToken ())
+ let pat1 = SynPat.Wild(commaRange.StartRange)
+ let pat2 = SynPat.Wild(commaRange.EndRange)
+ [pat2; pat1] }
conjPatternElements:
| conjPatternElements AMP headBindingPattern
@@ -3210,7 +3245,10 @@ constrPattern:
atomicPatsOrNamePatPairs:
| LPAREN namePatPairs rparen
- { SynArgPats.NamePatPairs $2, snd $2 }
+ { let mParen = rhs2 parseState 1 3
+ let pats, m = $2
+ let trivia = { ParenRange = mParen }
+ SynArgPats.NamePatPairs(pats, m, trivia), snd $2 }
| atomicPatterns
{ let mParsed = rhs parseState 1
@@ -3351,8 +3389,10 @@ parenPattern:
{ let mBar = rhs parseState 2
SynPat.Or($1, $3, rhs2 parseState 1 3, { BarRange = mBar }) }
- | tupleParenPatternElements
- { SynPat.Tuple(false, List.rev $1, lhs parseState) }
+ | tupleParenPatternElements
+ { let pats = normalizeTuplePat $1
+ let m = (rhs parseState 1, pats) ||> unionRangeWithListBy (fun p -> p.Range)
+ SynPat.Tuple(false, List.rev pats, m) }
| conjParenPatternElements
{ SynPat.Ands(List.rev $1, rhs2 parseState 1 3) }
@@ -3366,16 +3406,42 @@ parenPattern:
SynPat.Attrib($2, $1, mLhs) }
| parenPattern COLON_COLON parenPattern
- { SynPat.LongIdent (SynLongIdent(mkSynCaseName (rhs parseState 2) opNameCons, [], [ Some (IdentTrivia.OriginalNotation "::") ]), None, None, SynArgPats.Pats [ SynPat.Tuple (false, [$1;$3], rhs2 parseState 1 3) ], None, lhs parseState) }
+ { let mColonColon = rhs parseState 2
+ SynPat.ListCons($1, $3, rhs2 parseState 1 3, { ColonColonRange = mColonColon }) }
| constrPattern { $1 }
tupleParenPatternElements:
- | tupleParenPatternElements COMMA parenPattern
+ | tupleParenPatternElements COMMA parenPattern
{ $3 :: $1 }
- | parenPattern COMMA parenPattern
- { $3 :: $1 :: [] }
+ | parenPattern COMMA parenPattern
+ { [$3; $1] }
+
+ | tupleParenPatternElements COMMA ends_coming_soon_or_recover
+ { let commaRange = rhs parseState 2
+ reportParseErrorAt commaRange (FSComp.SR.parsExpectingPatternInTuple())
+ let pat2 = SynPat.Wild(commaRange.EndRange)
+ pat2 :: $1 }
+
+ | parenPattern COMMA ends_coming_soon_or_recover
+ { let commaRange = rhs parseState 2
+ reportParseErrorAt commaRange (FSComp.SR.parsExpectingPatternInTuple())
+ let pat2 = SynPat.Wild(commaRange.EndRange)
+ [pat2; $1] }
+
+ | COMMA parenPattern
+ { let commaRange = rhs parseState 1
+ reportParseErrorAt commaRange (FSComp.SR.parsExpectingPatternInTuple())
+ let pat1 = SynPat.Wild(commaRange.StartRange)
+ [$2; pat1] }
+
+ | COMMA ends_coming_soon_or_recover
+ { let commaRange = rhs parseState 1
+ if not $2 then reportParseErrorAt commaRange (FSComp.SR.parsExpectedPatternAfterToken ())
+ let pat1 = SynPat.Wild(commaRange.StartRange)
+ let pat2 = SynPat.Wild(commaRange.EndRange)
+ [pat2; pat1] }
conjParenPatternElements:
| conjParenPatternElements AMP parenPattern
diff --git a/src/Compiler/xlf/FSComp.txt.cs.xlf b/src/Compiler/xlf/FSComp.txt.cs.xlf
index 822297d4ff9..edd370fe467 100644
--- a/src/Compiler/xlf/FSComp.txt.cs.xlf
+++ b/src/Compiler/xlf/FSComp.txt.cs.xlf
@@ -592,6 +592,16 @@
Neočekávaný token v definici typu. Za typem {0} se očekává =.
+
+ Expected a pattern after this point
+ Expected a pattern after this point
+
+
+
+ Expecting pattern
+ Expecting pattern
+
+ Incomplete character literal (example: 'Q') or qualified type invocation (example: 'T.Name)Neúplný znakový literál (příklad: Q) nebo volání kvalifikovaného typu (příklad: T.Name)
@@ -3783,8 +3793,8 @@
- This union case expects {0} arguments in tupled form
- Tento případ typu union očekává argumenty v počtu {0} v podobě řazené kolekce členů.
+ This union case expects {0} arguments in tupled form, but was given {1}. The missing field arguments may be any of:{2}
+ This union case expects {0} arguments in tupled form, but was given {1}. The missing field arguments may be any of:{2}
diff --git a/src/Compiler/xlf/FSComp.txt.de.xlf b/src/Compiler/xlf/FSComp.txt.de.xlf
index afb89b3f305..a56cade1c09 100644
--- a/src/Compiler/xlf/FSComp.txt.de.xlf
+++ b/src/Compiler/xlf/FSComp.txt.de.xlf
@@ -592,6 +592,16 @@
Unerwartetes Token in Typdefinition. Nach Typ "{0}" wurde "=" erwartet.
+
+ Expected a pattern after this point
+ Expected a pattern after this point
+
+
+
+ Expecting pattern
+ Expecting pattern
+
+ Incomplete character literal (example: 'Q') or qualified type invocation (example: 'T.Name)Unvollständiges Zeichenliteral (Beispiel: „Q“) oder qualifizierter Typaufruf (Beispiel: „T.Name“)
@@ -3783,8 +3793,8 @@
- This union case expects {0} arguments in tupled form
- Dieser Union-Fall erwartet {0} Argumente als Tupel.
+ This union case expects {0} arguments in tupled form, but was given {1}. The missing field arguments may be any of:{2}
+ This union case expects {0} arguments in tupled form, but was given {1}. The missing field arguments may be any of:{2}
diff --git a/src/Compiler/xlf/FSComp.txt.es.xlf b/src/Compiler/xlf/FSComp.txt.es.xlf
index 7bff656b19d..ce338b5124c 100644
--- a/src/Compiler/xlf/FSComp.txt.es.xlf
+++ b/src/Compiler/xlf/FSComp.txt.es.xlf
@@ -592,6 +592,16 @@
Token inesperado en la definición de tipo. Se esperaba "=" después del tipo "{0}".
+
+ Expected a pattern after this point
+ Expected a pattern after this point
+
+
+
+ Expecting pattern
+ Expecting pattern
+
+ Incomplete character literal (example: 'Q') or qualified type invocation (example: 'T.Name)Literal de carácter incompleto (ejemplo: 'Q') o invocación de tipo completo (ejemplo: 'T.Name)
@@ -3783,8 +3793,8 @@
- This union case expects {0} arguments in tupled form
- Este caso de unión espera {0} argumentos en forma de tupla.
+ This union case expects {0} arguments in tupled form, but was given {1}. The missing field arguments may be any of:{2}
+ This union case expects {0} arguments in tupled form, but was given {1}. The missing field arguments may be any of:{2}
diff --git a/src/Compiler/xlf/FSComp.txt.fr.xlf b/src/Compiler/xlf/FSComp.txt.fr.xlf
index 9e4bb29ee0c..8718d5db4e9 100644
--- a/src/Compiler/xlf/FSComp.txt.fr.xlf
+++ b/src/Compiler/xlf/FSComp.txt.fr.xlf
@@ -592,6 +592,16 @@
Jeton inattendu dans la définition de type. Signe '=' attendu après le type '{0}'.
+
+ Expected a pattern after this point
+ Expected a pattern after this point
+
+
+
+ Expecting pattern
+ Expecting pattern
+
+ Incomplete character literal (example: 'Q') or qualified type invocation (example: 'T.Name)Littéral de caractère incomplet (exemple : 'Q') ou appel de type qualifié (exemple : 'T.Name)
@@ -3783,8 +3793,8 @@
- This union case expects {0} arguments in tupled form
- Ce cas d'union attend {0} arguments basés sur des tuples
+ This union case expects {0} arguments in tupled form, but was given {1}. The missing field arguments may be any of:{2}
+ This union case expects {0} arguments in tupled form, but was given {1}. The missing field arguments may be any of:{2}
diff --git a/src/Compiler/xlf/FSComp.txt.it.xlf b/src/Compiler/xlf/FSComp.txt.it.xlf
index 6e56bbe7ee8..1c3deaeb130 100644
--- a/src/Compiler/xlf/FSComp.txt.it.xlf
+++ b/src/Compiler/xlf/FSComp.txt.it.xlf
@@ -592,6 +592,16 @@
Token imprevisto nella definizione del tipo. Dopo il tipo '{0}' è previsto '='.
+
+ Expected a pattern after this point
+ Expected a pattern after this point
+
+
+
+ Expecting pattern
+ Expecting pattern
+
+ Incomplete character literal (example: 'Q') or qualified type invocation (example: 'T.Name)Valore letterale carattere incompleto (ad esempio: 'Q') o chiamata di tipo qualificato (ad esempio: 'T.Name)
@@ -3783,8 +3793,8 @@
- This union case expects {0} arguments in tupled form
- Questo case di unione prevede {0} argomenti sotto forma di tupla
+ This union case expects {0} arguments in tupled form, but was given {1}. The missing field arguments may be any of:{2}
+ This union case expects {0} arguments in tupled form, but was given {1}. The missing field arguments may be any of:{2}
diff --git a/src/Compiler/xlf/FSComp.txt.ja.xlf b/src/Compiler/xlf/FSComp.txt.ja.xlf
index 18b818fea07..06c51c429d4 100644
--- a/src/Compiler/xlf/FSComp.txt.ja.xlf
+++ b/src/Compiler/xlf/FSComp.txt.ja.xlf
@@ -592,6 +592,16 @@
型定義に予期しないトークンがあります。型 '{0}' の後には '=' が必要です。
+
+ Expected a pattern after this point
+ Expected a pattern after this point
+
+
+
+ Expecting pattern
+ Expecting pattern
+
+ Incomplete character literal (example: 'Q') or qualified type invocation (example: 'T.Name)Incomplete character literal (example: 'Q') or qualified type invocation (example: 'T.Name)
@@ -3783,8 +3793,8 @@
- This union case expects {0} arguments in tupled form
- この共用体ケースにはタプル形式の引数を {0} 個指定してください
+ This union case expects {0} arguments in tupled form, but was given {1}. The missing field arguments may be any of:{2}
+ This union case expects {0} arguments in tupled form, but was given {1}. The missing field arguments may be any of:{2}
diff --git a/src/Compiler/xlf/FSComp.txt.ko.xlf b/src/Compiler/xlf/FSComp.txt.ko.xlf
index 052d424f56f..dbf570b4be7 100644
--- a/src/Compiler/xlf/FSComp.txt.ko.xlf
+++ b/src/Compiler/xlf/FSComp.txt.ko.xlf
@@ -592,6 +592,16 @@
형식 정의에 예기치 않은 토큰이 있습니다. '{0}' 형식 뒤에 '='가 필요합니다.
+
+ Expected a pattern after this point
+ Expected a pattern after this point
+
+
+
+ Expecting pattern
+ Expecting pattern
+
+ Incomplete character literal (example: 'Q') or qualified type invocation (example: 'T.Name)불완전한 문자 리터럴(예: 'Q') 또는 정규화된 형식 호출(예: 'T.Name)
@@ -3783,8 +3793,8 @@
- This union case expects {0} arguments in tupled form
- 이 공용 구조체 케이스에는 튜플된 형식의 인수 {0}개가 필요합니다.
+ This union case expects {0} arguments in tupled form, but was given {1}. The missing field arguments may be any of:{2}
+ This union case expects {0} arguments in tupled form, but was given {1}. The missing field arguments may be any of:{2}
diff --git a/src/Compiler/xlf/FSComp.txt.pl.xlf b/src/Compiler/xlf/FSComp.txt.pl.xlf
index eb4a2819499..15589cd24ab 100644
--- a/src/Compiler/xlf/FSComp.txt.pl.xlf
+++ b/src/Compiler/xlf/FSComp.txt.pl.xlf
@@ -592,6 +592,16 @@
Nieoczekiwany token w definicji typu. Oczekiwano znaku „=” po typie „{0}”.
+
+ Expected a pattern after this point
+ Expected a pattern after this point
+
+
+
+ Expecting pattern
+ Expecting pattern
+
+ Incomplete character literal (example: 'Q') or qualified type invocation (example: 'T.Name)Niekompletny literał znaku (przykład: „Q”) lub wywołanie typu kwalifikowanego (przykład: „T.Name”)
@@ -3783,8 +3793,8 @@
- This union case expects {0} arguments in tupled form
- Ten przypadek unii oczekuje {0} argumentów w postaci spójnej kolekcji
+ This union case expects {0} arguments in tupled form, but was given {1}. The missing field arguments may be any of:{2}
+ This union case expects {0} arguments in tupled form, but was given {1}. The missing field arguments may be any of:{2}
diff --git a/src/Compiler/xlf/FSComp.txt.pt-BR.xlf b/src/Compiler/xlf/FSComp.txt.pt-BR.xlf
index 04e91c3089b..71212e1cd43 100644
--- a/src/Compiler/xlf/FSComp.txt.pt-BR.xlf
+++ b/src/Compiler/xlf/FSComp.txt.pt-BR.xlf
@@ -592,6 +592,16 @@
Token inesperado na definição de tipo. Esperava-se '=' após o tipo '{0}'.
+
+ Expected a pattern after this point
+ Expected a pattern after this point
+
+
+
+ Expecting pattern
+ Expecting pattern
+
+ Incomplete character literal (example: 'Q') or qualified type invocation (example: 'T.Name)Literal de caractere incompleto (exemplo: 'Q') ou invocação de tipo qualificado (exemplo: 'T.Name)
@@ -3783,8 +3793,8 @@
- This union case expects {0} arguments in tupled form
- Este caso união espera argumentos {0} na forma de tupla
+ This union case expects {0} arguments in tupled form, but was given {1}. The missing field arguments may be any of:{2}
+ This union case expects {0} arguments in tupled form, but was given {1}. The missing field arguments may be any of:{2}
diff --git a/src/Compiler/xlf/FSComp.txt.ru.xlf b/src/Compiler/xlf/FSComp.txt.ru.xlf
index 29bdaf2512e..c5191baf446 100644
--- a/src/Compiler/xlf/FSComp.txt.ru.xlf
+++ b/src/Compiler/xlf/FSComp.txt.ru.xlf
@@ -592,6 +592,16 @@
Неожиданный токен в определении типа. После типа "{0}" ожидается "=".
+
+ Expected a pattern after this point
+ Expected a pattern after this point
+
+
+
+ Expecting pattern
+ Expecting pattern
+
+ Incomplete character literal (example: 'Q') or qualified type invocation (example: 'T.Name)Неполный символьный литерал (например: "Q") или вызов квалифицированного типа (например: "T.Name)
@@ -3783,8 +3793,8 @@
- This union case expects {0} arguments in tupled form
- Для данного случая объединения требуется {0} аргументов в форме кортежа
+ This union case expects {0} arguments in tupled form, but was given {1}. The missing field arguments may be any of:{2}
+ This union case expects {0} arguments in tupled form, but was given {1}. The missing field arguments may be any of:{2}
diff --git a/src/Compiler/xlf/FSComp.txt.tr.xlf b/src/Compiler/xlf/FSComp.txt.tr.xlf
index 4b1b2804206..f840cc2a2ed 100644
--- a/src/Compiler/xlf/FSComp.txt.tr.xlf
+++ b/src/Compiler/xlf/FSComp.txt.tr.xlf
@@ -592,6 +592,16 @@
Tür tanımında beklenmeyen belirteç var. '{0}' türünden sonra '=' bekleniyordu.
+
+ Expected a pattern after this point
+ Expected a pattern after this point
+
+
+
+ Expecting pattern
+ Expecting pattern
+
+ Incomplete character literal (example: 'Q') or qualified type invocation (example: 'T.Name)Eksik karakter değişmez değeri (örnek: 'Q') veya tam tür çağrısı (örnek: 'T.Name)
@@ -3783,8 +3793,8 @@
- This union case expects {0} arguments in tupled form
- Bu birleşim durumu grup olarak tanımlanmış biçimde {0} bağımsız değişken bekliyor
+ This union case expects {0} arguments in tupled form, but was given {1}. The missing field arguments may be any of:{2}
+ This union case expects {0} arguments in tupled form, but was given {1}. The missing field arguments may be any of:{2}
diff --git a/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf b/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf
index 653c27378ca..908d33e58bd 100644
--- a/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf
+++ b/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf
@@ -592,6 +592,16 @@
类型定义中出现意外标记。类型“{0}”后应为 "="。
+
+ Expected a pattern after this point
+ Expected a pattern after this point
+
+
+
+ Expecting pattern
+ Expecting pattern
+
+ Incomplete character literal (example: 'Q') or qualified type invocation (example: 'T.Name)字符文本不完整(示例: "Q")或限定类型调用(示例: "T.Name")
@@ -3783,8 +3793,8 @@
- This union case expects {0} arguments in tupled form
- 此联合用例需要 {0} 个元组格式的参数
+ This union case expects {0} arguments in tupled form, but was given {1}. The missing field arguments may be any of:{2}
+ This union case expects {0} arguments in tupled form, but was given {1}. The missing field arguments may be any of:{2}
diff --git a/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf b/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf
index 781002375e3..24faf41e95c 100644
--- a/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf
+++ b/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf
@@ -592,6 +592,16 @@
型別定義中出現非預期的權杖。類型 '{0}' 之後應該要有 '='。
+
+ Expected a pattern after this point
+ Expected a pattern after this point
+
+
+
+ Expecting pattern
+ Expecting pattern
+
+ Incomplete character literal (example: 'Q') or qualified type invocation (example: 'T.Name)Incomplete character literal (example: 'Q') or qualified type invocation (example: 'T.Name)
@@ -3783,8 +3793,8 @@
- This union case expects {0} arguments in tupled form
- 這個聯集需要 {0} 個 Tuple 形式的引數
+ This union case expects {0} arguments in tupled form, but was given {1}. The missing field arguments may be any of:{2}
+ This union case expects {0} arguments in tupled form, but was given {1}. The missing field arguments may be any of:{2}
diff --git a/src/FSharp.Core/prim-types.fs b/src/FSharp.Core/prim-types.fs
index eb92de29cba..0489528c062 100644
--- a/src/FSharp.Core/prim-types.fs
+++ b/src/FSharp.Core/prim-types.fs
@@ -601,20 +601,19 @@ namespace Microsoft.FSharp.Core
// duplicated from above since we're using integers in this section
let CompilationRepresentationFlags_PermitNull = 8
- let getTypeInfo (ty:Type) =
- if ty.IsValueType
+ let private getTypeInfo<'T> =
+ if typeof<'T>.IsValueType
then TypeNullnessSemantics_NullNever else
- let mappingAttrs = ty.GetCustomAttributes(typeof, false)
- if mappingAttrs.Length = 0
+ if not (typeof<'T>.IsDefined(typeof, false))
then TypeNullnessSemantics_NullIsExtraValue
- elif ty.Equals(typeof) then
+ elif typeof<'T>.Equals(typeof) then
TypeNullnessSemantics_NullTrueValue
- elif typeof.IsAssignableFrom(ty) then
+ elif typeof.IsAssignableFrom(typeof<'T>) then
TypeNullnessSemantics_NullIsExtraValue
- elif ty.GetCustomAttributes(typeof, false).Length > 0 then
+ elif typeof<'T>.IsDefined(typeof, false) then
TypeNullnessSemantics_NullIsExtraValue
else
- let reprAttrs = ty.GetCustomAttributes(typeof, false)
+ let reprAttrs = typeof<'T>.GetCustomAttributes(typeof, false)
if reprAttrs.Length = 0 then
TypeNullnessSemantics_NullNotLiked
else
@@ -627,7 +626,7 @@ namespace Microsoft.FSharp.Core
type TypeInfo<'T>() =
// Compute an on-demand per-instantiation static field
- static let info = getTypeInfo typeof<'T>
+ static let info = getTypeInfo<'T>
// Publish the results of that computation
static member TypeInfo = info
diff --git a/tests/FSharp.Compiler.ComponentTests/CompilerOptions/fsc/warn.fs b/tests/FSharp.Compiler.ComponentTests/CompilerOptions/fsc/warn.fs
index 1ba362eb86a..4e98ff92545 100644
--- a/tests/FSharp.Compiler.ComponentTests/CompilerOptions/fsc/warn.fs
+++ b/tests/FSharp.Compiler.ComponentTests/CompilerOptions/fsc/warn.fs
@@ -70,6 +70,18 @@ module TestCompilerWarningLevel =
|> withDiagnosticMessageMatches "The value has been copied to ensure the original is not mutated by this operation or because the copy is implicit when returning a struct from a member and another member is then accessed$"
|> ignore
+#if NETSTANDARD
+// This test works with KeyValuePair, which is not a 'readonly struct' in net472
+ []
+ let ``no error 52 with readonly struct`` compilation =
+ compilation
+ |> asExe
+ |> withOptions ["--warn:5"; "--warnaserror:52"]
+ |> compile
+ |> shouldSucceed
+ |> ignore
+#endif
+
[]
let ``warn_level6_fs --warn:6`` compilation =
compilation
diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicTypeAndModuleDefinitions/GeneratedEqualityHashingComparison/Attributes/Diags/Diags.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicTypeAndModuleDefinitions/GeneratedEqualityHashingComparison/Attributes/Diags/Diags.fs
index 295ee002be7..95fe85e3678 100644
--- a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicTypeAndModuleDefinitions/GeneratedEqualityHashingComparison/Attributes/Diags/Diags.fs
+++ b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicTypeAndModuleDefinitions/GeneratedEqualityHashingComparison/Attributes/Diags/Diags.fs
@@ -17,7 +17,7 @@ module Diags =
|> compile
|> shouldFail
|> withDiagnostics [
- (Error 501, Line 7, Col 3, Line 7, Col 23, "The object constructor 'StructuralComparisonAttribute' takes 0 argument(s) but is here given 1. The required signature is 'new: unit -> StructuralComparisonAttribute'.")
+ (Error 501, Line 7, Col 3, Line 7, Col 30, "The object constructor 'StructuralComparisonAttribute' takes 0 argument(s) but is here given 1. The required signature is 'new: unit -> StructuralComparisonAttribute'.")
]
// SOURCE=E_AdjustUses01b.fs SCFLAGS=--test:ErrorRanges # E_AdjustUses01b.fs
@@ -28,6 +28,6 @@ module Diags =
|> compile
|> shouldFail
|> withDiagnostics [
- (Error 501, Line 7, Col 3, Line 7, Col 23, "The object constructor 'StructuralComparisonAttribute' takes 0 argument(s) but is here given 1. The required signature is 'new: unit -> StructuralComparisonAttribute'.")
+ (Error 501, Line 7, Col 3, Line 7, Col 30, "The object constructor 'StructuralComparisonAttribute' takes 0 argument(s) but is here given 1. The required signature is 'new: unit -> StructuralComparisonAttribute'.")
]
diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicTypeAndModuleDefinitions/GeneratedEqualityHashingComparison/Attributes/Legacy/Legacy.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicTypeAndModuleDefinitions/GeneratedEqualityHashingComparison/Attributes/Legacy/Legacy.fs
index e26e9b5d08b..af9e9f3472e 100644
--- a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicTypeAndModuleDefinitions/GeneratedEqualityHashingComparison/Attributes/Legacy/Legacy.fs
+++ b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicTypeAndModuleDefinitions/GeneratedEqualityHashingComparison/Attributes/Legacy/Legacy.fs
@@ -17,9 +17,9 @@ module Legacy =
|> compile
|> shouldFail
|> withDiagnostics [
- (Error 501, Line 7, Col 5, Line 7, Col 22, "The object constructor 'ReferenceEqualityAttribute' takes 0 argument(s) but is here given 1. The required signature is 'new: unit -> ReferenceEqualityAttribute'.")
- (Error 501, Line 8, Col 5, Line 8, Col 25, "The object constructor 'StructuralComparisonAttribute' takes 0 argument(s) but is here given 1. The required signature is 'new: unit -> StructuralComparisonAttribute'.")
- (Error 501, Line 9, Col 5, Line 9, Col 23, "The object constructor 'StructuralEqualityAttribute' takes 0 argument(s) but is here given 1. The required signature is 'new: unit -> StructuralEqualityAttribute'.")
+ (Error 501, Line 7, Col 5, Line 7, Col 28, "The object constructor 'ReferenceEqualityAttribute' takes 0 argument(s) but is here given 1. The required signature is 'new: unit -> ReferenceEqualityAttribute'.")
+ (Error 501, Line 8, Col 5, Line 8, Col 31, "The object constructor 'StructuralComparisonAttribute' takes 0 argument(s) but is here given 1. The required signature is 'new: unit -> StructuralComparisonAttribute'.")
+ (Error 501, Line 9, Col 5, Line 9, Col 29, "The object constructor 'StructuralEqualityAttribute' takes 0 argument(s) but is here given 1. The required signature is 'new: unit -> StructuralEqualityAttribute'.")
]
// SOURCE=Test02.fs SCFLAGS="--test:ErrorRanges" # Test02.fs
@@ -30,9 +30,9 @@ module Legacy =
|> compile
|> shouldFail
|> withDiagnostics [
- (Error 501, Line 8, Col 5, Line 8, Col 22, "The object constructor 'ReferenceEqualityAttribute' takes 0 argument(s) but is here given 1. The required signature is 'new: unit -> ReferenceEqualityAttribute'.")
- (Error 501, Line 9, Col 5, Line 9, Col 25, "The object constructor 'StructuralComparisonAttribute' takes 0 argument(s) but is here given 1. The required signature is 'new: unit -> StructuralComparisonAttribute'.")
- (Error 501, Line 10, Col 5, Line 10, Col 23, "The object constructor 'StructuralEqualityAttribute' takes 0 argument(s) but is here given 1. The required signature is 'new: unit -> StructuralEqualityAttribute'.")
+ (Error 501, Line 8, Col 5, Line 8, Col 28, "The object constructor 'ReferenceEqualityAttribute' takes 0 argument(s) but is here given 1. The required signature is 'new: unit -> ReferenceEqualityAttribute'.")
+ (Error 501, Line 9, Col 5, Line 9, Col 31, "The object constructor 'StructuralComparisonAttribute' takes 0 argument(s) but is here given 1. The required signature is 'new: unit -> StructuralComparisonAttribute'.")
+ (Error 501, Line 10, Col 5, Line 10, Col 30, "The object constructor 'StructuralEqualityAttribute' takes 0 argument(s) but is here given 1. The required signature is 'new: unit -> StructuralEqualityAttribute'.")
]
// SOURCE=Test03.fs SCFLAGS="--test:ErrorRanges" # Test03.fs
@@ -43,8 +43,8 @@ module Legacy =
|> compile
|> shouldFail
|> withDiagnostics [
- (Error 501, Line 7, Col 5, Line 7, Col 22, "The object constructor 'ReferenceEqualityAttribute' takes 0 argument(s) but is here given 1. The required signature is 'new: unit -> ReferenceEqualityAttribute'.")
- (Error 501, Line 8, Col 5, Line 8, Col 25, "The object constructor 'StructuralComparisonAttribute' takes 0 argument(s) but is here given 1. The required signature is 'new: unit -> StructuralComparisonAttribute'.")
+ (Error 501, Line 7, Col 5, Line 7, Col 28, "The object constructor 'ReferenceEqualityAttribute' takes 0 argument(s) but is here given 1. The required signature is 'new: unit -> ReferenceEqualityAttribute'.")
+ (Error 501, Line 8, Col 5, Line 8, Col 31, "The object constructor 'StructuralComparisonAttribute' takes 0 argument(s) but is here given 1. The required signature is 'new: unit -> StructuralComparisonAttribute'.")
]
// SOURCE=Test04.fs SCFLAGS="--test:ErrorRanges" # Test04.fs
@@ -55,9 +55,9 @@ module Legacy =
|> compile
|> shouldFail
|> withDiagnostics [
- (Error 501, Line 7, Col 5, Line 7, Col 22, "The object constructor 'ReferenceEqualityAttribute' takes 0 argument(s) but is here given 1. The required signature is 'new: unit -> ReferenceEqualityAttribute'.")
- (Error 501, Line 8, Col 5, Line 8, Col 25, "The object constructor 'StructuralComparisonAttribute' takes 0 argument(s) but is here given 1. The required signature is 'new: unit -> StructuralComparisonAttribute'.")
- (Error 501, Line 9, Col 5, Line 9, Col 23, "The object constructor 'StructuralEqualityAttribute' takes 0 argument(s) but is here given 1. The required signature is 'new: unit -> StructuralEqualityAttribute'.")
+ (Error 501, Line 7, Col 5, Line 7, Col 28, "The object constructor 'ReferenceEqualityAttribute' takes 0 argument(s) but is here given 1. The required signature is 'new: unit -> ReferenceEqualityAttribute'.")
+ (Error 501, Line 8, Col 5, Line 8, Col 32, "The object constructor 'StructuralComparisonAttribute' takes 0 argument(s) but is here given 1. The required signature is 'new: unit -> StructuralComparisonAttribute'.")
+ (Error 501, Line 9, Col 5, Line 9, Col 29, "The object constructor 'StructuralEqualityAttribute' takes 0 argument(s) but is here given 1. The required signature is 'new: unit -> StructuralEqualityAttribute'.")
]
// SOURCE=Test05.fs SCFLAGS="--test:ErrorRanges" # Test05.fs
@@ -68,9 +68,9 @@ module Legacy =
|> compile
|> shouldFail
|> withDiagnostics [
- (Error 501, Line 7, Col 5, Line 7, Col 22, "The object constructor 'ReferenceEqualityAttribute' takes 0 argument(s) but is here given 1. The required signature is 'new: unit -> ReferenceEqualityAttribute'.")
- (Error 501, Line 8, Col 5, Line 8, Col 25, "The object constructor 'StructuralComparisonAttribute' takes 0 argument(s) but is here given 1. The required signature is 'new: unit -> StructuralComparisonAttribute'.")
- (Error 501, Line 9, Col 5, Line 9, Col 23, "The object constructor 'StructuralEqualityAttribute' takes 0 argument(s) but is here given 1. The required signature is 'new: unit -> StructuralEqualityAttribute'.")
+ (Error 501, Line 7, Col 5, Line 7, Col 28, "The object constructor 'ReferenceEqualityAttribute' takes 0 argument(s) but is here given 1. The required signature is 'new: unit -> ReferenceEqualityAttribute'.")
+ (Error 501, Line 8, Col 5, Line 8, Col 32, "The object constructor 'StructuralComparisonAttribute' takes 0 argument(s) but is here given 1. The required signature is 'new: unit -> StructuralComparisonAttribute'.")
+ (Error 501, Line 9, Col 5, Line 9, Col 30, "The object constructor 'StructuralEqualityAttribute' takes 0 argument(s) but is here given 1. The required signature is 'new: unit -> StructuralEqualityAttribute'.")
]
// SOURCE=Test06.fs SCFLAGS="--test:ErrorRanges" # Test06.fs
@@ -81,8 +81,8 @@ module Legacy =
|> compile
|> shouldFail
|> withDiagnostics [
- (Error 501, Line 7, Col 5, Line 7, Col 22, "The object constructor 'ReferenceEqualityAttribute' takes 0 argument(s) but is here given 1. The required signature is 'new: unit -> ReferenceEqualityAttribute'.")
- (Error 501, Line 8, Col 5, Line 8, Col 25, "The object constructor 'StructuralComparisonAttribute' takes 0 argument(s) but is here given 1. The required signature is 'new: unit -> StructuralComparisonAttribute'.")
+ (Error 501, Line 7, Col 5, Line 7, Col 28, "The object constructor 'ReferenceEqualityAttribute' takes 0 argument(s) but is here given 1. The required signature is 'new: unit -> ReferenceEqualityAttribute'.")
+ (Error 501, Line 8, Col 5, Line 8, Col 32, "The object constructor 'StructuralComparisonAttribute' takes 0 argument(s) but is here given 1. The required signature is 'new: unit -> StructuralComparisonAttribute'.")
]
// SOURCE=Test07.fs SCFLAGS="--test:ErrorRanges" # Test07.fs
@@ -93,8 +93,8 @@ module Legacy =
|> compile
|> shouldFail
|> withDiagnostics [
- (Error 501, Line 7, Col 5, Line 7, Col 22, "The object constructor 'ReferenceEqualityAttribute' takes 0 argument(s) but is here given 1. The required signature is 'new: unit -> ReferenceEqualityAttribute'.")
- (Error 501, Line 9, Col 5, Line 9, Col 23, "The object constructor 'StructuralEqualityAttribute' takes 0 argument(s) but is here given 1. The required signature is 'new: unit -> StructuralEqualityAttribute'.")
+ (Error 501, Line 7, Col 5, Line 7, Col 28, "The object constructor 'ReferenceEqualityAttribute' takes 0 argument(s) but is here given 1. The required signature is 'new: unit -> ReferenceEqualityAttribute'.")
+ (Error 501, Line 9, Col 5, Line 9, Col 29, "The object constructor 'StructuralEqualityAttribute' takes 0 argument(s) but is here given 1. The required signature is 'new: unit -> StructuralEqualityAttribute'.")
]
// SOURCE=Test08.fs SCFLAGS="--test:ErrorRanges" # Test08.fs
@@ -105,8 +105,8 @@ module Legacy =
|> compile
|> shouldFail
|> withDiagnostics [
- (Error 501, Line 7, Col 5, Line 7, Col 22, "The object constructor 'ReferenceEqualityAttribute' takes 0 argument(s) but is here given 1. The required signature is 'new: unit -> ReferenceEqualityAttribute'.")
- (Error 501, Line 9, Col 5, Line 9, Col 23, "The object constructor 'StructuralEqualityAttribute' takes 0 argument(s) but is here given 1. The required signature is 'new: unit -> StructuralEqualityAttribute'.")
+ (Error 501, Line 7, Col 5, Line 7, Col 28, "The object constructor 'ReferenceEqualityAttribute' takes 0 argument(s) but is here given 1. The required signature is 'new: unit -> ReferenceEqualityAttribute'.")
+ (Error 501, Line 9, Col 5, Line 9, Col 30, "The object constructor 'StructuralEqualityAttribute' takes 0 argument(s) but is here given 1. The required signature is 'new: unit -> StructuralEqualityAttribute'.")
]
// SOURCE=Test09.fs SCFLAGS="--test:ErrorRanges" # Test09.fs
@@ -117,7 +117,7 @@ module Legacy =
|> compile
|> shouldFail
|> withDiagnostics [
- (Error 501, Line 6, Col 5, Line 6, Col 22, "The object constructor 'ReferenceEqualityAttribute' takes 0 argument(s) but is here given 1. The required signature is 'new: unit -> ReferenceEqualityAttribute'.")
+ (Error 501, Line 6, Col 5, Line 6, Col 28, "The object constructor 'ReferenceEqualityAttribute' takes 0 argument(s) but is here given 1. The required signature is 'new: unit -> ReferenceEqualityAttribute'.")
]
// SOURCE=Test10.fs SCFLAGS="--test:ErrorRanges" # Test10.fs
@@ -128,9 +128,9 @@ module Legacy =
|> compile
|> shouldFail
|> withDiagnostics [
- (Error 501, Line 8, Col 5, Line 8, Col 22, "The object constructor 'ReferenceEqualityAttribute' takes 0 argument(s) but is here given 1. The required signature is 'new: unit -> ReferenceEqualityAttribute'.")
- (Error 501, Line 9, Col 5, Line 9, Col 25, "The object constructor 'StructuralComparisonAttribute' takes 0 argument(s) but is here given 1. The required signature is 'new: unit -> StructuralComparisonAttribute'.")
- (Error 501, Line 10, Col 5, Line 10, Col 23, "The object constructor 'StructuralEqualityAttribute' takes 0 argument(s) but is here given 1. The required signature is 'new: unit -> StructuralEqualityAttribute'.")
+ (Error 501, Line 8, Col 5, Line 8, Col 29, "The object constructor 'ReferenceEqualityAttribute' takes 0 argument(s) but is here given 1. The required signature is 'new: unit -> ReferenceEqualityAttribute'.")
+ (Error 501, Line 9, Col 5, Line 9, Col 31, "The object constructor 'StructuralComparisonAttribute' takes 0 argument(s) but is here given 1. The required signature is 'new: unit -> StructuralComparisonAttribute'.")
+ (Error 501, Line 10, Col 5, Line 10, Col 29, "The object constructor 'StructuralEqualityAttribute' takes 0 argument(s) but is here given 1. The required signature is 'new: unit -> StructuralEqualityAttribute'.")
]
// SOURCE=Test11.fs SCFLAGS="--test:ErrorRanges" # Test11.fs
@@ -141,9 +141,9 @@ module Legacy =
|> compile
|> shouldFail
|> withDiagnostics [
- (Error 501, Line 8, Col 5, Line 8, Col 22, "The object constructor 'ReferenceEqualityAttribute' takes 0 argument(s) but is here given 1. The required signature is 'new: unit -> ReferenceEqualityAttribute'.")
- (Error 501, Line 9, Col 5, Line 9, Col 25, "The object constructor 'StructuralComparisonAttribute' takes 0 argument(s) but is here given 1. The required signature is 'new: unit -> StructuralComparisonAttribute'.")
- (Error 501, Line 10, Col 5, Line 10, Col 23, "The object constructor 'StructuralEqualityAttribute' takes 0 argument(s) but is here given 1. The required signature is 'new: unit -> StructuralEqualityAttribute'.")
+ (Error 501, Line 8, Col 5, Line 8, Col 29, "The object constructor 'ReferenceEqualityAttribute' takes 0 argument(s) but is here given 1. The required signature is 'new: unit -> ReferenceEqualityAttribute'.")
+ (Error 501, Line 9, Col 5, Line 9, Col 31, "The object constructor 'StructuralComparisonAttribute' takes 0 argument(s) but is here given 1. The required signature is 'new: unit -> StructuralComparisonAttribute'.")
+ (Error 501, Line 10, Col 5, Line 10, Col 30, "The object constructor 'StructuralEqualityAttribute' takes 0 argument(s) but is here given 1. The required signature is 'new: unit -> StructuralEqualityAttribute'.")
]
// SOURCE=Test12.fs SCFLAGS="--test:ErrorRanges" # Test12.fs
@@ -154,8 +154,8 @@ module Legacy =
|> compile
|> shouldFail
|> withDiagnostics [
- (Error 501, Line 7, Col 5, Line 7, Col 22, "The object constructor 'ReferenceEqualityAttribute' takes 0 argument(s) but is here given 1. The required signature is 'new: unit -> ReferenceEqualityAttribute'.")
- (Error 501, Line 8, Col 5, Line 8, Col 25, "The object constructor 'StructuralComparisonAttribute' takes 0 argument(s) but is here given 1. The required signature is 'new: unit -> StructuralComparisonAttribute'.")
+ (Error 501, Line 7, Col 5, Line 7, Col 29, "The object constructor 'ReferenceEqualityAttribute' takes 0 argument(s) but is here given 1. The required signature is 'new: unit -> ReferenceEqualityAttribute'.")
+ (Error 501, Line 8, Col 5, Line 8, Col 31, "The object constructor 'StructuralComparisonAttribute' takes 0 argument(s) but is here given 1. The required signature is 'new: unit -> StructuralComparisonAttribute'.")
]
// SOURCE=Test13.fs SCFLAGS="--test:ErrorRanges" # Test13.fs
@@ -166,9 +166,9 @@ module Legacy =
|> compile
|> shouldFail
|> withDiagnostics [
- (Error 501, Line 7, Col 5, Line 7, Col 22, "The object constructor 'ReferenceEqualityAttribute' takes 0 argument(s) but is here given 1. The required signature is 'new: unit -> ReferenceEqualityAttribute'.")
- (Error 501, Line 8, Col 5, Line 8, Col 25, "The object constructor 'StructuralComparisonAttribute' takes 0 argument(s) but is here given 1. The required signature is 'new: unit -> StructuralComparisonAttribute'.")
- (Error 501, Line 9, Col 5, Line 9, Col 23, "The object constructor 'StructuralEqualityAttribute' takes 0 argument(s) but is here given 1. The required signature is 'new: unit -> StructuralEqualityAttribute'.")
+ (Error 501, Line 7, Col 5, Line 7, Col 29, "The object constructor 'ReferenceEqualityAttribute' takes 0 argument(s) but is here given 1. The required signature is 'new: unit -> ReferenceEqualityAttribute'.")
+ (Error 501, Line 8, Col 5, Line 8, Col 32, "The object constructor 'StructuralComparisonAttribute' takes 0 argument(s) but is here given 1. The required signature is 'new: unit -> StructuralComparisonAttribute'.")
+ (Error 501, Line 9, Col 5, Line 9, Col 29, "The object constructor 'StructuralEqualityAttribute' takes 0 argument(s) but is here given 1. The required signature is 'new: unit -> StructuralEqualityAttribute'.")
]
// SOURCE=Test14.fs SCFLAGS="--test:ErrorRanges" # Test14.fs
@@ -179,9 +179,9 @@ module Legacy =
|> compile
|> shouldFail
|> withDiagnostics [
- (Error 501, Line 9, Col 5, Line 9, Col 22, "The object constructor 'ReferenceEqualityAttribute' takes 0 argument(s) but is here given 1. The required signature is 'new: unit -> ReferenceEqualityAttribute'.")
- (Error 501, Line 10, Col 5, Line 10, Col 25, "The object constructor 'StructuralComparisonAttribute' takes 0 argument(s) but is here given 1. The required signature is 'new: unit -> StructuralComparisonAttribute'.")
- (Error 501, Line 11, Col 5, Line 11, Col 23, "The object constructor 'StructuralEqualityAttribute' takes 0 argument(s) but is here given 1. The required signature is 'new: unit -> StructuralEqualityAttribute'.")
+ (Error 501, Line 9, Col 5, Line 9, Col 29, "The object constructor 'ReferenceEqualityAttribute' takes 0 argument(s) but is here given 1. The required signature is 'new: unit -> ReferenceEqualityAttribute'.")
+ (Error 501, Line 10, Col 5, Line 10, Col 32, "The object constructor 'StructuralComparisonAttribute' takes 0 argument(s) but is here given 1. The required signature is 'new: unit -> StructuralComparisonAttribute'.")
+ (Error 501, Line 11, Col 5, Line 11, Col 30, "The object constructor 'StructuralEqualityAttribute' takes 0 argument(s) but is here given 1. The required signature is 'new: unit -> StructuralEqualityAttribute'.")
]
// SOURCE=Test15.fs SCFLAGS="--test:ErrorRanges" # Test15.fs
@@ -192,8 +192,8 @@ module Legacy =
|> compile
|> shouldFail
|> withDiagnostics [
- (Error 501, Line 7, Col 5, Line 7, Col 22, "The object constructor 'ReferenceEqualityAttribute' takes 0 argument(s) but is here given 1. The required signature is 'new: unit -> ReferenceEqualityAttribute'.")
- (Error 501, Line 8, Col 5, Line 8, Col 25, "The object constructor 'StructuralComparisonAttribute' takes 0 argument(s) but is here given 1. The required signature is 'new: unit -> StructuralComparisonAttribute'.")
+ (Error 501, Line 7, Col 5, Line 7, Col 29, "The object constructor 'ReferenceEqualityAttribute' takes 0 argument(s) but is here given 1. The required signature is 'new: unit -> ReferenceEqualityAttribute'.")
+ (Error 501, Line 8, Col 5, Line 8, Col 32, "The object constructor 'StructuralComparisonAttribute' takes 0 argument(s) but is here given 1. The required signature is 'new: unit -> StructuralComparisonAttribute'.")
]
// SOURCE=Test16.fs SCFLAGS="--test:ErrorRanges" # Test16.fs
@@ -204,8 +204,8 @@ module Legacy =
|> compile
|> shouldFail
|> withDiagnostics [
- (Error 501, Line 7, Col 5, Line 7, Col 22, "The object constructor 'ReferenceEqualityAttribute' takes 0 argument(s) but is here given 1. The required signature is 'new: unit -> ReferenceEqualityAttribute'.")
- (Error 501, Line 9, Col 5, Line 9, Col 23, "The object constructor 'StructuralEqualityAttribute' takes 0 argument(s) but is here given 1. The required signature is 'new: unit -> StructuralEqualityAttribute'.")
+ (Error 501, Line 7, Col 5, Line 7, Col 29, "The object constructor 'ReferenceEqualityAttribute' takes 0 argument(s) but is here given 1. The required signature is 'new: unit -> ReferenceEqualityAttribute'.")
+ (Error 501, Line 9, Col 5, Line 9, Col 29, "The object constructor 'StructuralEqualityAttribute' takes 0 argument(s) but is here given 1. The required signature is 'new: unit -> StructuralEqualityAttribute'.")
]
// SOURCE=Test17.fs SCFLAGS="--test:ErrorRanges" # Test17.fs
@@ -216,8 +216,8 @@ module Legacy =
|> compile
|> shouldFail
|> withDiagnostics [
- (Error 501, Line 6, Col 5, Line 6, Col 22, "The object constructor 'ReferenceEqualityAttribute' takes 0 argument(s) but is here given 1. The required signature is 'new: unit -> ReferenceEqualityAttribute'.")
- (Error 501, Line 8, Col 5, Line 8, Col 23, "The object constructor 'StructuralEqualityAttribute' takes 0 argument(s) but is here given 1. The required signature is 'new: unit -> StructuralEqualityAttribute'.")
+ (Error 501, Line 6, Col 5, Line 6, Col 29, "The object constructor 'ReferenceEqualityAttribute' takes 0 argument(s) but is here given 1. The required signature is 'new: unit -> ReferenceEqualityAttribute'.")
+ (Error 501, Line 8, Col 5, Line 8, Col 30, "The object constructor 'StructuralEqualityAttribute' takes 0 argument(s) but is here given 1. The required signature is 'new: unit -> StructuralEqualityAttribute'.")
]
// SOURCE=Test18.fs SCFLAGS="--test:ErrorRanges" # Test18.fs
@@ -228,7 +228,7 @@ module Legacy =
|> compile
|> shouldFail
|> withDiagnostics [
- (Error 501, Line 6, Col 5, Line 6, Col 22, "The object constructor 'ReferenceEqualityAttribute' takes 0 argument(s) but is here given 1. The required signature is 'new: unit -> ReferenceEqualityAttribute'.")
+ (Error 501, Line 6, Col 5, Line 6, Col 29, "The object constructor 'ReferenceEqualityAttribute' takes 0 argument(s) but is here given 1. The required signature is 'new: unit -> ReferenceEqualityAttribute'.")
]
// SOURCE=Test19.fs SCFLAGS="--test:ErrorRanges" # Test19.fs
@@ -239,8 +239,8 @@ module Legacy =
|> compile
|> shouldFail
|> withDiagnostics [
- (Error 501, Line 7, Col 5, Line 7, Col 25, "The object constructor 'StructuralComparisonAttribute' takes 0 argument(s) but is here given 1. The required signature is 'new: unit -> StructuralComparisonAttribute'.")
- (Error 501, Line 8, Col 5, Line 8, Col 23, "The object constructor 'StructuralEqualityAttribute' takes 0 argument(s) but is here given 1. The required signature is 'new: unit -> StructuralEqualityAttribute'.")
+ (Error 501, Line 7, Col 5, Line 7, Col 31, "The object constructor 'StructuralComparisonAttribute' takes 0 argument(s) but is here given 1. The required signature is 'new: unit -> StructuralComparisonAttribute'.")
+ (Error 501, Line 8, Col 5, Line 8, Col 29, "The object constructor 'StructuralEqualityAttribute' takes 0 argument(s) but is here given 1. The required signature is 'new: unit -> StructuralEqualityAttribute'.")
]
// SOURCE=Test20.fs SCFLAGS="--test:ErrorRanges" # Test20.fs
@@ -251,8 +251,8 @@ module Legacy =
|> compile
|> shouldFail
|> withDiagnostics [
- (Error 501, Line 7, Col 5, Line 7, Col 25, "The object constructor 'StructuralComparisonAttribute' takes 0 argument(s) but is here given 1. The required signature is 'new: unit -> StructuralComparisonAttribute'.")
- (Error 501, Line 8, Col 5, Line 8, Col 23, "The object constructor 'StructuralEqualityAttribute' takes 0 argument(s) but is here given 1. The required signature is 'new: unit -> StructuralEqualityAttribute'.")
+ (Error 501, Line 7, Col 5, Line 7, Col 31, "The object constructor 'StructuralComparisonAttribute' takes 0 argument(s) but is here given 1. The required signature is 'new: unit -> StructuralComparisonAttribute'.")
+ (Error 501, Line 8, Col 5, Line 8, Col 30, "The object constructor 'StructuralEqualityAttribute' takes 0 argument(s) but is here given 1. The required signature is 'new: unit -> StructuralEqualityAttribute'.")
]
// SOURCE=Test21.fs SCFLAGS="--test:ErrorRanges" # Test21.fs
@@ -263,7 +263,7 @@ module Legacy =
|> compile
|> shouldFail
|> withDiagnostics [
- (Error 501, Line 6, Col 5, Line 6, Col 25, "The object constructor 'StructuralComparisonAttribute' takes 0 argument(s) but is here given 1. The required signature is 'new: unit -> StructuralComparisonAttribute'.")
+ (Error 501, Line 6, Col 5, Line 6, Col 31, "The object constructor 'StructuralComparisonAttribute' takes 0 argument(s) but is here given 1. The required signature is 'new: unit -> StructuralComparisonAttribute'.")
]
// SOURCE=Test22.fs SCFLAGS="--test:ErrorRanges" # Test22.fs
@@ -274,8 +274,8 @@ module Legacy =
|> compile
|> shouldFail
|> withDiagnostics [
- (Error 501, Line 7, Col 5, Line 7, Col 25, "The object constructor 'StructuralComparisonAttribute' takes 0 argument(s) but is here given 1. The required signature is 'new: unit -> StructuralComparisonAttribute'.")
- (Error 501, Line 8, Col 5, Line 8, Col 23, "The object constructor 'StructuralEqualityAttribute' takes 0 argument(s) but is here given 1. The required signature is 'new: unit -> StructuralEqualityAttribute'.")
+ (Error 501, Line 7, Col 5, Line 7, Col 32, "The object constructor 'StructuralComparisonAttribute' takes 0 argument(s) but is here given 1. The required signature is 'new: unit -> StructuralComparisonAttribute'.")
+ (Error 501, Line 8, Col 5, Line 8, Col 29, "The object constructor 'StructuralEqualityAttribute' takes 0 argument(s) but is here given 1. The required signature is 'new: unit -> StructuralEqualityAttribute'.")
]
// SOURCE=Test23.fs SCFLAGS="--test:ErrorRanges" # Test23.fs
@@ -286,8 +286,8 @@ module Legacy =
|> compile
|> shouldFail
|> withDiagnostics [
- (Error 501, Line 9, Col 5, Line 9, Col 25, "The object constructor 'StructuralComparisonAttribute' takes 0 argument(s) but is here given 1. The required signature is 'new: unit -> StructuralComparisonAttribute'.")
- (Error 501, Line 10, Col 5, Line 10, Col 23, "The object constructor 'StructuralEqualityAttribute' takes 0 argument(s) but is here given 1. The required signature is 'new: unit -> StructuralEqualityAttribute'.")
+ (Error 501, Line 9, Col 5, Line 9, Col 32, "The object constructor 'StructuralComparisonAttribute' takes 0 argument(s) but is here given 1. The required signature is 'new: unit -> StructuralComparisonAttribute'.")
+ (Error 501, Line 10, Col 5, Line 10, Col 30, "The object constructor 'StructuralEqualityAttribute' takes 0 argument(s) but is here given 1. The required signature is 'new: unit -> StructuralEqualityAttribute'.")
]
// SOURCE=Test24.fs SCFLAGS="--test:ErrorRanges" # Test24.fs
@@ -298,7 +298,7 @@ module Legacy =
|> compile
|> shouldFail
|> withDiagnostics [
- (Error 501, Line 6, Col 5, Line 6, Col 25, "The object constructor 'StructuralComparisonAttribute' takes 0 argument(s) but is here given 1. The required signature is 'new: unit -> StructuralComparisonAttribute'.")
+ (Error 501, Line 6, Col 5, Line 6, Col 32, "The object constructor 'StructuralComparisonAttribute' takes 0 argument(s) but is here given 1. The required signature is 'new: unit -> StructuralComparisonAttribute'.")
]
// SOURCE=Test25.fs SCFLAGS="--test:ErrorRanges" # Test25.fs
@@ -309,7 +309,7 @@ module Legacy =
|> compile
|> shouldFail
|> withDiagnostics [
- (Error 501, Line 7, Col 5, Line 7, Col 23, "The object constructor 'StructuralEqualityAttribute' takes 0 argument(s) but is here given 1. The required signature is 'new: unit -> StructuralEqualityAttribute'.")
+ (Error 501, Line 7, Col 5, Line 7, Col 29, "The object constructor 'StructuralEqualityAttribute' takes 0 argument(s) but is here given 1. The required signature is 'new: unit -> StructuralEqualityAttribute'.")
]
// SOURCE=Test26.fs SCFLAGS="--test:ErrorRanges" # Test26.fs
@@ -320,7 +320,7 @@ module Legacy =
|> compile
|> shouldFail
|> withDiagnostics [
- (Error 501, Line 7, Col 5, Line 7, Col 23, "The object constructor 'StructuralEqualityAttribute' takes 0 argument(s) but is here given 1. The required signature is 'new: unit -> StructuralEqualityAttribute'.")
+ (Error 501, Line 7, Col 5, Line 7, Col 30, "The object constructor 'StructuralEqualityAttribute' takes 0 argument(s) but is here given 1. The required signature is 'new: unit -> StructuralEqualityAttribute'.")
]
// SOURCE=Test27.fs SCFLAGS="--test:ErrorRanges" # Test27.fs
@@ -340,7 +340,7 @@ module Legacy =
|> compile
|> shouldFail
|> withDiagnostics [
- (Error 501, Line 7, Col 3, Line 7, Col 21, "The object constructor 'StructuralEqualityAttribute' takes 0 argument(s) but is here given 1. The required signature is 'new: unit -> StructuralEqualityAttribute'.")
+ (Error 501, Line 7, Col 3, Line 7, Col 28, "The object constructor 'StructuralEqualityAttribute' takes 0 argument(s) but is here given 1. The required signature is 'new: unit -> StructuralEqualityAttribute'.")
]
diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/DeclarationElements/CustomAttributes/AttributeUsage/AttributeUsage.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/DeclarationElements/CustomAttributes/AttributeUsage/AttributeUsage.fs
index eeac02384ab..0161db9cd6e 100644
--- a/tests/FSharp.Compiler.ComponentTests/Conformance/DeclarationElements/CustomAttributes/AttributeUsage/AttributeUsage.fs
+++ b/tests/FSharp.Compiler.ComponentTests/Conformance/DeclarationElements/CustomAttributes/AttributeUsage/AttributeUsage.fs
@@ -79,8 +79,8 @@ module AttributeUsage =
|> shouldFail
|> withDiagnostics [
(Error 842, Line 21, Col 21, Line 21, Col 22, "This attribute is not valid for use on this language element")
- (Error 842, Line 24, Col 28, Line 24, Col 29, "This attribute is not valid for use on this language element")
- (Error 842, Line 27, Col 15, Line 27, Col 16, "This attribute is not valid for use on this language element")
+ (Error 842, Line 24, Col 21, Line 24, Col 29, "This attribute is not valid for use on this language element")
+ (Error 842, Line 27, Col 7, Line 27, Col 16, "This attribute is not valid for use on this language element")
]
// SOURCE=E_AttributeTargets02.fs # E_AttributeTargets02.fs
@@ -90,9 +90,9 @@ module AttributeUsage =
|> verifyCompile
|> shouldFail
|> withDiagnostics [
- (Error 842, Line 14, Col 17, Line 14, Col 34, "This attribute is not valid for use on this language element")
- (Error 842, Line 24, Col 14, Line 24, Col 29, "This attribute is not valid for use on this language element")
- (Error 842, Line 29, Col 25, Line 29, Col 40, "This attribute is not valid for use on this language element")
+ (Error 842, Line 14, Col 7, Line 14, Col 34, "This attribute is not valid for use on this language element")
+ (Error 842, Line 24, Col 7, Line 24, Col 36, "This attribute is not valid for use on this language element")
+ (Error 842, Line 29, Col 15, Line 29, Col 47, "This attribute is not valid for use on this language element")
]
// SOURCE=E_ConditionalAttribute.fs SCFLAGS="--test:ErrorRanges" # E_ConditionalAttribute.fs
diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/DeclarationElements/CustomAttributes/Basic/Basic.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/DeclarationElements/CustomAttributes/Basic/Basic.fs
index 8bc5e456829..829d0f86f79 100644
--- a/tests/FSharp.Compiler.ComponentTests/Conformance/DeclarationElements/CustomAttributes/Basic/Basic.fs
+++ b/tests/FSharp.Compiler.ComponentTests/Conformance/DeclarationElements/CustomAttributes/Basic/Basic.fs
@@ -41,7 +41,7 @@ module Basic =
|> verifyCompile
|> shouldFail
|> withDiagnostics [
- (Error 841, Line 7, Col 12, Line 7, Col 49, "This attribute is not valid for use on this language element. Assembly attributes should be attached to a 'do ()' declaration, if necessary within an F# module.")
+ (Error 841, Line 7, Col 3, Line 7, Col 111, "This attribute is not valid for use on this language element. Assembly attributes should be attached to a 'do ()' declaration, if necessary within an F# module.")
]
// SOURCE=E_AttributeApplication02.fs SCFLAGS="--test:ErrorRanges" # E_AttributeApplication02.fs
@@ -106,8 +106,8 @@ module Basic =
(Error 1, Line 10, Col 3, Line 10, Col 59, "This expression was expected to have type\n 'int array' \nbut here has type\n 'unit' ")
(Error 267, Line 10, Col 3, Line 10, Col 59, "This is not a valid constant expression or custom attribute value")
(Error 850, Line 10, Col 3, Line 10, Col 59, "This attribute cannot be used in this version of F#")
- (Error 850, Line 13, Col 3, Line 13, Col 52, "This attribute cannot be used in this version of F#")
- (Error 850, Line 16, Col 13, Line 16, Col 37, "This attribute cannot be used in this version of F#")
+ (Error 850, Line 13, Col 3, Line 13, Col 101, "This attribute cannot be used in this version of F#")
+ (Error 850, Line 16, Col 3, Line 16, Col 50, "This attribute cannot be used in this version of F#")
]
// SOURCE=E_AttributeTargetSpecifications.fs # E_AttributeTargetSpecifications.fs
@@ -305,7 +305,7 @@ module Basic =
|> verifyCompile
|> shouldFail
|> withDiagnostics [
- (Error 429, Line 16, Col 28, Line 16, Col 31, "The attribute type 'CA1' has 'AllowMultiple=false'. Multiple instances of this attribute cannot be attached to a single language element.")
+ (Error 429, Line 16, Col 28, Line 16, Col 37, "The attribute type 'CA1' has 'AllowMultiple=false'. Multiple instances of this attribute cannot be attached to a single language element.")
]
// SOURCE=W_StructLayoutExplicit01.fs SCFLAGS="--test:ErrorRanges" PEVER="/Exp_Fail" # W_StructLayoutExplicit01.fs
diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/DeclarationElements/LetBindings/Basic/Basic.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/DeclarationElements/LetBindings/Basic/Basic.fs
index fc9e36d748e..c472ec9b0ea 100644
--- a/tests/FSharp.Compiler.ComponentTests/Conformance/DeclarationElements/LetBindings/Basic/Basic.fs
+++ b/tests/FSharp.Compiler.ComponentTests/Conformance/DeclarationElements/LetBindings/Basic/Basic.fs
@@ -53,9 +53,9 @@ module Basic =
|> shouldFail
|> withDiagnostics [
(Error 683, Line 14, Col 6, Line 14, Col 27, "Attributes are not allowed within patterns")
- (Error 842, Line 14, Col 8, Line 14, Col 23, "This attribute is not valid for use on this language element")
+ (Error 842, Line 14, Col 8, Line 14, Col 25, "This attribute is not valid for use on this language element")
(Error 683, Line 14, Col 42, Line 14, Col 63, "Attributes are not allowed within patterns")
- (Error 842, Line 14, Col 44, Line 14, Col 59, "This attribute is not valid for use on this language element")
+ (Error 842, Line 14, Col 44, Line 14, Col 61, "This attribute is not valid for use on this language element")
]
// SOURCE=E_ErrorsForInlineValue.fs SCFLAGS="--test:ErrorRanges" # E_ErrorsForInlineValue.fs
diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/StructDefensiveCopy/StructDefensiveCopy.fs b/tests/FSharp.Compiler.ComponentTests/EmittedIL/StructDefensiveCopy/StructDefensiveCopy.fs
new file mode 100644
index 00000000000..fe7f88ff74a
--- /dev/null
+++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/StructDefensiveCopy/StructDefensiveCopy.fs
@@ -0,0 +1,158 @@
+module FSharp.Compiler.ComponentTests.EmittedIL.StructDefensiveCopy
+
+open Xunit
+open System.IO
+open FSharp.Test
+open FSharp.Test.Compiler
+
+let verifyKeyValuePairInstanceMethodCall expectedIl =
+ FSharp """
+module StructUnion01
+open System.Runtime.CompilerServices
+open System.Collections.Generic
+
+let doWork(kvp1:inref>) =
+ kvp1.ToString()
+ """
+ |> ignoreWarnings
+ |> compile
+ |> shouldSucceed
+ |> verifyIL expectedIl
+
+#if NETSTANDARD
+// KeyValuePair defined as a readonly struct (in C#)
+[]
+let ``Defensive copy can be skipped on read-only structs``() =
+ verifyKeyValuePairInstanceMethodCall [""" .method public static string doWork([in] valuetype [runtime]System.Collections.Generic.KeyValuePair`2& kvp1) cil managed
+ {
+ .param [1]
+ .custom instance void [runtime]System.Runtime.CompilerServices.IsReadOnlyAttribute::.ctor() = ( 01 00 00 00 )
+
+ .maxstack 8
+ IL_0000: ldarg.0
+ IL_0001: constrained. valuetype [runtime]System.Collections.Generic.KeyValuePair`2
+ IL_0007: callvirt instance string [runtime]System.Object::ToString()
+ IL_000c: ret
+ }
+
+} """]
+
+#else
+// KeyValuePair just a regular struct. Notice the "ldobj" instruction
+[]
+let ``Non readonly struct needs a defensive copy``() =
+ verifyKeyValuePairInstanceMethodCall [""" .method public static string doWork([in] valuetype [runtime]System.Collections.Generic.KeyValuePair`2& kvp1) cil managed
+ {
+ .param [1]
+ .custom instance void [runtime]System.Runtime.CompilerServices.IsReadOnlyAttribute::.ctor() = ( 01 00 00 00 )
+
+ .maxstack 3
+ .locals init (valuetype [runtime]System.Collections.Generic.KeyValuePair`2 V_0)
+ IL_0000: ldarg.0
+ IL_0001: ldobj valuetype [runtime]System.Collections.Generic.KeyValuePair`2
+ IL_0006: stloc.0
+ IL_0007: ldloca.s V_0
+ IL_0009: constrained. valuetype [runtime]System.Collections.Generic.KeyValuePair`2
+ IL_000f: callvirt instance string [runtime]System.Object::ToString()
+ IL_0014: ret
+ } """]
+#endif
+
+let verifyDateTimeExtensionMethodCall expectedIl =
+ FSharp """
+module DateTimeExtensionMethod
+
+open System
+open System.Collections.Generic
+open System.Runtime.CompilerServices
+
+[]
+type DateTimeExtensions =
+ []
+ static member PrintDate(d: inref) = d.ToString()
+
+let doWork(dt:inref) =
+ dt.PrintDate()
+ """
+ |> ignoreWarnings
+ |> compile
+ |> shouldSucceed
+ |> verifyIL expectedIl
+
+#if NETSTANDARD
+// DateTime defined as a readonly struct (in C#)
+[]
+let ``Defensive copy can be skipped for extension methods on read-only structs``() =
+ verifyDateTimeExtensionMethodCall [""" .method public static string doWork([in] valuetype [runtime]System.DateTime& dt) cil managed
+ {
+ .param [1]
+ .custom instance void [runtime]System.Runtime.CompilerServices.IsReadOnlyAttribute::.ctor() = ( 01 00 00 00 )
+
+ .maxstack 8
+ IL_0000: ldarg.0
+ IL_0001: constrained. [runtime]System.DateTime
+ IL_0007: callvirt instance string [runtime]System.Object::ToString()
+ IL_000c: ret
+ } """]
+
+#else
+// DateTime just a regular struct. Notice the "ldobj" instruction
+[]
+let ``Non readonly struct needs a defensive copy when its extension method is called``() =
+ verifyDateTimeExtensionMethodCall [""" .method public static string doWork([in] valuetype [runtime]System.DateTime& dt) cil managed
+ {
+ .param [1]
+ .custom instance void [runtime]System.Runtime.CompilerServices.IsReadOnlyAttribute::.ctor() = ( 01 00 00 00 )
+
+ .maxstack 3
+ .locals init (valuetype [runtime]System.DateTime& V_0,
+ valuetype [runtime]System.DateTime V_1)
+ IL_0000: ldarg.0
+ IL_0001: stloc.0
+ IL_0002: ldloc.0
+ IL_0003: ldobj [runtime]System.DateTime
+ IL_0008: stloc.1
+ IL_0009: ldloca.s V_1
+ IL_000b: constrained. [runtime]System.DateTime
+ IL_0011: callvirt instance string [runtime]System.Object::ToString()
+ IL_0016: ret
+ } """]
+#endif
+
+
+#if NETSTANDARD
+[]
+#endif
+let ``Csharp extension method on a readonly struct does not need defensive copy``() =
+ let csLib =
+ CSharp """
+using System;
+public static class DateTimeExtensionMethod
+{
+ public static string CustomPrintDate(this in DateTime d)
+ {
+ return d.Date.ToShortDateString();
+ }
+}""" |> withName "CsLib"
+
+ FSharp """
+module DateTimeDefinedInCsharpUsage
+open System
+let doWork(dt:inref) =
+ dt.CustomPrintDate()
+ """
+ |> withReferences [csLib]
+ |> ignoreWarnings
+ |> compile
+ |> shouldSucceed
+ |> verifyIL [""" .method public static string doWork([in] valuetype [runtime]System.DateTime& dt) cil managed
+ {
+ .param [1]
+ .custom instance void [runtime]System.Runtime.CompilerServices.IsReadOnlyAttribute::.ctor() = ( 01 00 00 00 )
+
+ .maxstack 8
+ IL_0000: ldarg.0
+ IL_0001: call string [CsLib]DateTimeExtensionMethod::CustomPrintDate(valuetype [runtime]System.DateTime&)
+ IL_0006: ret
+ } """]
+
diff --git a/tests/FSharp.Compiler.ComponentTests/ErrorMessages/UnionCasePatternMatchingErrors.fs b/tests/FSharp.Compiler.ComponentTests/ErrorMessages/UnionCasePatternMatchingErrors.fs
new file mode 100644
index 00000000000..b64dff5176c
--- /dev/null
+++ b/tests/FSharp.Compiler.ComponentTests/ErrorMessages/UnionCasePatternMatchingErrors.fs
@@ -0,0 +1,72 @@
+module FSharp.Compiler.ComponentTests.ErrorMessages.UnionCasePatternMatchingErrors
+
+open Xunit
+open FSharp.Test.Compiler
+
+[]
+let ``Union matching error - Incomplete union fields`` () =
+ FSharp """
+module Tests
+type U =
+ | B of f1:int list * {|X:string|} * f3:U * f4: (int * System.String)
+
+let x : U = failwith ""
+let myVal =
+ match x with
+ | B -> 42"""
+ |> typecheck
+ |> shouldFail
+ |> withSingleDiagnostic (Error 727, Line 9, Col 7, Line 9, Col 8,
+ "This union case expects 4 arguments in tupled form, but was given 0. The missing field arguments may be any of:
+\tf1: int list
+\t{| X: string |}
+\tf3: U
+\tf4: (int * System.String)")
+
+[]
+let ``Union matching error - Named args - Name used twice`` () =
+ FSharp """
+module Tests
+type U =
+ | B of field: int * int
+let x : U = failwith ""
+let myVal =
+ match x with
+ | B (field = x; field = z) -> let y = x + z + 1 in ()"""
+ |> typecheck
+ |> shouldFail
+ |> withSingleDiagnostic (Error 3175, Line 8, Col 21, Line 8, Col 26, "Union case/exception field 'field' cannot be used more than once.")
+
+[]
+let ``Union matching error - Multiple tupled args`` () =
+ FSharp """
+module Tests
+type U =
+ | B of field: int * int
+
+let x : U = failwith ""
+let myVal =
+ match x with
+ | B x z -> let y = x + z + 1 in ()"""
+ |> typecheck
+ |> shouldFail
+ |> withSingleDiagnostic (Error 727, Line 9, Col 7, Line 9, Col 12, "This union case expects 2 arguments in tupled form, but was given 0. The missing field arguments may be any of:
+\tfield: int
+\tint")
+
+[]
+let ``Union matching error - Missing field`` () =
+ FSharp """
+module Tests
+type U =
+ | A
+ | B of int * int * int
+
+let myVal =
+ match A with
+ | A -> 15
+ | B (x, _) -> 16"""
+ |> typecheck
+ |> shouldFail
+ |> withSingleDiagnostic (Error 727, Line 10, Col 7, Line 10, Col 15, "This union case expects 3 arguments in tupled form, but was given 2. The missing field arguments may be any of:
+\tint")
\ No newline at end of file
diff --git a/tests/FSharp.Compiler.ComponentTests/ErrorMessages/UnsupportedAttributes.fs b/tests/FSharp.Compiler.ComponentTests/ErrorMessages/UnsupportedAttributes.fs
index 439b0bd7bdb..276bad5963c 100644
--- a/tests/FSharp.Compiler.ComponentTests/ErrorMessages/UnsupportedAttributes.fs
+++ b/tests/FSharp.Compiler.ComponentTests/ErrorMessages/UnsupportedAttributes.fs
@@ -27,7 +27,7 @@ type C() =
Range = { StartLine = 3
StartColumn = 13
EndLine = 3
- EndColumn = 37 }
+ EndColumn = 41 }
Message =
"This attribute is currently unsupported by the F# compiler. Applying it will not achieve its intended effect." }
{ Error = Warning 202
@@ -41,7 +41,7 @@ type C() =
Range = { StartLine = 6
StartColumn = 22
EndLine = 6
- EndColumn = 78 }
+ EndColumn = 82 }
Message =
"This attribute is currently unsupported by the F# compiler. Applying it will not achieve its intended effect." }
{ Error = Warning 202
diff --git a/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj b/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj
index 4acda7d0cd7..0b5e005d7b7 100644
--- a/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj
+++ b/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj
@@ -134,6 +134,7 @@
+
@@ -158,6 +159,7 @@
+
diff --git a/tests/FSharp.Compiler.ComponentTests/Language/ObsoleteAttributeCheckingTests.fs b/tests/FSharp.Compiler.ComponentTests/Language/ObsoleteAttributeCheckingTests.fs
index c2fa57509fc..20e785370a3 100644
--- a/tests/FSharp.Compiler.ComponentTests/Language/ObsoleteAttributeCheckingTests.fs
+++ b/tests/FSharp.Compiler.ComponentTests/Language/ObsoleteAttributeCheckingTests.fs
@@ -205,10 +205,80 @@ C.Update()
|> shouldFail
|> withDiagnostics [
(Error 101, Line 9, Col 1, Line 9, Col 9, "This construct is deprecated. Use B instead")
- ]
+ ]
[]
- let ``Obsolete attribute is taken into account when used on an enum and invocation`` () =
+ let ``Obsolete attribute error is taken into account when used on a struct du and invocation`` () =
+ Fsx """
+open System
+[]
+[]
+type Color =
+ | Red
+ | Green
+
+let c = Color.Red
+ """
+ |> ignoreWarnings
+ |> compile
+ |> shouldFail
+ |> withDiagnostics [
+ (Error 101, Line 9, Col 9, Line 9, Col 14, "This construct is deprecated. Use B instead")
+ ]
+
+ []
+ let ``Obsolete attribute error is taken into account when used on a du and invocation`` () =
+ Fsx """
+open System
+[]
+type Color =
+ | Red
+ | Green
+
+let c = Color.Red
+ """
+ |> ignoreWarnings
+ |> compile
+ |> shouldFail
+ |> withDiagnostics [
+ (Error 101, Line 8, Col 9, Line 8, Col 14, "This construct is deprecated. Use B instead")
+ ]
+
+ []
+ let ``Obsolete attribute error is taken into account when used on a du field and invocation`` () =
+ Fsx """
+open System
+type Color =
+ | [] Red
+ | Green
+
+let c = Color.Red
+ """
+ |> ignoreWarnings
+ |> compile
+ |> shouldFail
+ |> withDiagnostics [
+ (Error 101, Line 7, Col 9, Line 7, Col 18, "This construct is deprecated. Use B instead")
+ ]
+
+ []
+ let ``Obsolete attribute warning is taken into account when used on a du field and invocation`` () =
+ Fsx """
+open System
+type Color =
+ | [] Red
+ | Green
+
+let c = Color.Red
+ """
+ |> compile
+ |> shouldFail
+ |> withDiagnostics [
+ (Warning 44, Line 7, Col 9, Line 7, Col 18, "This construct is deprecated. Use B instead")
+ ]
+
+ []
+ let ``Obsolete attribute error is taken into account when used on an enum and invocation`` () =
Fsx """
open System
@@ -219,15 +289,14 @@ type Color =
let c = Color.Red
"""
- |> ignoreWarnings
|> compile
|> shouldFail
|> withDiagnostics [
(Error 101, Line 9, Col 9, Line 9, Col 14, "This construct is deprecated. Use B instead")
]
-
+
[]
- let ``Obsolete attribute is taken into account when used on an enum entry and invocation`` () =
+ let ``Obsolete attribute error is taken into account when used on an enum field and invocation`` () =
Fsx """
open System
@@ -237,9 +306,28 @@ type Color =
let c = Color.Red
"""
- |> ignoreWarnings
|> compile
- |> shouldSucceed
+ |> shouldFail
+ |> withDiagnostics [
+ (Error 101, Line 8, Col 9, Line 8, Col 18, "This construct is deprecated. Use B instead")
+ ]
+
+ []
+ let ``Obsolete attribute warning is taken into account when used on an enum field and invocation`` () =
+ Fsx """
+open System
+
+type Color =
+ | [] Red = 0
+ | Green = 1
+
+let c = Color.Red
+ """
+ |> compile
+ |> shouldFail
+ |> withDiagnostics [
+ (Warning 44, Line 8, Col 9, Line 8, Col 18, "This construct is deprecated. Use B instead")
+ ]
[]
let ``Obsolete attribute is taken into account when used on an type and use extension method`` () =
@@ -899,6 +987,7 @@ Class.ObsoleteEvent |> ignore
(Warning 44, Line 3, Col 1, Line 3, Col 20, "This construct is deprecated. Field is obsolete");
(Warning 44, Line 4, Col 1, Line 4, Col 21, "This construct is deprecated. Method is obsolete");
(Warning 44, Line 5, Col 1, Line 5, Col 23, "This construct is deprecated. Property is obsolete")
+ (Warning 44, Line 6, Col 1, Line 6, Col 20, "This construct is deprecated. Event is obsolete")
]
[]
@@ -937,4 +1026,5 @@ Class.ObsoleteEvent |> ignore
(Error 101, Line 3, Col 1, Line 3, Col 20, "This construct is deprecated. Field is obsolete");
(Error 101, Line 4, Col 1, Line 4, Col 21, "This construct is deprecated. Method is obsolete");
(Error 101, Line 5, Col 1, Line 5, Col 23, "This construct is deprecated. Property is obsolete")
+ (Error 101, Line 6, Col 1, Line 6, Col 20, "This construct is deprecated. Event is obsolete")
]
diff --git a/tests/FSharp.Compiler.ComponentTests/resources/tests/CompilerOptions/fsc/warn/nowarn_readonlystruct.fs b/tests/FSharp.Compiler.ComponentTests/resources/tests/CompilerOptions/fsc/warn/nowarn_readonlystruct.fs
new file mode 100644
index 00000000000..2a4f0152709
--- /dev/null
+++ b/tests/FSharp.Compiler.ComponentTests/resources/tests/CompilerOptions/fsc/warn/nowarn_readonlystruct.fs
@@ -0,0 +1,9 @@
+// #Regression #NoMT #CompilerOptions
+// See DevDiv:364238
+open System.Collections.Generic
+
+let x : IEnumerator> = failwith ""
+printfn "%A" x.Current.Key // no defensive copy needed, because KeyValuePair is a "readonly struct"
+
+let y : list> = failwith "" // KeyValuePair
+printfn "%A" y.[0].Key // no defensive copy needed, because KeyValuePair is a "readonly struct"
diff --git a/tests/FSharp.Compiler.ComponentTests/resources/tests/CompilerOptions/fsc/warn/warn_level5.fs b/tests/FSharp.Compiler.ComponentTests/resources/tests/CompilerOptions/fsc/warn/warn_level5.fs
index d33dfcf9eec..2b6115e5718 100644
--- a/tests/FSharp.Compiler.ComponentTests/resources/tests/CompilerOptions/fsc/warn/warn_level5.fs
+++ b/tests/FSharp.Compiler.ComponentTests/resources/tests/CompilerOptions/fsc/warn/warn_level5.fs
@@ -2,8 +2,12 @@
// See DevDiv:364238
open System.Collections.Generic
-let x : IEnumerator> = failwith ""
-printfn "%A" x.Current.Key // defensive copy
+[]
+type NonReadOnlyStruct=
+ member val Property = "" with get, set
-let y : list> = failwith ""
-printfn "%A" y.[0].Key // defensive copy
+let x : IEnumerator = failwith ""
+printfn "%A" x.Current.Property // defensive copy
+
+let y : list = failwith "" // KeyValuePair
+printfn "%A" y.[0].Property // defensive copy
diff --git a/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.Tests.fsproj b/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.Tests.fsproj
index 19175fd7f05..202bd49532e 100644
--- a/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.Tests.fsproj
+++ b/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.Tests.fsproj
@@ -101,6 +101,9 @@
SyntaxTree\MemberFlagTests.fs
+
+ SyntaxTree\MemberTests.fs
+
SyntaxTree\ComputationExpressionTests.fs
@@ -116,6 +119,12 @@
SyntaxTree\SynIdentTests.fs
+
+ SyntaxTree\AttributeTests.fs
+
+
+ SyntaxTree\ExternTests.fs
+
FileSystemTests.fs
diff --git a/tests/FSharp.Compiler.Service.Tests/FSharp.CompilerService.SurfaceArea.netstandard.expected b/tests/FSharp.Compiler.Service.Tests/FSharp.CompilerService.SurfaceArea.netstandard.expected
index 736193358e7..1d2367fb0a6 100644
--- a/tests/FSharp.Compiler.Service.Tests/FSharp.CompilerService.SurfaceArea.netstandard.expected
+++ b/tests/FSharp.Compiler.Service.Tests/FSharp.CompilerService.SurfaceArea.netstandard.expected
@@ -3977,7 +3977,6 @@ FSharp.Compiler.EditorServices.ToolTipElementData
FSharp.Compiler.EditorServices.ToolTipElementData: Boolean Equals(FSharp.Compiler.EditorServices.ToolTipElementData)
FSharp.Compiler.EditorServices.ToolTipElementData: Boolean Equals(System.Object)
FSharp.Compiler.EditorServices.ToolTipElementData: Boolean Equals(System.Object, System.Collections.IEqualityComparer)
-FSharp.Compiler.EditorServices.ToolTipElementData: FSharp.Compiler.EditorServices.ToolTipElementData Create(FSharp.Compiler.Text.TaggedText[], FSharp.Compiler.Symbols.FSharpXmlDoc, Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Text.TaggedText[]]], Microsoft.FSharp.Core.FSharpOption`1[System.String], Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.TaggedText[]])
FSharp.Compiler.EditorServices.ToolTipElementData: FSharp.Compiler.Symbols.FSharpXmlDoc XmlDoc
FSharp.Compiler.EditorServices.ToolTipElementData: FSharp.Compiler.Symbols.FSharpXmlDoc get_XmlDoc()
FSharp.Compiler.EditorServices.ToolTipElementData: FSharp.Compiler.Text.TaggedText[] MainDescription
@@ -5830,6 +5829,8 @@ FSharp.Compiler.Syntax.SynArgInfo: Microsoft.FSharp.Core.FSharpOption`1[FSharp.C
FSharp.Compiler.Syntax.SynArgInfo: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Syntax.Ident] ident
FSharp.Compiler.Syntax.SynArgInfo: System.String ToString()
FSharp.Compiler.Syntax.SynArgPats
+FSharp.Compiler.Syntax.SynArgPats+NamePatPairs: FSharp.Compiler.SyntaxTrivia.SynArgPatsNamePatPairsTrivia get_trivia()
+FSharp.Compiler.Syntax.SynArgPats+NamePatPairs: FSharp.Compiler.SyntaxTrivia.SynArgPatsNamePatPairsTrivia trivia
FSharp.Compiler.Syntax.SynArgPats+NamePatPairs: FSharp.Compiler.Text.Range get_range()
FSharp.Compiler.Syntax.SynArgPats+NamePatPairs: FSharp.Compiler.Text.Range range
FSharp.Compiler.Syntax.SynArgPats+NamePatPairs: Microsoft.FSharp.Collections.FSharpList`1[System.Tuple`3[FSharp.Compiler.Syntax.Ident,FSharp.Compiler.Text.Range,FSharp.Compiler.Syntax.SynPat]] get_pats()
@@ -5842,7 +5843,7 @@ FSharp.Compiler.Syntax.SynArgPats: Boolean IsNamePatPairs
FSharp.Compiler.Syntax.SynArgPats: Boolean IsPats
FSharp.Compiler.Syntax.SynArgPats: Boolean get_IsNamePatPairs()
FSharp.Compiler.Syntax.SynArgPats: Boolean get_IsPats()
-FSharp.Compiler.Syntax.SynArgPats: FSharp.Compiler.Syntax.SynArgPats NewNamePatPairs(Microsoft.FSharp.Collections.FSharpList`1[System.Tuple`3[FSharp.Compiler.Syntax.Ident,FSharp.Compiler.Text.Range,FSharp.Compiler.Syntax.SynPat]], FSharp.Compiler.Text.Range)
+FSharp.Compiler.Syntax.SynArgPats: FSharp.Compiler.Syntax.SynArgPats NewNamePatPairs(Microsoft.FSharp.Collections.FSharpList`1[System.Tuple`3[FSharp.Compiler.Syntax.Ident,FSharp.Compiler.Text.Range,FSharp.Compiler.Syntax.SynPat]], FSharp.Compiler.Text.Range, FSharp.Compiler.SyntaxTrivia.SynArgPatsNamePatPairsTrivia)
FSharp.Compiler.Syntax.SynArgPats: FSharp.Compiler.Syntax.SynArgPats NewPats(Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynPat])
FSharp.Compiler.Syntax.SynArgPats: FSharp.Compiler.Syntax.SynArgPats+NamePatPairs
FSharp.Compiler.Syntax.SynArgPats: FSharp.Compiler.Syntax.SynArgPats+Pats
@@ -8003,6 +8004,14 @@ FSharp.Compiler.Syntax.SynPat+IsInst: FSharp.Compiler.Syntax.SynType get_pat()
FSharp.Compiler.Syntax.SynPat+IsInst: FSharp.Compiler.Syntax.SynType pat
FSharp.Compiler.Syntax.SynPat+IsInst: FSharp.Compiler.Text.Range get_range()
FSharp.Compiler.Syntax.SynPat+IsInst: FSharp.Compiler.Text.Range range
+FSharp.Compiler.Syntax.SynPat+ListCons: FSharp.Compiler.Syntax.SynPat get_lhsPat()
+FSharp.Compiler.Syntax.SynPat+ListCons: FSharp.Compiler.Syntax.SynPat get_rhsPat()
+FSharp.Compiler.Syntax.SynPat+ListCons: FSharp.Compiler.Syntax.SynPat lhsPat
+FSharp.Compiler.Syntax.SynPat+ListCons: FSharp.Compiler.Syntax.SynPat rhsPat
+FSharp.Compiler.Syntax.SynPat+ListCons: FSharp.Compiler.SyntaxTrivia.SynPatListConsTrivia get_trivia()
+FSharp.Compiler.Syntax.SynPat+ListCons: FSharp.Compiler.SyntaxTrivia.SynPatListConsTrivia trivia
+FSharp.Compiler.Syntax.SynPat+ListCons: FSharp.Compiler.Text.Range get_range()
+FSharp.Compiler.Syntax.SynPat+ListCons: FSharp.Compiler.Text.Range range
FSharp.Compiler.Syntax.SynPat+LongIdent: FSharp.Compiler.Syntax.SynArgPats argPats
FSharp.Compiler.Syntax.SynPat+LongIdent: FSharp.Compiler.Syntax.SynArgPats get_argPats()
FSharp.Compiler.Syntax.SynPat+LongIdent: FSharp.Compiler.Syntax.SynLongIdent get_longDotId()
@@ -8058,6 +8067,7 @@ FSharp.Compiler.Syntax.SynPat+Tags: Int32 DeprecatedCharRange
FSharp.Compiler.Syntax.SynPat+Tags: Int32 FromParseError
FSharp.Compiler.Syntax.SynPat+Tags: Int32 InstanceMember
FSharp.Compiler.Syntax.SynPat+Tags: Int32 IsInst
+FSharp.Compiler.Syntax.SynPat+Tags: Int32 ListCons
FSharp.Compiler.Syntax.SynPat+Tags: Int32 LongIdent
FSharp.Compiler.Syntax.SynPat+Tags: Int32 Named
FSharp.Compiler.Syntax.SynPat+Tags: Int32 Null
@@ -8092,6 +8102,7 @@ FSharp.Compiler.Syntax.SynPat: Boolean IsDeprecatedCharRange
FSharp.Compiler.Syntax.SynPat: Boolean IsFromParseError
FSharp.Compiler.Syntax.SynPat: Boolean IsInstanceMember
FSharp.Compiler.Syntax.SynPat: Boolean IsIsInst
+FSharp.Compiler.Syntax.SynPat: Boolean IsListCons
FSharp.Compiler.Syntax.SynPat: Boolean IsLongIdent
FSharp.Compiler.Syntax.SynPat: Boolean IsNamed
FSharp.Compiler.Syntax.SynPat: Boolean IsNull
@@ -8112,6 +8123,7 @@ FSharp.Compiler.Syntax.SynPat: Boolean get_IsDeprecatedCharRange()
FSharp.Compiler.Syntax.SynPat: Boolean get_IsFromParseError()
FSharp.Compiler.Syntax.SynPat: Boolean get_IsInstanceMember()
FSharp.Compiler.Syntax.SynPat: Boolean get_IsIsInst()
+FSharp.Compiler.Syntax.SynPat: Boolean get_IsListCons()
FSharp.Compiler.Syntax.SynPat: Boolean get_IsLongIdent()
FSharp.Compiler.Syntax.SynPat: Boolean get_IsNamed()
FSharp.Compiler.Syntax.SynPat: Boolean get_IsNull()
@@ -8132,6 +8144,7 @@ FSharp.Compiler.Syntax.SynPat: FSharp.Compiler.Syntax.SynPat NewDeprecatedCharRa
FSharp.Compiler.Syntax.SynPat: FSharp.Compiler.Syntax.SynPat NewFromParseError(FSharp.Compiler.Syntax.SynPat, FSharp.Compiler.Text.Range)
FSharp.Compiler.Syntax.SynPat: FSharp.Compiler.Syntax.SynPat NewInstanceMember(FSharp.Compiler.Syntax.Ident, FSharp.Compiler.Syntax.Ident, Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Syntax.Ident], Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Syntax.SynAccess], FSharp.Compiler.Text.Range)
FSharp.Compiler.Syntax.SynPat: FSharp.Compiler.Syntax.SynPat NewIsInst(FSharp.Compiler.Syntax.SynType, FSharp.Compiler.Text.Range)
+FSharp.Compiler.Syntax.SynPat: FSharp.Compiler.Syntax.SynPat NewListCons(FSharp.Compiler.Syntax.SynPat, FSharp.Compiler.Syntax.SynPat, FSharp.Compiler.Text.Range, FSharp.Compiler.SyntaxTrivia.SynPatListConsTrivia)
FSharp.Compiler.Syntax.SynPat: FSharp.Compiler.Syntax.SynPat NewLongIdent(FSharp.Compiler.Syntax.SynLongIdent, Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Syntax.Ident], Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Syntax.SynValTyparDecls], FSharp.Compiler.Syntax.SynArgPats, Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Syntax.SynAccess], FSharp.Compiler.Text.Range)
FSharp.Compiler.Syntax.SynPat: FSharp.Compiler.Syntax.SynPat NewNamed(FSharp.Compiler.Syntax.SynIdent, Boolean, Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Syntax.SynAccess], FSharp.Compiler.Text.Range)
FSharp.Compiler.Syntax.SynPat: FSharp.Compiler.Syntax.SynPat NewNull(FSharp.Compiler.Text.Range)
@@ -8152,6 +8165,7 @@ FSharp.Compiler.Syntax.SynPat: FSharp.Compiler.Syntax.SynPat+DeprecatedCharRange
FSharp.Compiler.Syntax.SynPat: FSharp.Compiler.Syntax.SynPat+FromParseError
FSharp.Compiler.Syntax.SynPat: FSharp.Compiler.Syntax.SynPat+InstanceMember
FSharp.Compiler.Syntax.SynPat: FSharp.Compiler.Syntax.SynPat+IsInst
+FSharp.Compiler.Syntax.SynPat: FSharp.Compiler.Syntax.SynPat+ListCons
FSharp.Compiler.Syntax.SynPat: FSharp.Compiler.Syntax.SynPat+LongIdent
FSharp.Compiler.Syntax.SynPat: FSharp.Compiler.Syntax.SynPat+Named
FSharp.Compiler.Syntax.SynPat: FSharp.Compiler.Syntax.SynPat+Null
@@ -9396,15 +9410,22 @@ FSharp.Compiler.SyntaxTrivia.ParsedSigFileInputTrivia: Microsoft.FSharp.Collecti
FSharp.Compiler.SyntaxTrivia.ParsedSigFileInputTrivia: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.SyntaxTrivia.ConditionalDirectiveTrivia] get_ConditionalDirectives()
FSharp.Compiler.SyntaxTrivia.ParsedSigFileInputTrivia: System.String ToString()
FSharp.Compiler.SyntaxTrivia.ParsedSigFileInputTrivia: Void .ctor(Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.SyntaxTrivia.ConditionalDirectiveTrivia], Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.SyntaxTrivia.CommentTrivia])
+FSharp.Compiler.SyntaxTrivia.SynArgPatsNamePatPairsTrivia
+FSharp.Compiler.SyntaxTrivia.SynArgPatsNamePatPairsTrivia: FSharp.Compiler.Text.Range ParenRange
+FSharp.Compiler.SyntaxTrivia.SynArgPatsNamePatPairsTrivia: FSharp.Compiler.Text.Range get_ParenRange()
+FSharp.Compiler.SyntaxTrivia.SynArgPatsNamePatPairsTrivia: System.String ToString()
+FSharp.Compiler.SyntaxTrivia.SynArgPatsNamePatPairsTrivia: Void .ctor(FSharp.Compiler.Text.Range)
FSharp.Compiler.SyntaxTrivia.SynBindingTrivia
FSharp.Compiler.SyntaxTrivia.SynBindingTrivia: FSharp.Compiler.SyntaxTrivia.SynBindingTrivia Zero
FSharp.Compiler.SyntaxTrivia.SynBindingTrivia: FSharp.Compiler.SyntaxTrivia.SynBindingTrivia get_Zero()
FSharp.Compiler.SyntaxTrivia.SynBindingTrivia: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range] EqualsRange
+FSharp.Compiler.SyntaxTrivia.SynBindingTrivia: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range] ExternKeyword
FSharp.Compiler.SyntaxTrivia.SynBindingTrivia: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range] LetKeyword
FSharp.Compiler.SyntaxTrivia.SynBindingTrivia: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range] get_EqualsRange()
+FSharp.Compiler.SyntaxTrivia.SynBindingTrivia: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range] get_ExternKeyword()
FSharp.Compiler.SyntaxTrivia.SynBindingTrivia: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range] get_LetKeyword()
FSharp.Compiler.SyntaxTrivia.SynBindingTrivia: System.String ToString()
-FSharp.Compiler.SyntaxTrivia.SynBindingTrivia: Void .ctor(Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range], Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range])
+FSharp.Compiler.SyntaxTrivia.SynBindingTrivia: Void .ctor(Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range], Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range], Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range])
FSharp.Compiler.SyntaxTrivia.SynEnumCaseTrivia
FSharp.Compiler.SyntaxTrivia.SynEnumCaseTrivia: FSharp.Compiler.Text.Range EqualsRange
FSharp.Compiler.SyntaxTrivia.SynEnumCaseTrivia: FSharp.Compiler.Text.Range get_EqualsRange()
@@ -9550,6 +9571,11 @@ FSharp.Compiler.SyntaxTrivia.SynModuleSigDeclNestedModuleTrivia: Microsoft.FShar
FSharp.Compiler.SyntaxTrivia.SynModuleSigDeclNestedModuleTrivia: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range] get_ModuleKeyword()
FSharp.Compiler.SyntaxTrivia.SynModuleSigDeclNestedModuleTrivia: System.String ToString()
FSharp.Compiler.SyntaxTrivia.SynModuleSigDeclNestedModuleTrivia: Void .ctor(Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range], Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range])
+FSharp.Compiler.SyntaxTrivia.SynPatListConsTrivia
+FSharp.Compiler.SyntaxTrivia.SynPatListConsTrivia: FSharp.Compiler.Text.Range ColonColonRange
+FSharp.Compiler.SyntaxTrivia.SynPatListConsTrivia: FSharp.Compiler.Text.Range get_ColonColonRange()
+FSharp.Compiler.SyntaxTrivia.SynPatListConsTrivia: System.String ToString()
+FSharp.Compiler.SyntaxTrivia.SynPatListConsTrivia: Void .ctor(FSharp.Compiler.Text.Range)
FSharp.Compiler.SyntaxTrivia.SynPatOrTrivia
FSharp.Compiler.SyntaxTrivia.SynPatOrTrivia: FSharp.Compiler.Text.Range BarRange
FSharp.Compiler.SyntaxTrivia.SynPatOrTrivia: FSharp.Compiler.Text.Range get_BarRange()
@@ -9901,8 +9927,6 @@ FSharp.Compiler.Tokenization.FSharpKeywords: Microsoft.FSharp.Collections.FSharp
FSharp.Compiler.Tokenization.FSharpKeywords: Microsoft.FSharp.Collections.FSharpList`1[System.String] get_KeywordNames()
FSharp.Compiler.Tokenization.FSharpKeywords: Microsoft.FSharp.Collections.FSharpList`1[System.Tuple`2[System.String,System.String]] KeywordsWithDescription
FSharp.Compiler.Tokenization.FSharpKeywords: Microsoft.FSharp.Collections.FSharpList`1[System.Tuple`2[System.String,System.String]] get_KeywordsWithDescription()
-FSharp.Compiler.Tokenization.FSharpKeywords: System.Collections.Generic.IDictionary`2[System.String,System.String] KeywordsDescriptionLookup
-FSharp.Compiler.Tokenization.FSharpKeywords: System.Collections.Generic.IDictionary`2[System.String,System.String] get_KeywordsDescriptionLookup()
FSharp.Compiler.Tokenization.FSharpKeywords: System.String NormalizeIdentifierBackticks(System.String)
FSharp.Compiler.Tokenization.FSharpLexer
FSharp.Compiler.Tokenization.FSharpLexer: Void Tokenize(FSharp.Compiler.Text.ISourceText, Microsoft.FSharp.Core.FSharpFunc`2[FSharp.Compiler.Tokenization.FSharpToken,Microsoft.FSharp.Core.Unit], Microsoft.FSharp.Core.FSharpOption`1[System.String], Microsoft.FSharp.Core.FSharpOption`1[System.String], Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Collections.FSharpList`1[System.String]], Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Tokenization.FSharpLexerFlags], Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Collections.FSharpMap`2[System.String,System.String]], Microsoft.FSharp.Core.FSharpOption`1[System.Threading.CancellationToken])
diff --git a/tests/fsharp/tests.fs b/tests/fsharp/tests.fs
index 44cf37b3268..a43f9b08d89 100644
--- a/tests/fsharp/tests.fs
+++ b/tests/fsharp/tests.fs
@@ -2586,6 +2586,21 @@ module TypecheckTests =
peverify cfg "pos40.exe"
exec cfg ("." ++ "pos40.exe") ""
+ []
+ let ``sigs pos1281`` () =
+ let cfg = testConfig "typecheck/sigs"
+ // This checks that warning 25 "incomplete matches" is not triggered
+ fsc cfg "%s --target:exe -o:pos1281.exe --warnaserror --nowarn:26" cfg.fsc_flags ["pos1281.fs"]
+ peverify cfg "pos1281.exe"
+ exec cfg ("." ++ "pos1281.exe") ""
+
+ []
+ let ``sigs pos3294`` () =
+ let cfg = testConfig "typecheck/sigs"
+ fsc cfg "%s --target:exe -o:pos3294.exe --warnaserror" cfg.fsc_flags ["pos3294.fs"]
+ peverify cfg "pos3294.exe"
+ exec cfg ("." ++ "pos3294.exe") ""
+
[]
let ``sigs pos23`` () =
let cfg = testConfig "typecheck/sigs"
diff --git a/tests/fsharp/typecheck/sigs/neg20.bsl b/tests/fsharp/typecheck/sigs/neg20.bsl
index 6fe2d2e3295..88f483967e4 100644
--- a/tests/fsharp/typecheck/sigs/neg20.bsl
+++ b/tests/fsharp/typecheck/sigs/neg20.bsl
@@ -271,7 +271,7 @@ neg20.fs(216,5,216,12): typecheck error FS0842: This attribute is not valid for
neg20.fs(219,5,219,15): typecheck error FS0842: This attribute is not valid for use on this language element
-neg20.fs(222,5,222,24): typecheck error FS0842: This attribute is not valid for use on this language element
+neg20.fs(222,5,222,31): typecheck error FS0842: This attribute is not valid for use on this language element
neg20.fs(225,5,225,22): typecheck error FS0842: This attribute is not valid for use on this language element
@@ -289,9 +289,9 @@ neg20.fs(243,5,243,23): typecheck error FS0842: This attribute is not valid for
neg20.fs(249,9,249,27): typecheck error FS0842: This attribute is not valid for use on this language element
-neg20.fs(255,5,255,21): typecheck error FS0842: This attribute is not valid for use on this language element
+neg20.fs(255,5,255,28): typecheck error FS0842: This attribute is not valid for use on this language element
-neg20.fs(258,5,258,31): typecheck error FS0842: This attribute is not valid for use on this language element
+neg20.fs(258,5,258,38): typecheck error FS0842: This attribute is not valid for use on this language element
neg20.fs(261,5,261,17): typecheck error FS0842: This attribute is not valid for use on this language element
@@ -299,7 +299,7 @@ neg20.fs(265,5,265,24): typecheck error FS0842: This attribute is not valid for
neg20.fs(268,5,268,27): typecheck error FS0842: This attribute is not valid for use on this language element
-neg20.fs(271,5,271,13): typecheck error FS0842: This attribute is not valid for use on this language element
+neg20.fs(271,5,271,15): typecheck error FS0842: This attribute is not valid for use on this language element
neg20.fs(278,14,278,95): typecheck error FS0507: No accessible member or object constructor named 'ProcessStartInfo' takes 0 arguments. Note the call to this member also provides 2 named arguments.
diff --git a/tests/fsharp/typecheck/sigs/neg31.bsl b/tests/fsharp/typecheck/sigs/neg31.bsl
index 86bb626f0b4..9140452d235 100644
--- a/tests/fsharp/typecheck/sigs/neg31.bsl
+++ b/tests/fsharp/typecheck/sigs/neg31.bsl
@@ -1,12 +1,12 @@
-neg31.fs(9,6,9,30): typecheck error FS1200: The attribute 'ObsoleteAttribute' appears in both the implementation and the signature, but the attribute arguments differ. Only the attribute from the signature will be included in the compiled code.
+neg31.fs(9,6,9,64): typecheck error FS1200: The attribute 'ObsoleteAttribute' appears in both the implementation and the signature, but the attribute arguments differ. Only the attribute from the signature will be included in the compiled code.
-neg31.fs(71,12,71,36): typecheck error FS1200: The attribute 'ObsoleteAttribute' appears in both the implementation and the signature, but the attribute arguments differ. Only the attribute from the signature will be included in the compiled code.
+neg31.fs(71,12,71,70): typecheck error FS1200: The attribute 'ObsoleteAttribute' appears in both the implementation and the signature, but the attribute arguments differ. Only the attribute from the signature will be included in the compiled code.
-neg31.fs(107,13,107,41): typecheck error FS1200: The attribute 'CLSCompliantAttribute' appears in both the implementation and the signature, but the attribute arguments differ. Only the attribute from the signature will be included in the compiled code.
+neg31.fs(107,13,107,48): typecheck error FS1200: The attribute 'CLSCompliantAttribute' appears in both the implementation and the signature, but the attribute arguments differ. Only the attribute from the signature will be included in the compiled code.
-neg31.fs(28,6,28,30): typecheck error FS1200: The attribute 'ObsoleteAttribute' appears in both the implementation and the signature, but the attribute arguments differ. Only the attribute from the signature will be included in the compiled code.
+neg31.fs(28,6,28,64): typecheck error FS1200: The attribute 'ObsoleteAttribute' appears in both the implementation and the signature, but the attribute arguments differ. Only the attribute from the signature will be included in the compiled code.
-neg31.fs(93,14,93,42): typecheck error FS1200: The attribute 'CLSCompliantAttribute' appears in both the implementation and the signature, but the attribute arguments differ. Only the attribute from the signature will be included in the compiled code.
+neg31.fs(93,14,93,49): typecheck error FS1200: The attribute 'CLSCompliantAttribute' appears in both the implementation and the signature, but the attribute arguments differ. Only the attribute from the signature will be included in the compiled code.
-neg31.fs(47,6,47,30): typecheck error FS1200: The attribute 'ObsoleteAttribute' appears in both the implementation and the signature, but the attribute arguments differ. Only the attribute from the signature will be included in the compiled code.
+neg31.fs(47,6,47,64): typecheck error FS1200: The attribute 'ObsoleteAttribute' appears in both the implementation and the signature, but the attribute arguments differ. Only the attribute from the signature will be included in the compiled code.
diff --git a/tests/fsharp/typecheck/sigs/neg32.bsl b/tests/fsharp/typecheck/sigs/neg32.bsl
index 6afdd7ae5a7..be532860a7a 100644
--- a/tests/fsharp/typecheck/sigs/neg32.bsl
+++ b/tests/fsharp/typecheck/sigs/neg32.bsl
@@ -1,5 +1,5 @@
-neg32.fs(17,21,17,49): typecheck error FS0842: This attribute is not valid for use on this language element
+neg32.fs(17,11,17,56): typecheck error FS0842: This attribute is not valid for use on this language element
neg32.fs(24,15,24,16): typecheck error FS0043: The member or object constructor 'TryParse' does not take 1 argument(s). An overload was found taking 2 arguments.
diff --git a/tests/fsharp/typecheck/sigs/pos1281.fs b/tests/fsharp/typecheck/sigs/pos1281.fs
new file mode 100644
index 00000000000..f2a73c07c3d
--- /dev/null
+++ b/tests/fsharp/typecheck/sigs/pos1281.fs
@@ -0,0 +1,17 @@
+module Pos1281
+
+type Cond = Foo | Bar | Baz
+let (|SetV|) x _ = x
+
+let c = Cond.Foo
+
+match c with
+| Baz ->
+ printfn "Baz"
+| Foo & SetV "and" kwd
+| Bar & SetV "or" kwd ->
+ printfn "Keyword: %s" kwd
+| Baz -> failwith "wat"
+
+printfn "test completed"
+exit 0
diff --git a/tests/fsharp/typecheck/sigs/pos3294.fs b/tests/fsharp/typecheck/sigs/pos3294.fs
new file mode 100644
index 00000000000..55fc5f2631b
--- /dev/null
+++ b/tests/fsharp/typecheck/sigs/pos3294.fs
@@ -0,0 +1,8 @@
+module Pos40
+
+let f = function
+ | [] -> 0
+ | (_ :: _) & _ -> 0
+
+printfn "test completed"
+exit 0
diff --git a/tests/fsharp/typecheck/sigs/version50/neg20.bsl b/tests/fsharp/typecheck/sigs/version50/neg20.bsl
index b1e3b87ffb5..37e8f71a499 100644
--- a/tests/fsharp/typecheck/sigs/version50/neg20.bsl
+++ b/tests/fsharp/typecheck/sigs/version50/neg20.bsl
@@ -319,7 +319,7 @@ neg20.fs(216,5,216,12): typecheck error FS0842: This attribute is not valid for
neg20.fs(219,5,219,15): typecheck error FS0842: This attribute is not valid for use on this language element
-neg20.fs(222,5,222,24): typecheck error FS0842: This attribute is not valid for use on this language element
+neg20.fs(222,5,222,31): typecheck error FS0842: This attribute is not valid for use on this language element
neg20.fs(225,5,225,22): typecheck error FS0842: This attribute is not valid for use on this language element
@@ -337,9 +337,9 @@ neg20.fs(243,5,243,23): typecheck error FS0842: This attribute is not valid for
neg20.fs(249,9,249,27): typecheck error FS0842: This attribute is not valid for use on this language element
-neg20.fs(255,5,255,21): typecheck error FS0842: This attribute is not valid for use on this language element
+neg20.fs(255,5,255,28): typecheck error FS0842: This attribute is not valid for use on this language element
-neg20.fs(258,5,258,31): typecheck error FS0842: This attribute is not valid for use on this language element
+neg20.fs(258,5,258,38): typecheck error FS0842: This attribute is not valid for use on this language element
neg20.fs(261,5,261,17): typecheck error FS0842: This attribute is not valid for use on this language element
@@ -347,7 +347,7 @@ neg20.fs(265,5,265,24): typecheck error FS0842: This attribute is not valid for
neg20.fs(268,5,268,27): typecheck error FS0842: This attribute is not valid for use on this language element
-neg20.fs(271,5,271,13): typecheck error FS0842: This attribute is not valid for use on this language element
+neg20.fs(271,5,271,15): typecheck error FS0842: This attribute is not valid for use on this language element
neg20.fs(278,14,278,95): typecheck error FS0507: No accessible member or object constructor named 'ProcessStartInfo' takes 0 arguments. Note the call to this member also provides 2 named arguments.
diff --git a/tests/fsharpqa/Source/Conformance/Signatures/SignatureConformance/AttributeMatching01.fs b/tests/fsharpqa/Source/Conformance/Signatures/SignatureConformance/AttributeMatching01.fs
index ceeadc93274..082ea859d45 100644
--- a/tests/fsharpqa/Source/Conformance/Signatures/SignatureConformance/AttributeMatching01.fs
+++ b/tests/fsharpqa/Source/Conformance/Signatures/SignatureConformance/AttributeMatching01.fs
@@ -1,6 +1,6 @@
// #Conformance #SignatureFiles #Attributes #Regression
// Regression for 6446 - verifying spec matches implementation when fs/fsi files attributes differ
-//The attribute 'ObsoleteAttribute' appears in both the implementation and the signature, but the attribute arguments differ\. Only the attribute from the signature will be included in the compiled code\.
+//The attribute 'ObsoleteAttribute' appears in both the implementation and the signature, but the attribute arguments differ\. Only the attribute from the signature will be included in the compiled code\.
module M
diff --git a/tests/fsharpqa/Source/Conformance/Signatures/SignatureConformance/AttributeMatching01.fsi b/tests/fsharpqa/Source/Conformance/Signatures/SignatureConformance/AttributeMatching01.fsi
index b3092d384b2..8f6e9113446 100644
--- a/tests/fsharpqa/Source/Conformance/Signatures/SignatureConformance/AttributeMatching01.fsi
+++ b/tests/fsharpqa/Source/Conformance/Signatures/SignatureConformance/AttributeMatching01.fsi
@@ -1,6 +1,6 @@
// #Conformance #SignatureFiles #Attributes #Regression
// Regression for 6446 - verifying spec matches implementation when fs/fsi files attributes differ
-//The attribute 'ObsoleteAttribute' appears in both the implementation and the signature, but the attribute arguments differ\. Only the attribute from the signature will be included in the compiled code\.
+//The attribute 'ObsoleteAttribute' appears in both the implementation and the signature, but the attribute arguments differ\. Only the attribute from the signature will be included in the compiled code\.
module M
diff --git a/tests/fsharpqa/Source/Misc/E_CompiledName.fs b/tests/fsharpqa/Source/Misc/E_CompiledName.fs
index cdf5e84ae72..437032e0112 100644
--- a/tests/fsharpqa/Source/Misc/E_CompiledName.fs
+++ b/tests/fsharpqa/Source/Misc/E_CompiledName.fs
@@ -1,8 +1,8 @@
// #Regression #Misc
// Regression test for FSHARP1.0:5936
// This test ensures that you can't apply the CompiledName attribute more than once to a property
-//The attribute type 'CompiledNameAttribute' has 'AllowMultiple=false'\. Multiple instances of this attribute cannot be attached to a single language element\.$
-//The attribute type 'CompiledNameAttribute' has 'AllowMultiple=false'\. Multiple instances of this attribute cannot be attached to a single language element\.$
+//The attribute type 'CompiledNameAttribute' has 'AllowMultiple=false'\. Multiple instances of this attribute cannot be attached to a single language element\.$
+//The attribute type 'CompiledNameAttribute' has 'AllowMultiple=false'\. Multiple instances of this attribute cannot be attached to a single language element\.$
module M
type T() =
diff --git a/tests/service/Common.fs b/tests/service/Common.fs
index 7f2a8e56813..e19ed1f1c49 100644
--- a/tests/service/Common.fs
+++ b/tests/service/Common.fs
@@ -232,6 +232,11 @@ let getSingleParenInnerExpr expr =
| SynModuleDecl.Expr(SynExpr.Paren(expr, _, _, _), _) -> expr
| _ -> failwith "Unexpected tree"
+let getLetDeclHeadPattern (moduleDecl: SynModuleDecl) =
+ match moduleDecl with
+ | SynModuleDecl.Let(_, [SynBinding(headPat = pat)], _) -> pat
+ | _ -> failwith "Unexpected tree"
+
let parseSourceCodeAndGetModule (source: string) =
parseSourceCode ("test.fsx", source) |> getSingleModuleLikeDecl
@@ -458,7 +463,7 @@ let coreLibAssemblyName =
"mscorlib"
#endif
-let getRange (e: SynExpr) = e.Range
+let inline getRange (node: ^T) = (^T: (member Range: range) node)
let assertRange
(expectedStartLine: int, expectedStartColumn: int)
diff --git a/tests/service/ParserTests.fs b/tests/service/ParserTests.fs
index b96083b77e7..cc4a9923ab7 100644
--- a/tests/service/ParserTests.fs
+++ b/tests/service/ParserTests.fs
@@ -131,9 +131,7 @@ match () with
match getSingleExprInModule parseResults with
| SynExpr.Match (clauses=[ SynMatchClause (pat=pat) ]) ->
match pat with
- | SynPat.Or
- (SynPat.FromParseError (SynPat.Paren (SynPat.FromParseError (SynPat.Wild _, _), _), _),
- SynPat.Named _, _, _) -> ()
+ | SynPat.Paren(SynPat.Or(SynPat.Tuple(_, [SynPat.Named _; SynPat.Wild _], _), SynPat.Named _, _, _), _) -> ()
| _ -> failwith "Unexpected pattern"
| _ -> failwith "Unexpected tree"
@@ -185,7 +183,7 @@ let f (x,
match getSingleDeclInModule parseResults with
| SynModuleDecl.Let (_, [ SynBinding (headPat = SynPat.LongIdent (argPats = SynArgPats.Pats [ pat ])) ], _) ->
match pat with
- | SynPat.FromParseError (SynPat.Paren (SynPat.FromParseError (SynPat.Wild _, _), _), _) -> ()
+ | SynPat.FromParseError (SynPat.Paren (SynPat.Tuple(_, [SynPat.Named _; SynPat.Wild _], _), _), _) -> ()
| _ -> failwith "Unexpected tree"
| _ -> failwith "Unexpected tree"
@@ -194,7 +192,11 @@ let assertIsBefore (f: _ -> range) (a, b) =
let r2 = f b
Position.posGeq r2.Start r1.End |> shouldEqual true
-let checkExprOrder exprs =
+let inline assertIsEmptyRange node =
+ let range = getRange node
+ Position.posEq range.Start range.End |> shouldEqual true
+
+let inline checkNodeOrder exprs =
exprs
|> List.pairwise
|> List.iter (assertIsBefore getRange)
@@ -220,7 +222,7 @@ let ``Expr - Tuple 01`` () =
| [ SynExpr.Tuple(_, [SynExpr.ArbitraryAfterError _ as e11; SynExpr.ArbitraryAfterError _ as e12], c1, _)
SynExpr.Tuple(_, [SynExpr.ArbitraryAfterError _ as e21; SynExpr.ArbitraryAfterError _ as e22; SynExpr.ArbitraryAfterError _ as e23], c2, _)
SynExpr.Tuple(_, [SynExpr.ArbitraryAfterError _ as e31; SynExpr.ArbitraryAfterError _ as e32; SynExpr.ArbitraryAfterError _ as e33; SynExpr.ArbitraryAfterError _ as e34], c3, _) ] ->
- [ e11; e12; e21; e22; e23; e31; e32; e33; e34 ] |> checkExprOrder
+ [ e11; e12; e21; e22; e23; e31; e32; e33; e34 ] |> checkNodeOrder
[ c1, 1; c2, 2; c3, 3 ] |> checkRangeCountAndOrder
| _ -> failwith "Unexpected tree"
@@ -237,7 +239,7 @@ let ``Expr - Tuple 02`` () =
| [ SynExpr.Tuple(_, [SynExpr.Const _ as e11; SynExpr.ArbitraryAfterError _ as e12], c1, _)
SynExpr.Tuple(_, [SynExpr.ArbitraryAfterError _ as e21; SynExpr.Const _ as e22], c2, _)
SynExpr.Tuple(_, [SynExpr.Const _ as e31; SynExpr.Const _ as e32], c3, _) ] ->
- [ e11; e12; e21; e22; e31; e32 ] |> checkExprOrder
+ [ e11; e12; e21; e22; e31; e32 ] |> checkNodeOrder
[ c1, 1; c2, 1; c3, 1 ] |> checkRangeCountAndOrder
| _ -> failwith "Unexpected tree"
@@ -269,7 +271,7 @@ let ``Expr - Tuple 03`` () =
[ e11; e12; e13; e21; e22; e23; e31; e32; e33
e41; e42; e43; e51; e52; e53; e61; e62; e63
e71; e72; e73 ]
- |> checkExprOrder
+ |> checkNodeOrder
[ c1, 2; c2, 2; c3, 2
c4, 2; c5, 2; c6, 2
@@ -294,9 +296,7 @@ let ``Expr - Tuple 04`` () =
SynExpr.ArbitraryAfterError _ as e6
SynExpr.Const _ as e7
SynExpr.ArbitraryAfterError _ as e8 ], c, _) ] ->
- [ e1; e2; e3; e4; e5; e6; e7; e8 ]
- |> checkExprOrder
-
+ [ e1; e2; e3; e4; e5; e6; e7; e8 ] |> checkNodeOrder
[ c, 7 ] |> checkRangeCountAndOrder
| _ -> failwith "Unexpected tree"
@@ -333,3 +333,138 @@ let x = 1,
shouldEqual expr.Range.StartLine expr.Range.EndLine
shouldEqual range.StartLine range.EndLine
| _ -> failwith "Unexpected tree"
+
+[]
+let ``Pattern - Head - Tuple 01`` () =
+ let parseResults = getParseResults """
+let , = ()
+let ,, = ()
+let ,,, = ()
+"""
+ let pats = getSingleModuleMemberDecls parseResults |> List.map getLetDeclHeadPattern
+ match pats with
+ | [ SynPat.Tuple(_, [SynPat.Wild _ as p11; SynPat.Wild _ as p12], _)
+ SynPat.Tuple(_, [SynPat.Wild _ as p21; SynPat.Wild _ as p22; SynPat.Wild _ as p23], _)
+ SynPat.Tuple(_, [SynPat.Wild _ as p31; SynPat.Wild _ as p32; SynPat.Wild _ as p33; SynPat.Wild _ as p34], _) ] ->
+ [ p11; p12; p21; p22; p23; p31; p32; p33; p34 ] |> checkNodeOrder
+ [ p11; p12; p21; p22; p23; p31; p32; p33; p34 ] |> List.iter assertIsEmptyRange
+
+ | _ -> failwith "Unexpected tree"
+
+[]
+let ``Pattern - Head - Tuple 02`` () =
+ let parseResults = getParseResults """
+let 1, = ()
+let ,1 = ()
+let 1,1 = ()
+"""
+ let pats = getSingleModuleMemberDecls parseResults |> List.map getLetDeclHeadPattern
+ match pats with
+ | [ SynPat.Tuple(_, [SynPat.Const _ as p11; SynPat.Wild _ as p12], _)
+ SynPat.Tuple(_, [SynPat.Wild _ as p21; SynPat.Const _ as p22], _)
+ SynPat.Tuple(_, [SynPat.Const _ as p31; SynPat.Const _ as p32], _) ] ->
+ [ p11; p12; p21; p22; p31; p32 ] |> checkNodeOrder
+ [ p12; p21 ] |> List.iter assertIsEmptyRange
+
+ | _ -> failwith "Unexpected tree"
+
+[]
+let ``Pattern - Head - Tuple 03`` () =
+ let parseResults = getParseResults """
+let 1,, = ()
+let ,1, = ()
+let ,,1 = ()
+
+let 1,1, = ()
+let ,1,1 = ()
+let 1,,1 = ()
+
+let 1,1,1 = ()
+"""
+ let pats = getSingleModuleMemberDecls parseResults |> List.map getLetDeclHeadPattern
+ match pats with
+ | [ SynPat.Tuple(_, [SynPat.Const _ as p11; SynPat.Wild _ as p12; SynPat.Wild _ as p13], _)
+ SynPat.Tuple(_, [SynPat.Wild _ as p21; SynPat.Const _ as p22; SynPat.Wild _ as p23], _)
+ SynPat.Tuple(_, [SynPat.Wild _ as p31; SynPat.Wild _ as p32; SynPat.Const _ as p33], _)
+
+ SynPat.Tuple(_, [SynPat.Const _ as p41; SynPat.Const _ as p42; SynPat.Wild _ as p43], _)
+ SynPat.Tuple(_, [SynPat.Wild _ as p51; SynPat.Const _ as p52; SynPat.Const _ as p53], _)
+ SynPat.Tuple(_, [SynPat.Const _ as p61; SynPat.Wild _ as p62; SynPat.Const _ as p63], _)
+
+ SynPat.Tuple(_, [SynPat.Const _ as p71; SynPat.Const _ as p72; SynPat.Const _ as p73], _) ] ->
+ [ p11; p12; p13; p21; p22; p23; p31; p32; p33
+ p41; p42; p43; p51; p52; p53; p61; p62; p63
+ p71; p72; p73 ] |> checkNodeOrder
+ [ p12; p13; p21; p23; p31; p32; p43; p51; p62 ] |> List.iter assertIsEmptyRange
+
+ | _ -> failwith "Unexpected tree"
+
+let getParenPatInnerPattern pat =
+ match pat with
+ | SynPat.Paren(pat, _) -> pat
+ | _ -> failwith "Unexpected tree"
+
+[]
+let ``Pattern - Paren - Tuple 01`` () =
+ let parseResults = getParseResults """
+let (,) = ()
+let (,,) = ()
+let (,,,) = ()
+"""
+ let pats = getSingleModuleMemberDecls parseResults |> List.map (getLetDeclHeadPattern >> getParenPatInnerPattern)
+ match pats with
+ | [ SynPat.Tuple(_, [SynPat.Wild _ as p11; SynPat.Wild _ as p12], _)
+ SynPat.Tuple(_, [SynPat.Wild _ as p21; SynPat.Wild _ as p22; SynPat.Wild _ as p23], _)
+ SynPat.Tuple(_, [SynPat.Wild _ as p31; SynPat.Wild _ as p32; SynPat.Wild _ as p33; SynPat.Wild _ as p34], _) ] ->
+ [ p11; p12; p21; p22; p23; p31; p32; p33; p34 ] |> checkNodeOrder
+ [ p11; p12; p21; p22; p23; p31; p32; p33; p34 ] |> List.iter assertIsEmptyRange
+
+ | _ -> failwith "Unexpected tree"
+
+[]
+let ``Pattern - Paren - Tuple 02`` () =
+ let parseResults = getParseResults """
+let (1,) = ()
+let (,1) = ()
+let (1,1) = ()
+"""
+ let pats = getSingleModuleMemberDecls parseResults |> List.map (getLetDeclHeadPattern >> getParenPatInnerPattern)
+ match pats with
+ | [ SynPat.Tuple(_, [SynPat.Const _ as p11; SynPat.Wild _ as p12], _)
+ SynPat.Tuple(_, [SynPat.Wild _ as p21; SynPat.Const _ as p22], _)
+ SynPat.Tuple(_, [SynPat.Const _ as p31; SynPat.Const _ as p32], _) ] ->
+ [ p11; p12; p21; p22; p31; p32 ] |> checkNodeOrder
+ [ p12; p21 ] |> List.iter assertIsEmptyRange
+
+ | _ -> failwith "Unexpected tree"
+
+[]
+let ``Pattern - Paren - Tuple 03`` () =
+ let parseResults = getParseResults """
+let (1,,) = ()
+let (,1,) = ()
+let (,,1) = ()
+
+let (1,1,) = ()
+let (,1,1) = ()
+let (1,,1) = ()
+
+let (1,1,1) = ()
+"""
+ let pats = getSingleModuleMemberDecls parseResults |> List.map (getLetDeclHeadPattern >> getParenPatInnerPattern)
+ match pats with
+ | [ SynPat.Tuple(_, [SynPat.Const _ as p11; SynPat.Wild _ as p12; SynPat.Wild _ as p13], _)
+ SynPat.Tuple(_, [SynPat.Wild _ as p21; SynPat.Const _ as p22; SynPat.Wild _ as p23], _)
+ SynPat.Tuple(_, [SynPat.Wild _ as p31; SynPat.Wild _ as p32; SynPat.Const _ as p33], _)
+
+ SynPat.Tuple(_, [SynPat.Const _ as p41; SynPat.Const _ as p42; SynPat.Wild _ as p43], _)
+ SynPat.Tuple(_, [SynPat.Wild _ as p51; SynPat.Const _ as p52; SynPat.Const _ as p53], _)
+ SynPat.Tuple(_, [SynPat.Const _ as p61; SynPat.Wild _ as p62; SynPat.Const _ as p63], _)
+
+ SynPat.Tuple(_, [SynPat.Const _ as p71; SynPat.Const _ as p72; SynPat.Const _ as p73], _) ] ->
+ [ p11; p12; p13; p21; p22; p23; p31; p32; p33
+ p41; p42; p43; p51; p52; p53; p61; p62; p63
+ p71; p72; p73 ] |> checkNodeOrder
+ [ p12; p13; p21; p23; p31; p32; p43; p51; p62 ] |> List.iter assertIsEmptyRange
+
+ | _ -> failwith "Unexpected tree"
diff --git a/tests/service/PatternMatchCompilationTests.fs b/tests/service/PatternMatchCompilationTests.fs
index 4e56b7672e2..49117c04cea 100644
--- a/tests/service/PatternMatchCompilationTests.fs
+++ b/tests/service/PatternMatchCompilationTests.fs
@@ -46,7 +46,7 @@ match () with
assertHasSymbolUsages ["x"; "y"; "CompiledNameAttribute"] checkResults
dumpDiagnostics checkResults |> shouldEqual [
"(3,2--3,25): Attributes are not allowed within patterns"
- "(3,4--3,16): This attribute is not valid for use on this language element"
+ "(3,4--3,23): This attribute is not valid for use on this language element"
]
@@ -81,26 +81,6 @@ match 1, 2 with
]
-[]
-#if !NETCOREAPP
-[]
-#endif
-let ``Union case 01 - Missing field`` () =
- let _, checkResults = getParseAndCheckResults """
-type U =
- | A
- | B of int * int * int
-
-match A with
-| B (x, _) -> let y = x + 1 in ()
-"""
- assertHasSymbolUsages ["x"; "y"] checkResults
- dumpDiagnostics checkResults |> shouldEqual [
- "(7,2--7,10): This union case expects 3 arguments in tupled form"
- "(6,6--6,7): Incomplete pattern matches on this expression. For example, the value 'A' may indicate a case not covered by the pattern(s)."
- ]
-
-
[]
#if !NETCOREAPP
[]
@@ -197,47 +177,6 @@ match A with
"(6,6--6,7): Incomplete pattern matches on this expression. For example, the value 'A' may indicate a case not covered by the pattern(s)."
]
-
-[]
-#if !NETCOREAPP
-[]
-#endif
-let ``Union case 07 - Named args - Name used twice`` () =
- let _, checkResults = getParseAndCheckResults """
-type U =
- | A
- | B of field: int * int
-
-match A with
-| B (field = x; field = z) -> let y = x + z + 1 in ()
-"""
- assertHasSymbolUsages ["x"; "y"; "z"] checkResults
- dumpDiagnostics checkResults |> shouldEqual [
- "(7,16--7,21): Union case/exception field 'field' cannot be used more than once."
- "(6,6--6,7): Incomplete pattern matches on this expression. For example, the value 'A' may indicate a case not covered by the pattern(s)."
- ]
-
-
-[]
-#if !NETCOREAPP
-[]
-#endif
-let ``Union case 08 - Multiple tupled args`` () =
- let _, checkResults = getParseAndCheckResults """
-type U =
- | A
- | B of field: int * int
-
-match A with
-| B x z -> let y = x + z + 1 in ()
-"""
- assertHasSymbolUsages ["x"; "y"; "z"] checkResults
- dumpDiagnostics checkResults |> shouldEqual [
- "(7,2--7,7): This union case expects 2 arguments in tupled form"
- "(6,6--6,7): Incomplete pattern matches on this expression. For example, the value 'A' may indicate a case not covered by the pattern(s)."
- ]
-
-
[]
let ``Union case 09 - Single arg`` () =
let _, checkResults = getParseAndCheckResults """
@@ -249,7 +188,6 @@ match None with
dumpDiagnostics checkResults |> shouldEqual [
]
-
[]
#if !NETCOREAPP
[]
@@ -781,6 +719,7 @@ let z as =
"""
dumpDiagnostics checkResults |> shouldEqual [
"(10,7--10,9): Unexpected keyword 'as' in binding"
+ "(10,5--10,6): Expecting pattern"
"(11,10--11,12): Unexpected keyword 'as' in binding. Expected '=' or other token."
"(12,9--12,11): Unexpected keyword 'as' in binding"
"(13,8--13,10): Unexpected keyword 'as' in binding"
@@ -801,6 +740,7 @@ let z as =
"(6,4--6,10): This runtime coercion or type test from type 'a to int involves an indeterminate type based on information prior to this program point. Runtime type tests are not allowed on some types. Further type annotations are needed."
"(8,29--8,30): This expression was expected to have type 'unit' but here has type 'int'"
"(9,26--9,27): This expression was expected to have type 'unit' but here has type 'int'"
+ "(10,14--10,15): This expression was expected to have type ''a * 'b' but here has type 'int'"
"(15,4--15,5): The pattern discriminator 'r' is not defined."
"(15,4--15,12): Incomplete pattern matches on this expression."
]
@@ -1182,6 +1122,7 @@ let as :? z =
"""
dumpDiagnostics checkResults |> shouldEqual [
"(10,7--10,9): Unexpected keyword 'as' in binding"
+ "(10,5--10,6): Expecting pattern"
"(11,10--11,12): Unexpected keyword 'as' in binding. Expected '=' or other token."
"(12,9--12,11): Unexpected keyword 'as' in binding"
"(13,8--13,10): Unexpected keyword 'as' in binding"
@@ -1209,6 +1150,8 @@ let as :? z =
"(8,25--8,29): The type 'unit' does not have any proper subtypes and cannot be used as the source of a type test or runtime coercion."
"(9,25--9,26): The type 'g' is not defined."
"(9,22--9,26): The type 'unit' does not have any proper subtypes and cannot be used as the source of a type test or runtime coercion."
+ "(10,13--10,14): The type 'i' is not defined."
+ "(10,10--10,14): The type ''a * 'b' does not have any proper subtypes and cannot be used as the source of a type test or runtime coercion."
"(16,4--16,5): The pattern discriminator 't' is not defined."
"(16,14--16,15): The type 'u' is not defined."
"(16,11--16,15): This runtime coercion or type test from type 'a to 'b involves an indeterminate type based on information prior to this program point. Runtime type tests are not allowed on some types. Further type annotations are needed."
diff --git a/tests/service/SyntaxTreeTests/AttributeTests.fs b/tests/service/SyntaxTreeTests/AttributeTests.fs
new file mode 100644
index 00000000000..c31aefae85f
--- /dev/null
+++ b/tests/service/SyntaxTreeTests/AttributeTests.fs
@@ -0,0 +1,50 @@
+module FSharp.Compiler.Service.Tests.SyntaxTreeTests.AttributeTests
+
+open FSharp.Compiler.Service.Tests.Common
+open FSharp.Compiler.Syntax
+open NUnit.Framework
+
+[]
+let ``range of attribute`` () =
+ let ast =
+ """
+[]
+do ()
+"""
+ |> getParseResults
+
+ match ast with
+ | ParsedInput.ImplFile (ParsedImplFileInput(contents = [ SynModuleOrNamespace.SynModuleOrNamespace(decls =
+ [ SynModuleDecl.Attributes(attributes = [ { Attributes = [ { Range = mAttribute } ] } ]) ; SynModuleDecl.Expr _ ] ) ])) ->
+ assertRange (2, 2) (2, 25) mAttribute
+ | _ -> Assert.Fail $"Could not get valid AST, got {ast}"
+
+[]
+let ``range of attribute with path`` () =
+ let ast =
+ """
+[]
+do ()
+"""
+ |> getParseResults
+
+ match ast with
+ | ParsedInput.ImplFile (ParsedImplFileInput(contents = [ SynModuleOrNamespace.SynModuleOrNamespace(decls =
+ [ SynModuleDecl.Attributes(attributes = [ { Attributes = [ { Range = mAttribute } ] } ]) ; SynModuleDecl.Expr _ ] ) ])) ->
+ assertRange (2, 2) (2, 32) mAttribute
+ | _ -> Assert.Fail $"Could not get valid AST, got {ast}"
+
+[]
+let ``range of attribute with target`` () =
+ let ast =
+ """
+[]
+do ()
+"""
+ |> getParseResults
+
+ match ast with
+ | ParsedInput.ImplFile (ParsedImplFileInput(contents = [ SynModuleOrNamespace.SynModuleOrNamespace(decls =
+ [ SynModuleDecl.Attributes(attributes = [ { Attributes = [ { Range = mAttribute } ] } ]) ; SynModuleDecl.Expr _ ] ) ])) ->
+ assertRange (2, 2) (2, 35) mAttribute
+ | _ -> Assert.Fail $"Could not get valid AST, got {ast}"
diff --git a/tests/service/SyntaxTreeTests/ExternTests.fs b/tests/service/SyntaxTreeTests/ExternTests.fs
new file mode 100644
index 00000000000..0599307d994
--- /dev/null
+++ b/tests/service/SyntaxTreeTests/ExternTests.fs
@@ -0,0 +1,21 @@
+module FSharp.Compiler.Service.Tests.SyntaxTreeTests.ExternTests
+
+open FSharp.Compiler.Service.Tests.Common
+open FSharp.Compiler.Syntax
+open FSharp.Compiler.SyntaxTrivia
+open NUnit.Framework
+
+[]
+let ``extern keyword is present in trivia`` () =
+ let parseResults = getParseResults "extern void GetProcessHeap()"
+
+ match parseResults with
+ | ParsedInput.ImplFile(ParsedImplFileInput(contents = [
+ SynModuleOrNamespace.SynModuleOrNamespace(decls = [
+ SynModuleDecl.Let(bindings = [
+ SynBinding(trivia = { ExternKeyword = Some mExtern })
+ ])
+ ])
+ ])) ->
+ assertRange (1, 0) (1, 6) mExtern
+ | _ -> Assert.Fail $"Could not get valid AST, got {parseResults}"
diff --git a/tests/service/SyntaxTreeTests/MemberTests.fs b/tests/service/SyntaxTreeTests/MemberTests.fs
new file mode 100644
index 00000000000..084af4bff85
--- /dev/null
+++ b/tests/service/SyntaxTreeTests/MemberTests.fs
@@ -0,0 +1,225 @@
+module FSharp.Compiler.Service.Tests.SyntaxTreeTests.MemberTests
+
+open FSharp.Compiler.Service.Tests.Common
+open FSharp.Compiler.Syntax
+open FSharp.Compiler.SyntaxTrivia
+open NUnit.Framework
+
+[]
+let ``SynTypeDefn with AutoProperty contains the range of the equals sign`` () =
+ let parseResults =
+ getParseResults
+ """
+/// mutable class with auto-properties
+type Person(name : string, age : int) =
+ /// Full name
+ member val Name = name with get, set
+"""
+
+ match parseResults with
+ | ParsedInput.ImplFile (ParsedImplFileInput (contents = [ SynModuleOrNamespace.SynModuleOrNamespace(decls = [
+ SynModuleDecl.Types(
+ typeDefns = [ SynTypeDefn(typeRepr = SynTypeDefnRepr.ObjectModel(members = [_ ; SynMemberDefn.AutoProperty(equalsRange = mEquals)])) ]
+ )
+ ]) ])) ->
+ assertRange (5, 20) (5, 21) mEquals
+ | _ -> Assert.Fail "Could not get valid AST"
+
+[]
+let ``SynTypeDefn with AutoProperty contains the range of the with keyword`` () =
+ let parseResults =
+ getParseResults
+ """
+type Foo() =
+ member val AutoProperty = autoProp with get, set
+ member val AutoProperty2 = autoProp
+"""
+
+ match parseResults with
+ | ParsedInput.ImplFile (ParsedImplFileInput (contents = [ SynModuleOrNamespace.SynModuleOrNamespace(decls = [
+ SynModuleDecl.Types(
+ typeDefns = [ SynTypeDefn(typeRepr = SynTypeDefnRepr.ObjectModel(members = [_
+ SynMemberDefn.AutoProperty(withKeyword=Some mWith)
+ SynMemberDefn.AutoProperty(withKeyword=None)])) ]
+ )
+ ]) ])) ->
+ assertRange (3, 39) (3, 43) mWith
+ | _ -> Assert.Fail "Could not get valid AST"
+
+[]
+let ``SynTypeDefn with AbstractSlot contains the range of the with keyword`` () =
+ let parseResults =
+ getParseResults
+ """
+type Foo() =
+ abstract member Bar : int with get,set
+"""
+
+ match parseResults with
+ | ParsedInput.ImplFile (ParsedImplFileInput (contents = [ SynModuleOrNamespace.SynModuleOrNamespace(decls = [
+ SynModuleDecl.Types(
+ typeDefns = [ SynTypeDefn(typeRepr = SynTypeDefnRepr.ObjectModel(members = [_
+ SynMemberDefn.AbstractSlot(slotSig=SynValSig(trivia = { WithKeyword = Some mWith }))])) ]
+ )
+ ]) ])) ->
+ assertRange (3, 30) (3, 34) mWith
+ | _ -> Assert.Fail "Could not get valid AST"
+
+[]
+let ``read-only property in SynMemberDefn.Member contains the range of the with keyword`` () =
+ let parseResults =
+ getParseResults
+ """
+type Foo() =
+ // A read-only property.
+ member this.MyReadProperty with get () = myInternalValue
+"""
+
+ match parseResults with
+ | ParsedInput.ImplFile (ParsedImplFileInput (contents = [ SynModuleOrNamespace.SynModuleOrNamespace(decls = [
+ SynModuleDecl.Types(
+ typeDefns = [ SynTypeDefn(typeRepr =
+ SynTypeDefnRepr.ObjectModel(members=[
+ _
+ SynMemberDefn.GetSetMember(Some(SynBinding _), None, _, { WithKeyword = mWith }) ])
+ ) ])
+ ]) ])) ->
+ assertRange (4, 31) (4, 35) mWith
+ | _ -> Assert.Fail "Could not get valid AST"
+
+[]
+let ``write-only property in SynMemberDefn.Member contains the range of the with keyword`` () =
+ let parseResults =
+ getParseResults
+ """
+type Foo() =
+ // A write-only property.
+ member this.MyWriteOnlyProperty with set (value) = myInternalValue <- value
+"""
+
+ match parseResults with
+ | ParsedInput.ImplFile (ParsedImplFileInput (contents = [ SynModuleOrNamespace.SynModuleOrNamespace(decls = [
+ SynModuleDecl.Types(
+ typeDefns = [ SynTypeDefn(typeRepr =
+ SynTypeDefnRepr.ObjectModel(members=[
+ _
+ SynMemberDefn.GetSetMember(None, Some(SynBinding _), _, { WithKeyword = mWith }) ])
+ ) ])
+ ]) ])) ->
+ assertRange (4, 36) (4, 40) mWith
+ | _ -> Assert.Fail "Could not get valid AST"
+
+[]
+let ``read/write property in SynMemberDefn.Member contains the range of the with keyword`` () =
+ let parseResults =
+ getParseResults
+ """
+type Foo() =
+ // A read-write property.
+ member this.MyReadWriteProperty
+ with get () = myInternalValue
+ and set (value) = myInternalValue <- value
+"""
+
+ match parseResults with
+ | ParsedInput.ImplFile (ParsedImplFileInput (contents = [ SynModuleOrNamespace.SynModuleOrNamespace(decls = [
+ SynModuleDecl.Types(
+ typeDefns = [ SynTypeDefn(typeRepr =
+ SynTypeDefnRepr.ObjectModel(members=[
+ _
+ SynMemberDefn.GetSetMember(Some _, Some _, _, { WithKeyword = mWith; AndKeyword = Some mAnd }) ])
+ ) ])
+ ]) ])) ->
+ assertRange (5, 8) (5, 12) mWith
+ assertRange (6, 8) (6, 11) mAnd
+ | _ -> Assert.Fail "Could not get valid AST"
+
+[]
+let ``SynTypeDefn with static member with get/set`` () =
+ let parseResults =
+ getParseResults
+ """
+type Foo =
+ static member ReadWrite2
+ with set x = lastUsed <- ("ReadWrite2", x)
+ and get () = lastUsed <- ("ReadWrite2", 0); 4
+"""
+
+ match parseResults with
+ | ParsedInput.ImplFile (ParsedImplFileInput (contents = [ SynModuleOrNamespace.SynModuleOrNamespace(decls = [
+ SynModuleDecl.Types(
+ typeDefns = [ SynTypeDefn(typeRepr = SynTypeDefnRepr.ObjectModel(members = [
+ SynMemberDefn.GetSetMember(Some _, Some _, m, { WithKeyword = mWith
+ GetKeyword = Some mGet
+ AndKeyword = Some mAnd
+ SetKeyword = Some mSet })
+ ])) ]
+ )
+ ]) ])) ->
+ assertRange (4, 8) (4, 12) mWith
+ assertRange (4, 13) (4, 16) mSet
+ assertRange (5, 8) (5, 11) mAnd
+ assertRange (5, 13) (5, 16) mGet
+ assertRange (3, 4) (5, 54) m
+ | _ -> Assert.Fail "Could not get valid AST"
+
+[]
+let ``SynTypeDefn with member with set/get`` () =
+ let parseResults =
+ getParseResults
+ """
+type A() =
+ member this.Z with set (_:int):unit = () and get():int = 1
+"""
+
+ match parseResults with
+ | ParsedInput.ImplFile (ParsedImplFileInput (contents = [ SynModuleOrNamespace.SynModuleOrNamespace(decls = [
+ SynModuleDecl.Types(
+ typeDefns = [ SynTypeDefn(typeRepr = SynTypeDefnRepr.ObjectModel(members = [
+ SynMemberDefn.ImplicitCtor _
+ SynMemberDefn.GetSetMember(Some (SynBinding(headPat = SynPat.LongIdent(extraId = Some getIdent))),
+ Some (SynBinding(headPat = SynPat.LongIdent(extraId = Some setIdent))),
+ m,
+ { WithKeyword = mWith
+ GetKeyword = Some mGet
+ AndKeyword = Some mAnd
+ SetKeyword = Some mSet })
+ ])) ]
+ )
+ ]) ])) ->
+ Assert.AreEqual("get", getIdent.idText)
+ Assert.AreEqual("set", setIdent.idText)
+ assertRange (3, 18) (3, 22) mWith
+ assertRange (3, 23) (3, 26) mSet
+ assertRange (3, 23) (3, 26) setIdent.idRange
+ assertRange (3, 45) (3, 48) mAnd
+ assertRange (3, 49) (3, 52) mGet
+ assertRange (3, 49) (3, 52) getIdent.idRange
+ assertRange (3, 4) (3, 62) m
+ | _ -> Assert.Fail "Could not get valid AST"
+
+[]
+let ``SynTypeDefn with member with get has xml comment`` () =
+ let parseResults =
+ getParseResults
+ """
+type A =
+ /// B
+ member x.B with get() = 5
+"""
+
+ match parseResults with
+ | ParsedInput.ImplFile (ParsedImplFileInput (contents = [ SynModuleOrNamespace.SynModuleOrNamespace(decls = [
+ SynModuleDecl.Types(
+ typeDefns = [ SynTypeDefn(typeRepr = SynTypeDefnRepr.ObjectModel(members = [
+ SynMemberDefn.GetSetMember(Some (SynBinding(xmlDoc = preXmlDoc)),
+ None,
+ _,
+ _)
+ ])) ]
+ )
+ ]) ])) ->
+ Assert.False preXmlDoc.IsEmpty
+ let comment = preXmlDoc.ToXmlDoc(false, None).GetXmlText()
+ Assert.False (System.String.IsNullOrWhiteSpace(comment))
+ | _ -> Assert.Fail "Could not get valid AST"
diff --git a/tests/service/SyntaxTreeTests/PatternTests.fs b/tests/service/SyntaxTreeTests/PatternTests.fs
index 61a511dc88a..c03325e6077 100644
--- a/tests/service/SyntaxTreeTests/PatternTests.fs
+++ b/tests/service/SyntaxTreeTests/PatternTests.fs
@@ -73,10 +73,10 @@ let (head::tail) = [ 1;2;4]
match parseResults with
| ParsedInput.ImplFile (ParsedImplFileInput (contents = [ SynModuleOrNamespace.SynModuleOrNamespace(decls = [
SynModuleDecl.Let(
- bindings = [ SynBinding(headPat = SynPat.Paren(SynPat.LongIdent(longDotId = SynLongIdent([ opColonColonIdent ], _, [ Some (IdentTrivia.OriginalNotation "::") ])), _)) ]
+ bindings = [ SynBinding(headPat = SynPat.Paren(pat = SynPat.ListCons(trivia = trivia))) ]
)
]) ])) ->
- Assert.AreEqual("op_ColonColon", opColonColonIdent.idText)
+ assertRange (2,9) (2,11) trivia.ColonColonRange
| _ -> Assert.Fail $"Could not get valid AST, got {parseResults}"
[]
@@ -92,9 +92,49 @@ match x with
| ParsedInput.ImplFile (ParsedImplFileInput (contents = [ SynModuleOrNamespace.SynModuleOrNamespace(decls = [
SynModuleDecl.Expr(
expr = SynExpr.Match(clauses = [
- SynMatchClause(pat = SynPat.LongIdent(longDotId = SynLongIdent([ opColonColonIdent ], _, [ Some (IdentTrivia.OriginalNotation "::") ])))
+ SynMatchClause(pat = SynPat.ListCons(trivia = trivia))
])
)
]) ])) ->
- Assert.AreEqual("op_ColonColon", opColonColonIdent.idText)
- | _ -> Assert.Fail $"Could not get valid AST, got {parseResults}"
\ No newline at end of file
+ assertRange (3, 9) (3, 11) trivia.ColonColonRange
+ | _ -> Assert.Fail $"Could not get valid AST, got {parseResults}"
+
+[]
+let ``Parentheses of SynArgPats.NamePatPairs`` () =
+ let parseResults =
+ getParseResults
+ """
+match data with
+| OnePartData( // foo
+ part1 = p1
+ (* bar *) ) -> p1
+| _ -> failwith "todo"
+"""
+
+ match parseResults with
+ | ParsedInput.ImplFile (ParsedImplFileInput (contents = [ SynModuleOrNamespace.SynModuleOrNamespace(decls = [
+ SynModuleDecl.Expr(
+ expr = SynExpr.Match(clauses = [
+ SynMatchClause(pat = SynPat.LongIdent(argPats = SynArgPats.NamePatPairs(trivia = trivia)))
+ _
+ ])
+ )
+ ]) ])) ->
+ assertRange (3, 13) (5, 13) trivia.ParenRange
+ | _ -> Assert.Fail $"Could not get valid AST, got {parseResults}"
+
+[]
+let ``:: in head pattern`` () =
+ let parseResults =
+ getParseResults
+ """
+let 1 :: _ = [ 4; 5; 6 ]
+"""
+
+ match parseResults with
+ | ParsedInput.ImplFile(ParsedImplFileInput(contents = [ SynModuleOrNamespace(decls = [
+ SynModuleDecl.Let(bindings = [ SynBinding(headPat =
+ SynPat.ListCons(trivia = trivia)) ])
+ ]) ])) ->
+ assertRange (2,6) (2, 8) trivia.ColonColonRange
+ | _ -> Assert.Fail $"Could not get valid AST, got {parseResults}"
diff --git a/tests/service/SyntaxTreeTests/TypeTests.fs b/tests/service/SyntaxTreeTests/TypeTests.fs
index 874c1f41dac..c006a7cd529 100644
--- a/tests/service/SyntaxTreeTests/TypeTests.fs
+++ b/tests/service/SyntaxTreeTests/TypeTests.fs
@@ -169,26 +169,6 @@ type Shape =
assertRange (2, 11) (2, 12) mEquals
| _ -> Assert.Fail "Could not get valid AST"
-[]
-let ``SynTypeDefn with AutoProperty contains the range of the equals sign`` () =
- let parseResults =
- getParseResults
- """
-/// mutable class with auto-properties
-type Person(name : string, age : int) =
- /// Full name
- member val Name = name with get, set
-"""
-
- match parseResults with
- | ParsedInput.ImplFile (ParsedImplFileInput (contents = [ SynModuleOrNamespace.SynModuleOrNamespace(decls = [
- SynModuleDecl.Types(
- typeDefns = [ SynTypeDefn(typeRepr = SynTypeDefnRepr.ObjectModel(members = [_ ; SynMemberDefn.AutoProperty(equalsRange = mEquals)])) ]
- )
- ]) ])) ->
- assertRange (5, 20) (5, 21) mEquals
- | _ -> Assert.Fail "Could not get valid AST"
-
[]
let ``SynTypeDefn with Record contains the range of the with keyword`` () =
let parseResults =
@@ -250,115 +230,6 @@ type Foo() =
assertRange (3, 18) (3, 22) mWithKeyword
| _ -> Assert.Fail "Could not get valid AST"
-[]
-let ``SynTypeDefn with AutoProperty contains the range of the with keyword`` () =
- let parseResults =
- getParseResults
- """
-type Foo() =
- member val AutoProperty = autoProp with get, set
- member val AutoProperty2 = autoProp
-"""
-
- match parseResults with
- | ParsedInput.ImplFile (ParsedImplFileInput (contents = [ SynModuleOrNamespace.SynModuleOrNamespace(decls = [
- SynModuleDecl.Types(
- typeDefns = [ SynTypeDefn(typeRepr = SynTypeDefnRepr.ObjectModel(members = [_
- SynMemberDefn.AutoProperty(withKeyword=Some mWith)
- SynMemberDefn.AutoProperty(withKeyword=None)])) ]
- )
- ]) ])) ->
- assertRange (3, 39) (3, 43) mWith
- | _ -> Assert.Fail "Could not get valid AST"
-
-[]
-let ``SynTypeDefn with AbstractSlot contains the range of the with keyword`` () =
- let parseResults =
- getParseResults
- """
-type Foo() =
- abstract member Bar : int with get,set
-"""
-
- match parseResults with
- | ParsedInput.ImplFile (ParsedImplFileInput (contents = [ SynModuleOrNamespace.SynModuleOrNamespace(decls = [
- SynModuleDecl.Types(
- typeDefns = [ SynTypeDefn(typeRepr = SynTypeDefnRepr.ObjectModel(members = [_
- SynMemberDefn.AbstractSlot(slotSig=SynValSig(trivia = { WithKeyword = Some mWith }))])) ]
- )
- ]) ])) ->
- assertRange (3, 30) (3, 34) mWith
- | _ -> Assert.Fail "Could not get valid AST"
-
-[]
-let ``read-only property in SynMemberDefn.Member contains the range of the with keyword`` () =
- let parseResults =
- getParseResults
- """
-type Foo() =
- // A read-only property.
- member this.MyReadProperty with get () = myInternalValue
-"""
-
- match parseResults with
- | ParsedInput.ImplFile (ParsedImplFileInput (contents = [ SynModuleOrNamespace.SynModuleOrNamespace(decls = [
- SynModuleDecl.Types(
- typeDefns = [ SynTypeDefn(typeRepr =
- SynTypeDefnRepr.ObjectModel(members=[
- _
- SynMemberDefn.GetSetMember(Some(SynBinding _), None, _, { WithKeyword = mWith }) ])
- ) ])
- ]) ])) ->
- assertRange (4, 31) (4, 35) mWith
- | _ -> Assert.Fail "Could not get valid AST"
-
-[]
-let ``write-only property in SynMemberDefn.Member contains the range of the with keyword`` () =
- let parseResults =
- getParseResults
- """
-type Foo() =
- // A write-only property.
- member this.MyWriteOnlyProperty with set (value) = myInternalValue <- value
-"""
-
- match parseResults with
- | ParsedInput.ImplFile (ParsedImplFileInput (contents = [ SynModuleOrNamespace.SynModuleOrNamespace(decls = [
- SynModuleDecl.Types(
- typeDefns = [ SynTypeDefn(typeRepr =
- SynTypeDefnRepr.ObjectModel(members=[
- _
- SynMemberDefn.GetSetMember(None, Some(SynBinding _), _, { WithKeyword = mWith }) ])
- ) ])
- ]) ])) ->
- assertRange (4, 36) (4, 40) mWith
- | _ -> Assert.Fail "Could not get valid AST"
-
-[]
-let ``read/write property in SynMemberDefn.Member contains the range of the with keyword`` () =
- let parseResults =
- getParseResults
- """
-type Foo() =
- // A read-write property.
- member this.MyReadWriteProperty
- with get () = myInternalValue
- and set (value) = myInternalValue <- value
-"""
-
- match parseResults with
- | ParsedInput.ImplFile (ParsedImplFileInput (contents = [ SynModuleOrNamespace.SynModuleOrNamespace(decls = [
- SynModuleDecl.Types(
- typeDefns = [ SynTypeDefn(typeRepr =
- SynTypeDefnRepr.ObjectModel(members=[
- _
- SynMemberDefn.GetSetMember(Some _, Some _, _, { WithKeyword = mWith; AndKeyword = Some mAnd }) ])
- ) ])
- ]) ])) ->
- assertRange (5, 8) (5, 12) mWith
- assertRange (6, 8) (6, 11) mAnd
- | _ -> Assert.Fail "Could not get valid AST"
-
[]
let ``SynTypeDefn with XmlDoc contains the range of the type keyword`` () =
let parseResults =
@@ -399,70 +270,6 @@ type A = B
assertRange (4, 0) (4, 4) mType
| _ -> Assert.Fail "Could not get valid AST"
-[]
-let ``SynTypeDefn with static member with get/set`` () =
- let parseResults =
- getParseResults
- """
-type Foo =
- static member ReadWrite2
- with set x = lastUsed <- ("ReadWrite2", x)
- and get () = lastUsed <- ("ReadWrite2", 0); 4
-"""
-
- match parseResults with
- | ParsedInput.ImplFile (ParsedImplFileInput (contents = [ SynModuleOrNamespace.SynModuleOrNamespace(decls = [
- SynModuleDecl.Types(
- typeDefns = [ SynTypeDefn(typeRepr = SynTypeDefnRepr.ObjectModel(members = [
- SynMemberDefn.GetSetMember(Some _, Some _, m, { WithKeyword = mWith
- GetKeyword = Some mGet
- AndKeyword = Some mAnd
- SetKeyword = Some mSet })
- ])) ]
- )
- ]) ])) ->
- assertRange (4, 8) (4, 12) mWith
- assertRange (4, 13) (4, 16) mSet
- assertRange (5, 8) (5, 11) mAnd
- assertRange (5, 13) (5, 16) mGet
- assertRange (3, 4) (5, 54) m
- | _ -> Assert.Fail "Could not get valid AST"
-
-[]
-let ``SynTypeDefn with member with set/get`` () =
- let parseResults =
- getParseResults
- """
-type A() =
- member this.Z with set (_:int):unit = () and get():int = 1
-"""
-
- match parseResults with
- | ParsedInput.ImplFile (ParsedImplFileInput (contents = [ SynModuleOrNamespace.SynModuleOrNamespace(decls = [
- SynModuleDecl.Types(
- typeDefns = [ SynTypeDefn(typeRepr = SynTypeDefnRepr.ObjectModel(members = [
- SynMemberDefn.ImplicitCtor _
- SynMemberDefn.GetSetMember(Some (SynBinding(headPat = SynPat.LongIdent(extraId = Some getIdent))),
- Some (SynBinding(headPat = SynPat.LongIdent(extraId = Some setIdent))),
- m,
- { WithKeyword = mWith
- GetKeyword = Some mGet
- AndKeyword = Some mAnd
- SetKeyword = Some mSet })
- ])) ]
- )
- ]) ])) ->
- Assert.AreEqual("get", getIdent.idText)
- Assert.AreEqual("set", setIdent.idText)
- assertRange (3, 18) (3, 22) mWith
- assertRange (3, 23) (3, 26) mSet
- assertRange (3, 23) (3, 26) setIdent.idRange
- assertRange (3, 45) (3, 48) mAnd
- assertRange (3, 49) (3, 52) mGet
- assertRange (3, 49) (3, 52) getIdent.idRange
- assertRange (3, 4) (3, 62) m
- | _ -> Assert.Fail "Could not get valid AST"
-
[]
let ``SynType.Fun has range of arrow`` () =
let parseResults =
@@ -502,7 +309,7 @@ let _: struct (int * int) = ()
])
) ->
assertRange (2, 7) (2, 25) mTuple
-
+
| _ -> Assert.Fail $"Could not get valid AST, got {parseResults}"
[]
@@ -522,7 +329,7 @@ let _: struct (int * int = ()
])
) ->
assertRange (2, 7) (2, 24) mTuple
-
+
| _ -> Assert.Fail $"Could not get valid AST, got {parseResults}"
[]
@@ -593,4 +400,4 @@ type X =
])) ->
Assert.AreEqual("a", a.idText)
assertRange (3, 23) (3, 41) m
- | _ -> Assert.Fail $"Could not get valid AST, got {parseResults}"
\ No newline at end of file
+ | _ -> Assert.Fail $"Could not get valid AST, got {parseResults}"
diff --git a/vsintegration/src/FSharp.Editor/CodeLens/CodeLensGeneralTagger.fs b/vsintegration/src/FSharp.Editor/CodeLens/CodeLensGeneralTagger.fs
deleted file mode 100644
index fbc54c1e5fc..00000000000
--- a/vsintegration/src/FSharp.Editor/CodeLens/CodeLensGeneralTagger.fs
+++ /dev/null
@@ -1,191 +0,0 @@
-// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information.
-
-namespace rec Microsoft.VisualStudio.FSharp.Editor
-
-open System
-open System.Windows.Controls
-open Microsoft.VisualStudio.Text
-open Microsoft.VisualStudio.Text.Editor
-open Microsoft.VisualStudio.Text.Formatting
-open System.Windows
-open Microsoft.VisualStudio.Text.Tagging
-
-open Microsoft.VisualStudio.FSharp.Editor.Logging
-
-type CodeLensGeneralTag(width, topSpace, baseline, textHeight, bottomSpace, affinity, tag:obj, providerTag:obj) =
- inherit SpaceNegotiatingAdornmentTag(width, topSpace, baseline, textHeight, bottomSpace, affinity, tag, providerTag)
-
-/// Class which provides support for general code lens
-/// Use the methods AddCodeLens and RemoveCodeLens
-type CodeLensGeneralTagger (view, buffer) as self =
- inherit CodeLensDisplayService(view, buffer, "CodeLens")
-
- /// The tags changed event to notify if the data for the tags has changed.
- let tagsChangedEvent = new Event,SnapshotSpanEventArgs>()
-
- /// Layouts all stack panels on the line
- override self.LayoutUIElementOnLine (view:IWpfTextView) (line:ITextViewLine) (ui:Grid) =
- let left, top =
- match self.UiElementNeighbour.TryGetValue ui with
- | true, parent ->
- let left = Canvas.GetLeft parent
- let top = Canvas.GetTop parent
- let width = parent.ActualWidth
-#if DEBUG
- logInfof "Width of parent: %.4f" width
-#endif
- left + width, top
- | _ ->
- try
- // Get the real offset so that the code lens are placed respectively to their content
- let offset =
- [0..line.Length - 1] |> Seq.tryFind (fun i -> not (Char.IsWhiteSpace (line.Start.Add(i).GetChar())))
- |> Option.defaultValue 0
-
- let realStart = line.Start.Add(offset)
- let g = view.TextViewLines.GetCharacterBounds(realStart)
- // WORKAROUND VS BUG, left cannot be zero if the offset is creater than zero!
- // Calling the method twice fixes this bug and ensures that all values are correct.
- // Okay not really :( Must be replaced later with an own calculation depending on editor font settings!
- if 7 * offset > int g.Left then
-#if DEBUG
- logErrorf "Incorrect return from geometry measure"
-#endif
- Canvas.GetLeft ui, g.Top
- else
- g.Left, g.Top
- with e ->
-#if DEBUG
- logExceptionWithContext (e, "Error in layout ui element on line")
-#else
- ignore e
-#endif
- Canvas.GetLeft ui, Canvas.GetTop ui
- Canvas.SetLeft(ui, left)
- Canvas.SetTop(ui, top)
-
- override self.AsyncCustomLayoutOperation _ _ =
- asyncMaybe {
- // Suspend 16 ms, instantly applying the layout to the adornment elements isn't needed
- // and would consume too much performance
- do! Async.Sleep(16) |> liftAsync // Skip at least one frames
- do! Async.SwitchToContext self.UiContext |> liftAsync
- let layer = self.CodeLensLayer
-
- do! Async.Sleep(495) |> liftAsync
-
- // WORKAROUND FOR VS BUG
- // The layout changed event may not provide us all real changed lines so
- // we take care of this on our own.
- let visibleSpan =
- let first, last =
- view.TextViewLines.FirstVisibleLine,
- view.TextViewLines.LastVisibleLine
- SnapshotSpan(first.Start, last.End)
- let customVisibleLines = view.TextViewLines.GetTextViewLinesIntersectingSpan visibleSpan
- let isLineVisible (line:ITextViewLine) = line.IsValid
- let linesToProcess = customVisibleLines |> Seq.filter isLineVisible
-
- for line in linesToProcess do
- try
- match line.GetAdornmentTags self |> Seq.tryHead with
- | Some (:? seq as stackPanels) ->
- for stackPanel in stackPanels do
- if stackPanel |> self.AddedAdornments.Contains |> not then
- layer.AddAdornment(AdornmentPositioningBehavior.OwnerControlled, Nullable(),
- self, stackPanel, AdornmentRemovedCallback(fun _ _ -> ())) |> ignore
- self.AddedAdornments.Add stackPanel |> ignore
- | _ -> ()
- with e ->
-#if DEBUG
- logExceptionWithContext (e, "LayoutChanged, processing new visible lines")
-#else
- ignore e
-#endif
- } |> Async.Ignore
-
- override self.AddUiElementToCodeLens (trackingSpan:ITrackingSpan, uiElement:UIElement)=
- base.AddUiElementToCodeLens (trackingSpan, uiElement) // We do the same as the base call execpt that we need to notify that the tag needs to be refreshed.
- tagsChangedEvent.Trigger(self, SnapshotSpanEventArgs(trackingSpan.GetSpan(buffer.CurrentSnapshot)))
-
- override self.RemoveUiElementFromCodeLens (trackingSpan:ITrackingSpan, uiElement:UIElement) =
- base.RemoveUiElementFromCodeLens (trackingSpan, uiElement)
- tagsChangedEvent.Trigger(self, SnapshotSpanEventArgs(trackingSpan.GetSpan(buffer.CurrentSnapshot))) // Need to refresh the tag.
-
- interface ITagger with
- []
- override _.TagsChanged = tagsChangedEvent.Publish
-
- /// Returns the tags which reserve the correct space for adornments
- /// Notice, it's asumed that the data in the collection is valid.
- override _.GetTags spans =
- try
- seq {
- for span in spans do
- let snapshot = span.Snapshot
- let lineNumber =
- try
- snapshot.GetLineNumberFromPosition(span.Start.Position)
- with e ->
-#if DEBUG
- logExceptionWithContext (e, "line number tagging")
-#else
- ignore e
-#endif
- 0
- if self.TrackingSpans.ContainsKey(lineNumber) && self.TrackingSpans.[lineNumber] |> Seq.isEmpty |> not then
-
- let tagSpan = snapshot.GetLineFromLineNumber(lineNumber).Extent
- let stackPanels =
- self.TrackingSpans.[lineNumber]
- |> Seq.map (fun trackingSpan ->
- let success, res = self.UiElements.TryGetValue trackingSpan
- if success then res else null
- )
- |> Seq.filter (isNull >> not)
- let span =
- try
- tagSpan.TranslateTo(span.Snapshot, SpanTrackingMode.EdgeExclusive)
- with e ->
-#if DEBUG
- logExceptionWithContext (e, "tag span translation")
-#else
- ignore e
-#endif
- tagSpan
- let sizes =
- try
- stackPanels |> Seq.map (fun ui ->
- ui.Measure(Size(10000., 10000.))
- ui.DesiredSize )
- with e ->
-#if DEBUG
- logExceptionWithContext (e, "internal tagging")
-#else
- ignore e
-#endif
- Seq.empty
- let height =
- try
- sizes
- |> Seq.map (fun size -> size.Height)
- |> Seq.sortDescending
- |> Seq.tryHead
- |> Option.defaultValue 0.
- with e ->
-#if DEBUG
- logExceptionWithContext (e, "height tagging")
-#else
- ignore e
-#endif
- 0.0
-
- yield TagSpan(span, CodeLensGeneralTag(0., height, 0., 0., 0., PositionAffinity.Predecessor, stackPanels, self)) :> ITagSpan
- }
- with e ->
-#if DEBUG
- logErrorf "Error in code lens get tags %A" e
-#else
- ignore e
-#endif
- Seq.empty
\ No newline at end of file
diff --git a/vsintegration/src/FSharp.Editor/CodeLens/CodeLensProvider.fs b/vsintegration/src/FSharp.Editor/CodeLens/CodeLensProvider.fs
index 8d3be2fcf35..abfa68e08b1 100644
--- a/vsintegration/src/FSharp.Editor/CodeLens/CodeLensProvider.fs
+++ b/vsintegration/src/FSharp.Editor/CodeLens/CodeLensProvider.fs
@@ -15,7 +15,6 @@ open Microsoft.CodeAnalysis.ExternalAccess.FSharp.Editor.Shared.Utilities
[)>]
[)>]
-[)>]
[]
[]
type internal CodeLensProvider
@@ -28,75 +27,37 @@ type internal CodeLensProvider
settings: EditorOptions
) =
- let lineLensProvider = ResizeArray()
- let taggers = ResizeArray()
+ let tryGetTextDocument (buffer: ITextBuffer) (factory: ITextDocumentFactoryService) =
+ match factory.TryGetTextDocument buffer with
+ | true, document -> Some document
+ | _ -> None
+
+ let lineLensProviders = ResizeArray()
let componentModel = Package.GetGlobalService(typeof) :?> ComponentModelHost.IComponentModel
let workspace = componentModel.GetService()
- /// Returns an provider for the textView if already one has been created. Else create one.
- let addCodeLensProviderOnce wpfView buffer =
- let res = taggers |> Seq.tryFind(fun (view, _) -> view = wpfView)
- match res with
- | Some (_, (tagger, _)) -> tagger
- | None ->
- let documentId =
- lazy (
- match textDocumentFactory.TryGetTextDocument(buffer) with
- | true, textDocument ->
- Seq.tryHead (workspace.CurrentSolution.GetDocumentIdsWithFilePath(textDocument.FilePath))
- | _ -> None
- |> Option.get
- )
-
- let tagger = CodeLensGeneralTagger(wpfView, buffer)
- let service = FSharpCodeLensService(serviceProvider, workspace, documentId, buffer, metadataAsSource, componentModel.GetService(), typeMap, tagger, settings)
- let provider = (wpfView, (tagger, service))
- wpfView.Closed.Add (fun _ -> taggers.Remove provider |> ignore)
- taggers.Add((wpfView, (tagger, service)))
- tagger
-
- /// Returns an provider for the textView if already one has been created. Else create one.
- let addLineLensProviderOnce wpfView buffer =
- let res = lineLensProvider |> Seq.tryFind(fun (view, _) -> view = wpfView)
- match res with
- | None ->
- let documentId =
- lazy (
- match textDocumentFactory.TryGetTextDocument(buffer) with
- | true, textDocument ->
- Seq.tryHead (workspace.CurrentSolution.GetDocumentIdsWithFilePath(textDocument.FilePath))
- | _ -> None
- |> Option.get
- )
+ let addLineLensProvider wpfView buffer =
+ textDocumentFactory
+ |> tryGetTextDocument buffer
+ |> Option.map (fun document -> workspace.CurrentSolution.GetDocumentIdsWithFilePath(document.FilePath))
+ |> Option.bind Seq.tryHead
+ |> Option.map (fun documentId ->
let service = FSharpCodeLensService(serviceProvider, workspace, documentId, buffer, metadataAsSource, componentModel.GetService(), typeMap, LineLensDisplayService(wpfView, buffer), settings)
let provider = (wpfView, service)
- wpfView.Closed.Add (fun _ -> lineLensProvider.Remove provider |> ignore)
- lineLensProvider.Add(provider)
- | _ -> ()
+ wpfView.Closed.Add (fun _ -> lineLensProviders.Remove provider |> ignore)
+ lineLensProviders.Add(provider))
- [); Name("CodeLens");
- Order(Before = PredefinedAdornmentLayers.Text);
- TextViewRole(PredefinedTextViewRoles.Document)>]
- member val CodeLensAdornmentLayerDefinition : AdornmentLayerDefinition = null with get, set
-
[); Name("LineLens");
Order(Before = PredefinedAdornmentLayers.Text);
TextViewRole(PredefinedTextViewRoles.Document)>]
member val LineLensAdornmentLayerDefinition : AdornmentLayerDefinition = null with get, set
- interface IViewTaggerProvider with
- override _.CreateTagger(view, buffer) =
- if settings.CodeLens.Enabled && not settings.CodeLens.ReplaceWithLineLens then
- let wpfView =
- match view with
- | :? IWpfTextView as view -> view
- | _ -> failwith "error"
-
- box(addCodeLensProviderOnce wpfView buffer) :?> _
- else
- null
-
interface IWpfTextViewCreationListener with
override _.TextViewCreated view =
- if settings.CodeLens.Enabled && settings.CodeLens.ReplaceWithLineLens then
- addLineLensProviderOnce view (view.TextBuffer) |> ignore
\ No newline at end of file
+ if settings.CodeLens.Enabled then
+ let provider =
+ lineLensProviders
+ |> Seq.tryFind (fun (v, _) -> v = view)
+
+ if provider.IsNone then
+ addLineLensProvider view (view.TextBuffer) |> ignore
\ No newline at end of file
diff --git a/vsintegration/src/FSharp.Editor/CodeLens/FSharpCodeLensService.fs b/vsintegration/src/FSharp.Editor/CodeLens/FSharpCodeLensService.fs
index 2e18270e97e..18e0aa8098c 100644
--- a/vsintegration/src/FSharp.Editor/CodeLens/FSharpCodeLensService.fs
+++ b/vsintegration/src/FSharp.Editor/CodeLens/FSharpCodeLensService.fs
@@ -12,18 +12,12 @@ open System.Windows.Media
open System.Windows.Media.Animation
open Microsoft.CodeAnalysis
-open Microsoft.CodeAnalysis.Editor.Shared.Extensions
open Microsoft.CodeAnalysis.ExternalAccess.FSharp.Classification
open Microsoft.CodeAnalysis.ExternalAccess.FSharp.Editor.Shared.Extensions
-open FSharp.Compiler.CodeAnalysis
-open FSharp.Compiler.Diagnostics
-open FSharp.Compiler.EditorServices
open FSharp.Compiler.Symbols
open FSharp.Compiler.Syntax
open FSharp.Compiler.Text
-open FSharp.Compiler.Text
-open FSharp.Compiler.Tokenization
open Microsoft.VisualStudio.FSharp.Editor.Logging
open Microsoft.VisualStudio.Shell.Interop
@@ -32,17 +26,17 @@ open Microsoft.VisualStudio.Text.Classification
open Microsoft.CodeAnalysis.ExternalAccess.FSharp.Editor.Shared.Utilities
-type internal CodeLens(taggedText, computed, fullTypeSignature, uiElement) =
+type internal CodeLens(taggedText, computed, funcID, uiElement) =
member val TaggedText: Async<(ResizeArray * FSharpNavigation) option> = taggedText
member val Computed: bool = computed with get, set
- member val FullTypeSignature: string = fullTypeSignature
+ member val FuncID: string = funcID
member val UiElement: UIElement = uiElement with get, set
type internal FSharpCodeLensService
(
serviceProvider: IServiceProvider,
workspace: Workspace,
- documentId: Lazy,
+ documentId: DocumentId,
buffer: ITextBuffer,
metadataAsSource: FSharpMetadataAsSourceService,
classificationFormatMapService: IClassificationFormatMapService,
@@ -153,7 +147,7 @@ type internal FSharpCodeLensService
#if DEBUG
logInfof "Rechecking code due to buffer edit!"
#endif
- let! document = workspace.CurrentSolution.GetDocument(documentId.Value) |> Option.ofObj
+ let! document = workspace.CurrentSolution.GetDocument documentId |> Option.ofObj
let! parseFileResults, checkFileResults = document.GetFSharpParseAndCheckResultsAsync(nameof(FSharpUseMutationWhenValueIsMutableFixProvider)) |> liftAsync
let parsedInput = parseFileResults.ParseTree
#if DEBUG
@@ -221,14 +215,12 @@ type internal FSharpCodeLensService
match symbolUse.Symbol with
| :? FSharpMemberOrFunctionOrValue as func when func.IsModuleValueOrMember || func.IsProperty ->
let funcID = func.LogicalName + (func.FullType.ToString() |> hash |> string)
- // Use a combination of the the function name + the hashed value of the type signature
- let fullTypeSignature = func.FullType.ToString()
// Try to re-use the last results
if lastResults.ContainsKey funcID then
// Make sure that the results are usable
let inline setNewResultsAndWarnIfOverridenLocal value = setNewResultsAndWarnIfOverriden funcID value
let lastTrackingSpan, codeLens as lastResult = lastResults.[funcID]
- if codeLens.FullTypeSignature = fullTypeSignature then
+ if codeLens.FuncID = funcID then
setNewResultsAndWarnIfOverridenLocal lastResult
oldResults.Remove funcID |> ignore
else
@@ -247,7 +239,7 @@ type internal FSharpCodeLensService
let res =
CodeLens( Async.cache (useResults (symbolUse.DisplayContext, func, range)),
false,
- fullTypeSignature,
+ funcID,
null)
// The old results aren't computed at all, because the line might have changed create new results
tagsToUpdate.[lastTrackingSpan] <- (newTrackingSpan, funcID, res)
@@ -257,12 +249,12 @@ type internal FSharpCodeLensService
else
// The symbol might be completely new or has slightly changed.
// We need to track this and iterate over the left entries to ensure that there isn't anything
- unattachedSymbols.Add((symbolUse, func, funcID, fullTypeSignature))
+ unattachedSymbols.Add(symbolUse, func, funcID)
| _ -> ()
// In best case this works quite `covfefe` fine because often enough we change only a small part of the file and not the complete.
for unattachedSymbol in unattachedSymbols do
- let symbolUse, func, funcID, fullTypeSignature = unattachedSymbol
+ let symbolUse, func, funcID = unattachedSymbol
let declarationLine, range =
match visit func.DeclarationLocation.Start parsedInput with
| Some range -> range.StartLine - 1, range
@@ -270,7 +262,7 @@ type internal FSharpCodeLensService
let test (v:KeyValuePair<_, _>) =
let _, (codeLens:CodeLens) = v.Value
- codeLens.FullTypeSignature = fullTypeSignature
+ codeLens.FuncID = funcID
match oldResults |> Seq.tryFind test with
| Some res ->
let (trackingSpan : ITrackingSpan), (codeLens : CodeLens) = res.Value
@@ -288,7 +280,7 @@ type internal FSharpCodeLensService
CodeLens(
Async.cache (useResults (symbolUse.DisplayContext, func, range)),
false,
- fullTypeSignature,
+ funcID,
null)
// The tag might be still valid but it hasn't been computed yet so create fresh results
tagsToUpdate.[trackingSpan] <- (newTrackingSpan, funcID, res)
@@ -303,7 +295,7 @@ type internal FSharpCodeLensService
CodeLens(
Async.cache (useResults (symbolUse.DisplayContext, func, range)),
false,
- fullTypeSignature,
+ funcID,
null)
try
let declarationSpan =
@@ -347,7 +339,7 @@ type internal FSharpCodeLensService
sb.Begin()
else
#if DEBUG
- logWarningf "Couldn't retrieve code lens information for %A" codeLens.FullTypeSignature
+ logWarningf "Couldn't retrieve code lens information for %A" codeLens.FuncID
#endif
()
} |> (RoslynHelpers.StartAsyncSafe CancellationToken.None) "UIElement creation"
diff --git a/vsintegration/src/FSharp.Editor/CodeLens/LineLensDisplayService.fs b/vsintegration/src/FSharp.Editor/CodeLens/LineLensDisplayService.fs
index a34df51c722..85f0349112a 100644
--- a/vsintegration/src/FSharp.Editor/CodeLens/LineLensDisplayService.fs
+++ b/vsintegration/src/FSharp.Editor/CodeLens/LineLensDisplayService.fs
@@ -16,23 +16,16 @@ type internal LineLensDisplayService (view, buffer) =
/// Layouts all stack panels on the line
override self.LayoutUIElementOnLine _ (line:ITextViewLine) (ui:Grid) =
let left, top =
- match self.UiElementNeighbour.TryGetValue ui with
- | true, parent ->
- let left = Canvas.GetLeft parent
- let top = Canvas.GetTop parent
- let width = parent.ActualWidth
- left + width, top
- | _ ->
- try
- let bounds = line.GetCharacterBounds(line.Start)
- line.TextRight + 5.0, bounds.Top - 1.
- with e ->
+ try
+ let bounds = line.GetCharacterBounds(line.Start)
+ line.TextRight + 5.0, bounds.Top - 1.
+ with e ->
#if DEBUG
- logExceptionWithContext (e, "Error in layout ui element on line")
+ logExceptionWithContext (e, "Error in layout ui element on line")
#else
- ignore e
+ ignore e
#endif
- Canvas.GetLeft ui, Canvas.GetTop ui
+ Canvas.GetLeft ui, Canvas.GetTop ui
Canvas.SetLeft(ui, left)
Canvas.SetTop(ui, top)
diff --git a/vsintegration/src/FSharp.Editor/FSharp.Editor.fsproj b/vsintegration/src/FSharp.Editor/FSharp.Editor.fsproj
index 156c187769d..c3fbf9a4258 100644
--- a/vsintegration/src/FSharp.Editor/FSharp.Editor.fsproj
+++ b/vsintegration/src/FSharp.Editor/FSharp.Editor.fsproj
@@ -126,7 +126,6 @@
-
diff --git a/vsintegration/src/FSharp.Editor/LanguageService/LanguageService.fs b/vsintegration/src/FSharp.Editor/LanguageService/LanguageService.fs
index 203867a6afe..ed20c78bf39 100644
--- a/vsintegration/src/FSharp.Editor/LanguageService/LanguageService.fs
+++ b/vsintegration/src/FSharp.Editor/LanguageService/LanguageService.fs
@@ -93,20 +93,39 @@ type internal FSharpWorkspaceServiceFactory
match checkerSingleton with
| Some _ -> ()
| _ ->
- let checker =
+ let checker =
lazy
- let checker =
+ let editorOptions =
+ let editorOptions = workspace.Services.GetService()
+
+ match box editorOptions with
+ | null -> None
+ | _ -> Some editorOptions
+
+ let enableParallelCheckingWithSignatureFiles =
+ editorOptions
+ |> Option.map (fun options -> options.LanguageServicePerformance.EnableParallelCheckingWithSignatureFiles)
+ |> Option.defaultValue false
+
+ let enableParallelReferenceResolution =
+ editorOptions
+ |> Option.map (fun options -> options.LanguageServicePerformance.EnableParallelReferenceResolution)
+ |> Option.defaultValue false
+
+ let checker =
FSharpChecker.Create(
- projectCacheSize = 5000, // We do not care how big the cache is. VS will actually tell FCS to clear caches, so this is fine.
+ projectCacheSize = 5000, // We do not care how big the cache is. VS will actually tell FCS to clear caches, so this is fine.
keepAllBackgroundResolutions = false,
legacyReferenceResolver=LegacyMSBuildReferenceResolver.getResolver(),
tryGetMetadataSnapshot = tryGetMetadataSnapshot,
keepAllBackgroundSymbolUses = false,
enableBackgroundItemKeyStoreAndSemanticClassification = true,
- enablePartialTypeChecking = true)
- checker
- checkerSingleton <- Some checker
- )
+ enablePartialTypeChecking = true,
+ enableParallelCheckingWithSignatureFiles = enableParallelCheckingWithSignatureFiles,
+ parallelReferenceResolution = enableParallelReferenceResolution)
+ checker
+ checkerSingleton <- Some checker
+ )
let optionsManager =
lazy
diff --git a/vsintegration/src/FSharp.Editor/Options/EditorOptions.fs b/vsintegration/src/FSharp.Editor/Options/EditorOptions.fs
index 689c410b5f1..b2df69f41eb 100644
--- a/vsintegration/src/FSharp.Editor/Options/EditorOptions.fs
+++ b/vsintegration/src/FSharp.Editor/Options/EditorOptions.fs
@@ -63,23 +63,23 @@ type LanguageServicePerformanceOptions =
{ EnableInMemoryCrossProjectReferences: bool
AllowStaleCompletionResults: bool
TimeUntilStaleCompletion: int
- ProjectCheckCacheSize: int }
+ EnableParallelCheckingWithSignatureFiles: bool
+ EnableParallelReferenceResolution: bool }
static member Default =
{ EnableInMemoryCrossProjectReferences = true
AllowStaleCompletionResults = true
TimeUntilStaleCompletion = 2000 // In ms, so this is 2 seconds
- ProjectCheckCacheSize = 200 }
+ EnableParallelCheckingWithSignatureFiles = false
+ EnableParallelReferenceResolution = false }
[]
type CodeLensOptions =
{ Enabled : bool
- ReplaceWithLineLens: bool
UseColors: bool
Prefix : string }
static member Default =
{ Enabled = false
UseColors = false
- ReplaceWithLineLens = true
Prefix = "// " }
[]
diff --git a/vsintegration/src/FSharp.UIResources/CodeLensOptionControl.xaml b/vsintegration/src/FSharp.UIResources/CodeLensOptionControl.xaml
index 7e62f575fd6..750cc260b43 100644
--- a/vsintegration/src/FSharp.UIResources/CodeLensOptionControl.xaml
+++ b/vsintegration/src/FSharp.UIResources/CodeLensOptionControl.xaml
@@ -27,9 +27,6 @@
-
diff --git a/vsintegration/src/FSharp.UIResources/FSharp.UIResources.csproj b/vsintegration/src/FSharp.UIResources/FSharp.UIResources.csproj
index b11c35d2187..1dfea7e42c8 100644
--- a/vsintegration/src/FSharp.UIResources/FSharp.UIResources.csproj
+++ b/vsintegration/src/FSharp.UIResources/FSharp.UIResources.csproj
@@ -24,4 +24,19 @@
+
+
+ True
+ True
+ Strings.resx
+
+
+
+
+
+ PublicResXFileCodeGenerator
+ Strings.Designer.cs
+
+
+
diff --git a/vsintegration/src/FSharp.UIResources/LanguageServicePerformanceOptionControl.xaml b/vsintegration/src/FSharp.UIResources/LanguageServicePerformanceOptionControl.xaml
index e67690250dd..26a38d423d5 100644
--- a/vsintegration/src/FSharp.UIResources/LanguageServicePerformanceOptionControl.xaml
+++ b/vsintegration/src/FSharp.UIResources/LanguageServicePerformanceOptionControl.xaml
@@ -23,27 +23,6 @@
IsChecked="{Binding EnableInMemoryCrossProjectReferences}"
Content="{x:Static local:Strings.Enable_in_memory_cross_project_references}"
ToolTip="{x:Static local:Strings.Tooltip_in_memory_cross_project_references}"/>
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
@@ -75,6 +54,16 @@
+
+
+
+
+
+
diff --git a/vsintegration/src/FSharp.UIResources/Strings.Designer.cs b/vsintegration/src/FSharp.UIResources/Strings.Designer.cs
index fd74fbb404f..2227b3e1819 100644
--- a/vsintegration/src/FSharp.UIResources/Strings.Designer.cs
+++ b/vsintegration/src/FSharp.UIResources/Strings.Designer.cs
@@ -19,7 +19,7 @@ namespace Microsoft.VisualStudio.FSharp.UIResources {
// class via a tool like ResGen or Visual Studio.
// To add or remove a member, edit your .ResX file then rerun ResGen
// with the /str option, or rebuild your VS project.
- [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")]
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
public class Strings {
@@ -177,6 +177,24 @@ public static string Enable_in_memory_cross_project_references {
}
}
+ ///
+ /// Looks up a localized string similar to Enable parallel type checking with signature files.
+ ///
+ public static string Enable_Parallel_Checking_With_Signature_Files {
+ get {
+ return ResourceManager.GetString("Enable_Parallel_Checking_With_Signature_Files", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Enable parallel reference resolution.
+ ///
+ public static string Enable_Parallel_Reference_Resolution {
+ get {
+ return ResourceManager.GetString("Enable_Parallel_Reference_Resolution", resourceCulture);
+ }
+ }
+
///
/// Looks up a localized string similar to Enable stale data for IntelliSense features.
///
@@ -223,7 +241,7 @@ public static string Enter_Key_Rule {
}
///
- /// Looks up a localized string similar to Re-format indentation on paste.
+ /// Looks up a localized string similar to Re-format indentation on paste (Experimental).
///
public static string Format_on_paste {
get {
@@ -268,11 +286,11 @@ public static string Outlining {
}
///
- /// Looks up a localized string similar to Number of projects whose data is cached in memory.
+ /// Looks up a localized string similar to Parallelization (requires restart).
///
- public static string Project_check_cache_size {
+ public static string Parallelization {
get {
- return ResourceManager.GetString("Project_check_cache_size", resourceCulture);
+ return ResourceManager.GetString("Parallelization", resourceCulture);
}
}
@@ -393,15 +411,6 @@ public static string Tooltip_in_memory_cross_project_references {
}
}
- ///
- /// Looks up a localized string similar to Project data is cached for IDE features. Higher values use more memory because more projects are cached. Tuning this value should not affect small or medium-sized solutions..
- ///
- public static string Tooltip_project_check_cache_size {
- get {
- return ResourceManager.GetString("Tooltip_project_check_cache_size", resourceCulture);
- }
- }
-
///
/// Looks up a localized string similar to Analyze and suggest fixes for unused values.
///
diff --git a/vsintegration/src/FSharp.UIResources/Strings.resx b/vsintegration/src/FSharp.UIResources/Strings.resx
index b0ceb57d47a..9846b778ddc 100644
--- a/vsintegration/src/FSharp.UIResources/Strings.resx
+++ b/vsintegration/src/FSharp.UIResources/Strings.resx
@@ -165,9 +165,6 @@
_Enable in-memory cross project references
-
- Number of projects whose data is cached in memory
-
S_how navigation links as
@@ -210,9 +207,6 @@
In-memory cross-project references store project-level data in memory to allow IDE features to work across projects.
-
- Project data is cached for IDE features. Higher values use more memory because more projects are cached. Tuning this value should not affect small or medium-sized solutions.
-
Always add new line on enter
@@ -237,4 +231,13 @@
Diagnostics
+
+ Parallelization (requires restart)
+
+
+ Enable parallel type checking with signature files
+
+
+ Enable parallel reference resolution
+
\ No newline at end of file
diff --git a/vsintegration/src/FSharp.UIResources/xlf/Strings.cs.xlf b/vsintegration/src/FSharp.UIResources/xlf/Strings.cs.xlf
index eb4650c57ed..a2cc11c84f8 100644
--- a/vsintegration/src/FSharp.UIResources/xlf/Strings.cs.xlf
+++ b/vsintegration/src/FSharp.UIResources/xlf/Strings.cs.xlf
@@ -47,6 +47,16 @@
Diagnostika
+
+ Enable parallel type checking with signature files
+ Enable parallel type checking with signature files
+
+
+
+ Enable parallel reference resolution
+ Enable parallel reference resolution
+
+ PerformanceVýkon
@@ -67,6 +77,11 @@
Navigační odkazy
+
+ Parallelization (requires restart)
+ Parallelization (requires restart)
+
+ Show s_ymbols in unopened namespacesZobrazit s_ymboly v neotevřených oborech názvů
@@ -87,11 +102,6 @@
_Povolit odkazy mezi projekty v paměti
-
- Number of projects whose data is cached in memory
- Počet projektů, jejichž data jsou uložená v mezipaměti
-
- S_how navigation links asZo_brazit navigační odkazy jako
@@ -167,11 +177,6 @@
V odkazech v paměti pro různé projekty jsou uložená data na úrovni projektů, aby mohly mezi projekty fungovat funkce IDE.
-
- Project data is cached for IDE features. Higher values use more memory because more projects are cached. Tuning this value should not affect small or medium-sized solutions.
- Projektová data jsou uložená v mezipaměti pro funkce IDE. Vyšší hodnoty znamenají využití více paměti, protože je uloženo více projektů. Vyladění této hodnoty by nemělo mít vliv na malá a středně velká řešení.
-
- Always add new line on enterPři stisku Enter vždy přidat nový řádek
diff --git a/vsintegration/src/FSharp.UIResources/xlf/Strings.de.xlf b/vsintegration/src/FSharp.UIResources/xlf/Strings.de.xlf
index 7db4ba605f3..3724e517a15 100644
--- a/vsintegration/src/FSharp.UIResources/xlf/Strings.de.xlf
+++ b/vsintegration/src/FSharp.UIResources/xlf/Strings.de.xlf
@@ -47,6 +47,16 @@
Diagnose
+
+ Enable parallel type checking with signature files
+ Enable parallel type checking with signature files
+
+
+
+ Enable parallel reference resolution
+ Enable parallel reference resolution
+
+ PerformanceLeistung
@@ -67,6 +77,11 @@
Navigationslinks
+
+ Parallelization (requires restart)
+ Parallelization (requires restart)
+
+ Show s_ymbols in unopened namespacesS_ymbole in nicht geöffneten Namespaces anzeigen
@@ -87,11 +102,6 @@
Proj_ektübergreifende Verweise im Arbeitsspeicher aktivieren
-
- Number of projects whose data is cached in memory
- Anzahl von Projekten, deren Daten im Arbeitsspeicher zwischengespeichert werden
-
- S_how navigation links asNavigationslink_s anzeigen als
@@ -167,11 +177,6 @@
Bei projektübergreifenden In-Memory-Verweisen werden Daten auf Projektebene im Arbeitsspeicher abgelegt, damit IDE-Features projektübergreifend verwendet werden können.
-
- Project data is cached for IDE features. Higher values use more memory because more projects are cached. Tuning this value should not affect small or medium-sized solutions.
- Für IDE-Features werden Projektdaten zwischengespeichert. Bei höheren Werten wird mehr Arbeitsspeicher beansprucht, weil mehr Projekte zwischengespeichert werden. Die Optimierung dieses Werts besitzt keine Auswirkungen auf kleine oder mittelgroße Projektmappen.
-
- Always add new line on enterNach Drücken der EINGABETASTE immer neue Zeile hinzufügen
diff --git a/vsintegration/src/FSharp.UIResources/xlf/Strings.es.xlf b/vsintegration/src/FSharp.UIResources/xlf/Strings.es.xlf
index 674c69434c2..b8fe4df4030 100644
--- a/vsintegration/src/FSharp.UIResources/xlf/Strings.es.xlf
+++ b/vsintegration/src/FSharp.UIResources/xlf/Strings.es.xlf
@@ -47,6 +47,16 @@
Diagnóstico
+
+ Enable parallel type checking with signature files
+ Enable parallel type checking with signature files
+
+
+
+ Enable parallel reference resolution
+ Enable parallel reference resolution
+
+ PerformanceRendimiento
@@ -67,6 +77,11 @@
Vínculos de navegación
+
+ Parallelization (requires restart)
+ Parallelization (requires restart)
+
+ Show s_ymbols in unopened namespacesMostrar sím_bolos en espacios de nombres sin abrir
@@ -87,11 +102,6 @@
_Habilitar referencias entre proyectos en memoria
-
- Number of projects whose data is cached in memory
- Número de proyectos cuyos datos se almacenan en la memoria caché
-
- S_how navigation links asM_ostrar vínculos de navegación como
@@ -167,11 +177,6 @@
Las referencias en memoria entre proyectos almacenan los datos de nivel de proyecto en memoria para permitir que las características del IDE funcionen de unos proyectos a otros.
-
- Project data is cached for IDE features. Higher values use more memory because more projects are cached. Tuning this value should not affect small or medium-sized solutions.
- Los datos de proyecto se almacenan en caché para que funcionen las características del IDE. Los valores más altos utilizan más memoria porque se almacenan en caché más proyectos. El ajuste de este valor no debería afectar a soluciones de tamaño pequeño o medio.
-
- Always add new line on enterSiempre agregar una nueva línea al pulsar Intro
diff --git a/vsintegration/src/FSharp.UIResources/xlf/Strings.fr.xlf b/vsintegration/src/FSharp.UIResources/xlf/Strings.fr.xlf
index ec9bafbe8df..82a00f7f4ac 100644
--- a/vsintegration/src/FSharp.UIResources/xlf/Strings.fr.xlf
+++ b/vsintegration/src/FSharp.UIResources/xlf/Strings.fr.xlf
@@ -47,6 +47,16 @@
Diagnostics
+
+ Enable parallel type checking with signature files
+ Enable parallel type checking with signature files
+
+
+
+ Enable parallel reference resolution
+ Enable parallel reference resolution
+
+ PerformancePerformances
@@ -67,6 +77,11 @@
Liens de navigation
+
+ Parallelization (requires restart)
+ Parallelization (requires restart)
+
+ Show s_ymbols in unopened namespacesAfficher les sym_boles dans les espaces de noms non ouverts
@@ -87,11 +102,6 @@
_Activer les références de projet croisé en mémoire
-
- Number of projects whose data is cached in memory
- Nombre de projets dont les données sont mises en cache dans la mémoire
-
- S_how navigation links asAffic_her les liens de navigation en tant que
@@ -167,11 +177,6 @@
Les références inter-projets en mémoire stockent les données de niveau projet dans la mémoire pour permettre aux fonctionnalités de l'IDE de fonctionner sur plusieurs projets.
-
- Project data is cached for IDE features. Higher values use more memory because more projects are cached. Tuning this value should not affect small or medium-sized solutions.
- Les données de projet sont mises en cache pour les fonctionnalités de l'IDE. Les valeurs plus élevées utilisent plus de mémoire, car davantage de projets sont mis en cache. L'ajustement de cette valeur ne devrait pas affecter les petites ou moyennes solutions.
-
- Always add new line on enterToujours ajouter une nouvelle ligne en appuyant sur Entrée
diff --git a/vsintegration/src/FSharp.UIResources/xlf/Strings.it.xlf b/vsintegration/src/FSharp.UIResources/xlf/Strings.it.xlf
index 9b2acf06d1b..3f5a0bef8bb 100644
--- a/vsintegration/src/FSharp.UIResources/xlf/Strings.it.xlf
+++ b/vsintegration/src/FSharp.UIResources/xlf/Strings.it.xlf
@@ -47,6 +47,16 @@
Diagnostica
+
+ Enable parallel type checking with signature files
+ Enable parallel type checking with signature files
+
+
+
+ Enable parallel reference resolution
+ Enable parallel reference resolution
+
+ PerformancePrestazioni
@@ -67,6 +77,11 @@
Collegamenti di navigazione
+
+ Parallelization (requires restart)
+ Parallelization (requires restart)
+
+ Show s_ymbols in unopened namespacesMostra si_mboli in spazi dei nomi non aperti
@@ -87,11 +102,6 @@
_Abilita i riferimenti tra progetti in memoria
-
- Number of projects whose data is cached in memory
- Numero di progetti i cui dati sono disponibili nella cache in memoria
-
- S_how navigation links asM_ostra collegamenti di navigazione come
@@ -167,11 +177,6 @@
I riferimenti tra progetti in memoria consentono di archiviare in memoria i dati a livello di progetto per consentire l'uso di funzionalità IDE tra progetti.
-
- Project data is cached for IDE features. Higher values use more memory because more projects are cached. Tuning this value should not affect small or medium-sized solutions.
- I dati del progetto sono memorizzati nella cache per le funzionalità IDE. Con valori più elevati viene usata una maggiore quantità di memoria perché nella cache viene memorizzato un numero maggiore di progetti. La disattivazione di questo valore non dovrebbe influire su soluzioni di piccole e medie dimensioni.
-
- Always add new line on enterAggiungi sempre una nuova riga dopo INVIO
diff --git a/vsintegration/src/FSharp.UIResources/xlf/Strings.ja.xlf b/vsintegration/src/FSharp.UIResources/xlf/Strings.ja.xlf
index 8ab4c15b6e1..0476d98187d 100644
--- a/vsintegration/src/FSharp.UIResources/xlf/Strings.ja.xlf
+++ b/vsintegration/src/FSharp.UIResources/xlf/Strings.ja.xlf
@@ -47,6 +47,16 @@
診断
+
+ Enable parallel type checking with signature files
+ Enable parallel type checking with signature files
+
+
+
+ Enable parallel reference resolution
+ Enable parallel reference resolution
+
+ Performanceパフォーマンス
@@ -67,6 +77,11 @@
ナビゲーション リンク
+
+ Parallelization (requires restart)
+ Parallelization (requires restart)
+
+ Show s_ymbols in unopened namespaces開かれていない名前空間の記号を表示する(_Y)
@@ -87,11 +102,6 @@
メモリ内のプロジェクト間参照を有効にする(_E)
-
- Number of projects whose data is cached in memory
- データがメモリ内にキャッシュされているプロジェクトの数
-
- S_how navigation links as次としてナビゲーション リンクを表示する(_H)
@@ -167,11 +177,6 @@
メモリ内のプロジェクト間参照に、プロジェクトをまたいで IDE 機能を動作可能にするプロジェクト レベルのデータが格納されます。
-
- Project data is cached for IDE features. Higher values use more memory because more projects are cached. Tuning this value should not affect small or medium-sized solutions.
- IDE 機能のためにプロジェクト データがキャッシュされます。値を高くすると、キャッシュされるプロジェクトが多くなるため、メモリ使用量が増えます。この値の調整は、小規模または中規模のソリューションに影響しません。
-
- Always add new line on enterEnter を押すと常に新しい行を追加します
diff --git a/vsintegration/src/FSharp.UIResources/xlf/Strings.ko.xlf b/vsintegration/src/FSharp.UIResources/xlf/Strings.ko.xlf
index 4812b0acc99..b14183356b6 100644
--- a/vsintegration/src/FSharp.UIResources/xlf/Strings.ko.xlf
+++ b/vsintegration/src/FSharp.UIResources/xlf/Strings.ko.xlf
@@ -47,6 +47,16 @@
진단
+
+ Enable parallel type checking with signature files
+ Enable parallel type checking with signature files
+
+
+
+ Enable parallel reference resolution
+ Enable parallel reference resolution
+
+ Performance성능
@@ -67,6 +77,11 @@
탐색 링크
+
+ Parallelization (requires restart)
+ Parallelization (requires restart)
+
+ Show s_ymbols in unopened namespaces열려 있지 않은 네임스페이스에 기호 표시(_Y)
@@ -87,11 +102,6 @@
메모리 내 크로스 프로젝트 참조 사용(_E)
-
- Number of projects whose data is cached in memory
- 메모리에 데이터가 캐시된 프로젝트 수
-
- S_how navigation links as탐색 링크를 다음으로 표시(_H)
@@ -167,11 +177,6 @@
메모리 내 크로스 프로젝트 참조가 메모리에 프로젝트 수준 데이터를 저장하여 IDE 기능이 프로젝트에서 작동하도록 합니다.
-
- Project data is cached for IDE features. Higher values use more memory because more projects are cached. Tuning this value should not affect small or medium-sized solutions.
- 프로젝트 데이터가 IDE 기능에 대해 캐시됩니다. 값이 클수록 프로제트가 더 많이 캐시되므로 메모리를 더 많이 사용합니다. 이 값을 조정해도 중소 규모 솔루션에 영향을 미치지 않습니다.
-
- Always add new line on enter입력 시 새 줄 항상 추가
diff --git a/vsintegration/src/FSharp.UIResources/xlf/Strings.pl.xlf b/vsintegration/src/FSharp.UIResources/xlf/Strings.pl.xlf
index c96168985ec..02fd84cb017 100644
--- a/vsintegration/src/FSharp.UIResources/xlf/Strings.pl.xlf
+++ b/vsintegration/src/FSharp.UIResources/xlf/Strings.pl.xlf
@@ -47,6 +47,16 @@
Diagnostyka
+
+ Enable parallel type checking with signature files
+ Enable parallel type checking with signature files
+
+
+
+ Enable parallel reference resolution
+ Enable parallel reference resolution
+
+ PerformanceWydajność
@@ -67,6 +77,11 @@
Linki nawigacyjne
+
+ Parallelization (requires restart)
+ Parallelization (requires restart)
+
+ Show s_ymbols in unopened namespacesPokaż s_ymbole w nieotwartych przestrzeniach nazw
@@ -87,11 +102,6 @@
_Włącz odwołania między projektami w pamięci
-
- Number of projects whose data is cached in memory
- Liczba projektów, które mają dane buforowane w pamięci
-
- S_how navigation links asP_okaż linki nawigacyjne jako
@@ -167,11 +177,6 @@
Odwołania między projektami w pamięci przechowują dane na poziomie projektu w pamięci, aby umożliwić funkcjom środowiska IDE działanie w wielu projektach.
-
- Project data is cached for IDE features. Higher values use more memory because more projects are cached. Tuning this value should not affect small or medium-sized solutions.
- Dane projektów są buforowane na potrzeby funkcji środowiska IDE. Wyższe wartości powodują używanie większej ilości pamięci, ponieważ buforowanych jest więcej projektów. Dostrajanie tej wartości nie powinno mieć wpływu na małe ani średnie rozwiązania.
-
- Always add new line on enterZawsze dodawaj nowy wiersz po naciśnięciu klawisza Enter
diff --git a/vsintegration/src/FSharp.UIResources/xlf/Strings.pt-BR.xlf b/vsintegration/src/FSharp.UIResources/xlf/Strings.pt-BR.xlf
index 076de7f9087..7ca5a251c15 100644
--- a/vsintegration/src/FSharp.UIResources/xlf/Strings.pt-BR.xlf
+++ b/vsintegration/src/FSharp.UIResources/xlf/Strings.pt-BR.xlf
@@ -47,6 +47,16 @@
Diagnóstico
+
+ Enable parallel type checking with signature files
+ Enable parallel type checking with signature files
+
+
+
+ Enable parallel reference resolution
+ Enable parallel reference resolution
+
+ PerformanceDesempenho
@@ -67,6 +77,11 @@
Links de navegação
+
+ Parallelization (requires restart)
+ Parallelization (requires restart)
+
+ Show s_ymbols in unopened namespacesMostrar s_ímbolos em namespaces não abertos
@@ -87,11 +102,6 @@
_Habilitar referências de projeto cruzado na memória
-
- Number of projects whose data is cached in memory
- Número de projetos cujos dados estão em cache na memória
-
- S_how navigation links asE_xibir link de navegação como
@@ -167,11 +177,6 @@
As referências entre projetos na memória armazenam os dados de nível de projeto na memória para permitir que os recursos do IDE funcionem nos projetos.
-
- Project data is cached for IDE features. Higher values use more memory because more projects are cached. Tuning this value should not affect small or medium-sized solutions.
- Os dados do projeto são colocados em cache para os recursos do IDE. Os valores mais altos utilizam mais memória porque mais projetos são colocados em cache. O ajuste desses valores não deve afetar as soluções de pequeno ou médio porte.
-
- Always add new line on enterSempre adicionar uma nova linha ao pressionar enter
diff --git a/vsintegration/src/FSharp.UIResources/xlf/Strings.ru.xlf b/vsintegration/src/FSharp.UIResources/xlf/Strings.ru.xlf
index 690059925df..91c8065c0ca 100644
--- a/vsintegration/src/FSharp.UIResources/xlf/Strings.ru.xlf
+++ b/vsintegration/src/FSharp.UIResources/xlf/Strings.ru.xlf
@@ -47,6 +47,16 @@
Диагностика
+
+ Enable parallel type checking with signature files
+ Enable parallel type checking with signature files
+
+
+
+ Enable parallel reference resolution
+ Enable parallel reference resolution
+
+ PerformanceПроизводительность
@@ -67,6 +77,11 @@
Ссылки навигации
+
+ Parallelization (requires restart)
+ Parallelization (requires restart)
+
+ Show s_ymbols in unopened namespacesПо_казать символы в неоткрытых пространствах имен
@@ -87,11 +102,6 @@
_Включить перекрестные ссылки между проектами в памяти
-
- Number of projects whose data is cached in memory
- Число проектов, данные которых кэшируются в памяти
-
- S_how navigation links asП_оказать ссылки навигации как
@@ -167,11 +177,6 @@
Перекрестные ссылки между проектами в памяти хранят данные уровня проекта в памяти, поэтому функции и компоненты IDE могут работать в разных проектах.
-
- Project data is cached for IDE features. Higher values use more memory because more projects are cached. Tuning this value should not affect small or medium-sized solutions.
- Для функций и компонентов IDE используются кэшированные данные проекта. Более высокие значения потребляют больший объем памяти, так как кэшируется больше проектов. Настройка этого значения не должна влиять на решения небольших или средних размеров.
-
- Always add new line on enterВсегда добавлять новую строку при нажатии клавиши ВВОД
diff --git a/vsintegration/src/FSharp.UIResources/xlf/Strings.tr.xlf b/vsintegration/src/FSharp.UIResources/xlf/Strings.tr.xlf
index e05c403767a..f7de45984dc 100644
--- a/vsintegration/src/FSharp.UIResources/xlf/Strings.tr.xlf
+++ b/vsintegration/src/FSharp.UIResources/xlf/Strings.tr.xlf
@@ -47,6 +47,16 @@
Tanılama
+
+ Enable parallel type checking with signature files
+ Enable parallel type checking with signature files
+
+
+
+ Enable parallel reference resolution
+ Enable parallel reference resolution
+
+ PerformancePerformans
@@ -67,6 +77,11 @@
Gezinti bağlantıları
+
+ Parallelization (requires restart)
+ Parallelization (requires restart)
+
+ Show s_ymbols in unopened namespacesAçılmamış ad alanlarında s_embolleri göster
@@ -87,11 +102,6 @@
_Bellek içi çapraz proje başvurularını etkinleştir
-
- Number of projects whose data is cached in memory
- Verileri bellekte önbelleğe alınan proje sayısı
-
- S_how navigation links asGezinti bağlantılarını farklı _göster
@@ -167,11 +177,6 @@
Bellek içi projeler arası başvurular, IDE özelliklerinin farklı projelerde çalışmasına imkan tanımak için bellekte proje düzeyi veriler depolar.
-
- Project data is cached for IDE features. Higher values use more memory because more projects are cached. Tuning this value should not affect small or medium-sized solutions.
- IDE özellikleri için proje verileri önbelleğe alınır. Değer yüksek olduğunda daha fazla proje önbelleğe alındığından daha fazla bellek kullanılır. Bu değerin ayarlanması küçük veya orta ölçekli çözümleri etkilememelidir.
-
- Always add new line on enterEnter'a basıldığında her zaman yeni satır ekle
diff --git a/vsintegration/src/FSharp.UIResources/xlf/Strings.zh-Hans.xlf b/vsintegration/src/FSharp.UIResources/xlf/Strings.zh-Hans.xlf
index b219edc12c0..7478bb60d18 100644
--- a/vsintegration/src/FSharp.UIResources/xlf/Strings.zh-Hans.xlf
+++ b/vsintegration/src/FSharp.UIResources/xlf/Strings.zh-Hans.xlf
@@ -47,6 +47,16 @@
诊断
+
+ Enable parallel type checking with signature files
+ Enable parallel type checking with signature files
+
+
+
+ Enable parallel reference resolution
+ Enable parallel reference resolution
+
+ Performance性能
@@ -67,6 +77,11 @@
导航链接
+
+ Parallelization (requires restart)
+ Parallelization (requires restart)
+
+ Show s_ymbols in unopened namespaces显示未打开的命名空间中的符号(_Y)
@@ -87,11 +102,6 @@
启用内存中跨项目引用(_E)
-
- Number of projects whose data is cached in memory
- 内存中缓存了其数据的项目数
-
- S_how navigation links as导航链接显示方式(_H)
@@ -167,11 +177,6 @@
内存中跨项目引用将项目级数据存储在内存中,让 IDE 功能能够跨项目工作。
-
- Project data is cached for IDE features. Higher values use more memory because more projects are cached. Tuning this value should not affect small or medium-sized solutions.
- 针对 IDE 功能缓存项目数据。值越大,缓存的项目越多,因此使用的内存越多。调整此值不应影响小型或中型解决方案。
-
- Always add new line on enter始终在点击回车时时添加新行
diff --git a/vsintegration/src/FSharp.UIResources/xlf/Strings.zh-Hant.xlf b/vsintegration/src/FSharp.UIResources/xlf/Strings.zh-Hant.xlf
index 0b6b964edda..255c7ee09d5 100644
--- a/vsintegration/src/FSharp.UIResources/xlf/Strings.zh-Hant.xlf
+++ b/vsintegration/src/FSharp.UIResources/xlf/Strings.zh-Hant.xlf
@@ -47,6 +47,16 @@
診斷
+
+ Enable parallel type checking with signature files
+ Enable parallel type checking with signature files
+
+
+
+ Enable parallel reference resolution
+ Enable parallel reference resolution
+
+ Performance效能
@@ -67,6 +77,11 @@
導覽連結
+
+ Parallelization (requires restart)
+ Parallelization (requires restart)
+
+ Show s_ymbols in unopened namespaces顯示未開啟之命名空間中的符號(_Y)
@@ -87,11 +102,6 @@
允許記憶體內跨專案參考(_E)
-
- Number of projects whose data is cached in memory
- 資料會快取到記憶體的專案數
-
- S_how navigation links as顯示導覽連結為(_H)
@@ -167,11 +177,6 @@
記憶體內跨專案參考,會在記憶體中儲存專案等級的資料,以允許 IDE 功能在各專案中皆可運作。
-
- Project data is cached for IDE features. Higher values use more memory because more projects are cached. Tuning this value should not affect small or medium-sized solutions.
- 專案資料會進行快取,供 IDE 功能使用。值較高時會使用較多的記憶體,這是因為會快取較多的專案數。調整此值應該不會影響中小型的解決方案。
-
- Always add new line on enter一律在按 ENTER 時新增新行