diff --git a/FSharpBuild.Directory.Build.props b/FSharpBuild.Directory.Build.props
index ff7a1b670da..080077bc21e 100644
--- a/FSharpBuild.Directory.Build.props
+++ b/FSharpBuild.Directory.Build.props
@@ -15,7 +15,8 @@
$(ArtifactsDir)\Bootstrap
4.4.0
1182;0025;$(WarningsAsErrors)
-
+ $(OtherFlags) --nowarn:3384
+
diff --git a/azure-pipelines.yml b/azure-pipelines.yml
index 37979ac6b9c..22cc0b32eff 100644
--- a/azure-pipelines.yml
+++ b/azure-pipelines.yml
@@ -56,6 +56,8 @@ variables:
value: .NETCore
- name: VisualStudioDropName
value: Products/$(System.TeamProject)/$(Build.Repository.Name)/$(Build.SourceBranchName)/$(Build.BuildNumber)
+ - name: LegacyDotNetSdkVersion
+ value: 3.1.405
- name: DotNetSdkVersion
value: '5.0.100'
- ${{ if and(eq(variables['System.TeamProject'], 'public'), eq(variables['Build.Reason'], 'PullRequest')) }}:
@@ -103,6 +105,12 @@ stages:
steps:
- checkout: self
clean: true
+ - task: UseDotNet@2
+ displayName: Add legacy .NET SDK
+ inputs:
+ packageType: sdk
+ version: $(LegacyDotNetSdkVersion)
+ installationPath: $(Agent.ToolsDirectory)/dotnet
- script: eng\CIBuild.cmd
-configuration $(_BuildConfig)
-prepareMachine
@@ -211,6 +219,12 @@ stages:
steps:
- checkout: self
clean: true
+ - task: UseDotNet@2
+ displayName: Add legacy .NET SDK
+ inputs:
+ packageType: sdk
+ version: $(LegacyDotNetSdkVersion)
+ installationPath: $(Agent.ToolsDirectory)/dotnet
- script: eng\CIBuild.cmd -configuration $(_configuration) -$(_testKind)
displayName: Build / Test
- task: PublishTestResults@2
@@ -261,6 +275,12 @@ stages:
steps:
- checkout: self
clean: true
+ - task: UseDotNet@2
+ displayName: Add legacy .NET SDK
+ inputs:
+ packageType: sdk
+ version: $(LegacyDotNetSdkVersion)
+ installationPath: $(Agent.ToolsDirectory)/dotnet
- script: ./eng/cibuild.sh --configuration $(_BuildConfig) --testcoreclr
displayName: Build / Test
- task: PublishTestResults@2
@@ -293,6 +313,12 @@ stages:
steps:
- checkout: self
clean: true
+ - task: UseDotNet@2
+ displayName: Add legacy .NET SDK
+ inputs:
+ packageType: sdk
+ version: $(LegacyDotNetSdkVersion)
+ installationPath: $(Agent.ToolsDirectory)/dotnet
- script: ./eng/cibuild.sh --configuration $(_BuildConfig) --testcoreclr
displayName: Build / Test
- task: PublishTestResults@2
diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml
index a02baf65fee..38beb569004 100644
--- a/eng/Version.Details.xml
+++ b/eng/Version.Details.xml
@@ -3,9 +3,9 @@
-
+
https://github.com/dotnet/arcade
- c313ff83e84445094fa5463498d5c94c29f27e1d
+ f6ed3308865528c56ed26b85004121fce56bf4f4
diff --git a/eng/common/internal-feed-operations.ps1 b/eng/common/internal-feed-operations.ps1
index b8f6529fdc8..418c09930cf 100644
--- a/eng/common/internal-feed-operations.ps1
+++ b/eng/common/internal-feed-operations.ps1
@@ -63,8 +63,6 @@ function SetupCredProvider {
}
if (($endpoints | Measure-Object).Count -gt 0) {
- # [SuppressMessage("Microsoft.Security", "CS002:SecretInNextLine", Justification="Endpoint code example with no real credentials.")]
- # Create the JSON object. It should look like '{"endpointCredentials": [{"endpoint":"http://example.index.json", "username":"optional", "password":"accesstoken"}]}'
$endpointCredentials = @{endpointCredentials=$endpoints} | ConvertTo-Json -Compress
# Create the environment variables the AzDo way
diff --git a/eng/common/internal-feed-operations.sh b/eng/common/internal-feed-operations.sh
index a27410f6321..e2233e78122 100755
--- a/eng/common/internal-feed-operations.sh
+++ b/eng/common/internal-feed-operations.sh
@@ -62,8 +62,6 @@ function SetupCredProvider {
endpoints+=']'
if [ ${#endpoints} -gt 2 ]; then
- # [SuppressMessage("Microsoft.Security", "CS002:SecretInNextLine", Justification="Endpoint code example with no real credentials.")]
- # Create the JSON object. It should look like '{"endpointCredentials": [{"endpoint":"http://example.index.json", "username":"optional", "password":"accesstoken"}]}'
local endpointCredentials="{\"endpointCredentials\": "$endpoints"}"
echo "##vso[task.setvariable variable=VSS_NUGET_EXTERNAL_FEED_ENDPOINTS]$endpointCredentials"
diff --git a/eng/common/sdl/init-sdl.ps1 b/eng/common/sdl/init-sdl.ps1
index a68bf0b88ea..bb6a4297110 100644
--- a/eng/common/sdl/init-sdl.ps1
+++ b/eng/common/sdl/init-sdl.ps1
@@ -29,18 +29,7 @@ $zipFile = "$WorkingDirectory/gdn.zip"
Add-Type -AssemblyName System.IO.Compression.FileSystem
$gdnFolder = (Join-Path $WorkingDirectory '.gdn')
-try {
- # We try to download the zip; if the request fails (e.g. the file doesn't exist), we catch it and init guardian instead
- Write-Host 'Downloading gdn folder from internal config repostiory...'
- Invoke-WebRequest -Headers @{ "Accept"="application/zip"; "Authorization"="Basic $encodedPat" } -Uri $uri -OutFile $zipFile
- if (Test-Path $gdnFolder) {
- # Remove the gdn folder if it exists (it shouldn't unless there's too much caching; this is just in case)
- Remove-Item -Force -Recurse $gdnFolder
- }
- [System.IO.Compression.ZipFile]::ExtractToDirectory($zipFile, $WorkingDirectory)
- Write-Host $gdnFolder
- ExitWithExitCode 0
-} catch [System.Net.WebException] { } # Catch and ignore webexception
+
try {
# if the folder does not exist, we'll do a guardian init and push it to the remote repository
Write-Host 'Initializing Guardian...'
diff --git a/eng/common/templates/post-build/post-build.yml b/eng/common/templates/post-build/post-build.yml
index 375e91acdf3..b9aa5b6052c 100644
--- a/eng/common/templates/post-build/post-build.yml
+++ b/eng/common/templates/post-build/post-build.yml
@@ -61,6 +61,7 @@ parameters:
VS167ChannelId: 1011
VS168ChannelId: 1154
VSMasterChannelId: 1012
+ VS169ChannelId: 1473
stages:
- ${{ if or(and(le(parameters.publishingInfraVersion, 2), eq(parameters.inline, 'true')), eq( parameters.enableNugetValidation, 'true'), eq(parameters.enableSigningValidation, 'true'), eq(parameters.enableSourceLinkValidation, 'true'), eq(parameters.SDLValidationParameters.enable, 'true')) }}:
@@ -90,7 +91,7 @@ stages:
inputs:
filePath: $(Build.SourcesDirectory)/eng/common/post-build/check-channel-consistency.ps1
arguments: -PromoteToChannels "$(TargetChannels)"
- -AvailableChannelIds ${{parameters.NetEngLatestChannelId}},${{parameters.NetEngValidationChannelId}},${{parameters.NetDev5ChannelId}},${{parameters.NetDev6ChannelId}},${{parameters.GeneralTestingChannelId}},${{parameters.NETCoreToolingDevChannelId}},${{parameters.NETCoreToolingReleaseChannelId}},${{parameters.NETInternalToolingChannelId}},${{parameters.NETCoreExperimentalChannelId}},${{parameters.NetEngServicesIntChannelId}},${{parameters.NetEngServicesProdChannelId}},${{parameters.NetCoreSDK313xxChannelId}},${{parameters.NetCoreSDK313xxInternalChannelId}},${{parameters.NetCoreSDK314xxChannelId}},${{parameters.NetCoreSDK314xxInternalChannelId}},${{parameters.VS166ChannelId}},${{parameters.VS167ChannelId}},${{parameters.VS168ChannelId}},${{parameters.VSMasterChannelId}}
+ -AvailableChannelIds ${{parameters.NetEngLatestChannelId}},${{parameters.NetEngValidationChannelId}},${{parameters.NetDev5ChannelId}},${{parameters.NetDev6ChannelId}},${{parameters.GeneralTestingChannelId}},${{parameters.NETCoreToolingDevChannelId}},${{parameters.NETCoreToolingReleaseChannelId}},${{parameters.NETInternalToolingChannelId}},${{parameters.NETCoreExperimentalChannelId}},${{parameters.NetEngServicesIntChannelId}},${{parameters.NetEngServicesProdChannelId}},${{parameters.NetCoreSDK313xxChannelId}},${{parameters.NetCoreSDK313xxInternalChannelId}},${{parameters.NetCoreSDK314xxChannelId}},${{parameters.NetCoreSDK314xxInternalChannelId}},${{parameters.VS166ChannelId}},${{parameters.VS167ChannelId}},${{parameters.VS168ChannelId}},${{parameters.VSMasterChannelId}},${{parameters.VS169ChannelId}}
- job:
displayName: NuGet Validation
@@ -552,3 +553,18 @@ stages:
transportFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools-transport/nuget/v3/index.json'
shippingFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools/nuget/v3/index.json'
symbolsFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools-symbols/nuget/v3/index.json'
+
+ - template: \eng\common\templates\post-build\channels\generic-public-channel.yml
+ parameters:
+ BARBuildId: ${{ parameters.BARBuildId }}
+ PromoteToChannelIds: ${{ parameters.PromoteToChannelIds }}
+ artifactsPublishingAdditionalParameters: ${{ parameters.artifactsPublishingAdditionalParameters }}
+ dependsOn: ${{ parameters.publishDependsOn }}
+ publishInstallersAndChecksums: ${{ parameters.publishInstallersAndChecksums }}
+ symbolPublishingAdditionalParameters: ${{ parameters.symbolPublishingAdditionalParameters }}
+ stageName: 'VS_16_9_Publishing'
+ channelName: 'VS 16.9'
+ channelId: ${{ parameters.VS169ChannelId }}
+ transportFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools-transport/nuget/v3/index.json'
+ shippingFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools/nuget/v3/index.json'
+ symbolsFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools-symbols/nuget/v3/index.json'
diff --git a/global.json b/global.json
index 8b1cead1aea..4d5a9337911 100644
--- a/global.json
+++ b/global.json
@@ -13,7 +13,7 @@
}
},
"msbuild-sdks": {
- "Microsoft.DotNet.Arcade.Sdk": "6.0.0-beta.21072.6",
+ "Microsoft.DotNet.Arcade.Sdk": "6.0.0-beta.21081.1",
"Microsoft.DotNet.Helix.Sdk": "2.0.0-beta.19069.2"
}
}
diff --git a/src/buildtools/fslex/Arg.fs b/src/buildtools/fslex/Arg.fs
index a1f63bd9638..b1131625cf3 100644
--- a/src/buildtools/fslex/Arg.fs
+++ b/src/buildtools/fslex/Arg.fs
@@ -52,13 +52,13 @@ type ArgParser() =
sbuf.ToString()
- static member ParsePartial(cursor,argv,argSpecs:seq,?other,?usageText) =
- let other = defaultArg other (fun _ -> ())
+ static member ParsePartial(cursor,argv,arguments:seq,?otherArgs,?usageText) =
+ let otherArgs = defaultArg otherArgs (fun _ -> ())
let usageText = defaultArg usageText ""
let nargs = Array.length argv
incr cursor;
- let argSpecs = argSpecs |> Seq.toList
- let specs = argSpecs |> List.map (fun (arg:ArgInfo) -> arg.Name, arg.ArgType)
+ let arguments = arguments |> Seq.toList
+ let specs = arguments |> List.map (fun (arg:ArgInfo) -> arg.Name, arg.ArgType)
while !cursor < nargs do
let arg = argv.[!cursor]
let rec findMatchingArg args =
@@ -66,7 +66,7 @@ type ArgParser() =
| ((s, action) :: _) when s = arg ->
let getSecondArg () =
if !cursor + 1 >= nargs then
- raise(Bad("option "+s+" needs an argument.\n"+getUsage argSpecs usageText));
+ raise(Bad("option "+s+" needs an argument.\n"+getUsage arguments usageText));
argv.[!cursor+1]
match action with
@@ -85,12 +85,12 @@ type ArgParser() =
cursor := !cursor + 2
| IntArg f ->
let arg2 = getSecondArg ()
- let arg2 = try int32 arg2 with _ -> raise(Bad(getUsage argSpecs usageText)) in
+ let arg2 = try int32 arg2 with _ -> raise(Bad(getUsage arguments usageText)) in
f arg2;
cursor := !cursor + 2;
| FloatArg f ->
let arg2 = getSecondArg()
- let arg2 = try float arg2 with _ -> raise(Bad(getUsage argSpecs usageText)) in
+ let arg2 = try float arg2 with _ -> raise(Bad(getUsage arguments usageText)) in
f arg2;
cursor := !cursor + 2;
| RestArg f ->
@@ -102,26 +102,26 @@ type ArgParser() =
| (_ :: more) -> findMatchingArg more
| [] ->
if arg = "-help" || arg = "--help" || arg = "/help" || arg = "/help" || arg = "/?" then
- raise (HelpText (getUsage argSpecs usageText))
+ raise (HelpText (getUsage arguments usageText))
// Note: for '/abc/def' does not count as an argument
// Note: '/abc' does
elif arg.Length>0 && (arg.[0] = '-' || (arg.[0] = '/' && not (arg.Length > 1 && arg.[1..].Contains ("/")))) then
- raise (Bad ("unrecognized argument: "+ arg + "\n" + getUsage argSpecs usageText))
+ raise (Bad ("unrecognized argument: "+ arg + "\n" + getUsage arguments usageText))
else
- other arg;
+ otherArgs arg;
incr cursor
findMatchingArg specs
- static member Usage (specs,?usage) =
+ static member Usage (arguments,?usage) =
let usage = defaultArg usage ""
- System.Console.Error.WriteLine (getUsage (Seq.toList specs) usage)
+ System.Console.Error.WriteLine (getUsage (Seq.toList arguments) usage)
#if FX_NO_COMMAND_LINE_ARGS
#else
- static member Parse (specs,?other,?usageText) =
+ static member Parse (arguments,?otherArgs,?usageText) =
let current = ref 0
let argv = System.Environment.GetCommandLineArgs()
- try ArgParser.ParsePartial (current, argv, specs, ?other=other, ?usageText=usageText)
+ try ArgParser.ParsePartial (current, argv, arguments, ?otherArgs=otherArgs, ?usageText=usageText)
with
| Bad h
| HelpText h ->
diff --git a/src/buildtools/fslex/Parsing.fsi b/src/buildtools/fslex/Parsing.fsi
index 2fef45975a8..f4d12606462 100644
--- a/src/buildtools/fslex/Parsing.fsi
+++ b/src/buildtools/fslex/Parsing.fsi
@@ -100,7 +100,7 @@ type Tables<'tok> =
/// Interpret the parser table taking input from the given lexer, using the given lex buffer, and the given start state.
/// Returns an object indicating the final synthesized value for the parse.
- member Interpret : lexer:(LexBuffer<'char> -> 'tok) * lexbuf:LexBuffer<'char> * startState:int -> obj
+ member Interpret : lexer:(LexBuffer<'char> -> 'tok) * lexbuf:LexBuffer<'char> * initialState:int -> obj
#if INTERNALIZED_FSLEXYACC_RUNTIME
exception internal Accept of obj
diff --git a/src/buildtools/fsyacc/Arg.fs b/src/buildtools/fsyacc/Arg.fs
index a1f63bd9638..b1131625cf3 100644
--- a/src/buildtools/fsyacc/Arg.fs
+++ b/src/buildtools/fsyacc/Arg.fs
@@ -52,13 +52,13 @@ type ArgParser() =
sbuf.ToString()
- static member ParsePartial(cursor,argv,argSpecs:seq,?other,?usageText) =
- let other = defaultArg other (fun _ -> ())
+ static member ParsePartial(cursor,argv,arguments:seq,?otherArgs,?usageText) =
+ let otherArgs = defaultArg otherArgs (fun _ -> ())
let usageText = defaultArg usageText ""
let nargs = Array.length argv
incr cursor;
- let argSpecs = argSpecs |> Seq.toList
- let specs = argSpecs |> List.map (fun (arg:ArgInfo) -> arg.Name, arg.ArgType)
+ let arguments = arguments |> Seq.toList
+ let specs = arguments |> List.map (fun (arg:ArgInfo) -> arg.Name, arg.ArgType)
while !cursor < nargs do
let arg = argv.[!cursor]
let rec findMatchingArg args =
@@ -66,7 +66,7 @@ type ArgParser() =
| ((s, action) :: _) when s = arg ->
let getSecondArg () =
if !cursor + 1 >= nargs then
- raise(Bad("option "+s+" needs an argument.\n"+getUsage argSpecs usageText));
+ raise(Bad("option "+s+" needs an argument.\n"+getUsage arguments usageText));
argv.[!cursor+1]
match action with
@@ -85,12 +85,12 @@ type ArgParser() =
cursor := !cursor + 2
| IntArg f ->
let arg2 = getSecondArg ()
- let arg2 = try int32 arg2 with _ -> raise(Bad(getUsage argSpecs usageText)) in
+ let arg2 = try int32 arg2 with _ -> raise(Bad(getUsage arguments usageText)) in
f arg2;
cursor := !cursor + 2;
| FloatArg f ->
let arg2 = getSecondArg()
- let arg2 = try float arg2 with _ -> raise(Bad(getUsage argSpecs usageText)) in
+ let arg2 = try float arg2 with _ -> raise(Bad(getUsage arguments usageText)) in
f arg2;
cursor := !cursor + 2;
| RestArg f ->
@@ -102,26 +102,26 @@ type ArgParser() =
| (_ :: more) -> findMatchingArg more
| [] ->
if arg = "-help" || arg = "--help" || arg = "/help" || arg = "/help" || arg = "/?" then
- raise (HelpText (getUsage argSpecs usageText))
+ raise (HelpText (getUsage arguments usageText))
// Note: for '/abc/def' does not count as an argument
// Note: '/abc' does
elif arg.Length>0 && (arg.[0] = '-' || (arg.[0] = '/' && not (arg.Length > 1 && arg.[1..].Contains ("/")))) then
- raise (Bad ("unrecognized argument: "+ arg + "\n" + getUsage argSpecs usageText))
+ raise (Bad ("unrecognized argument: "+ arg + "\n" + getUsage arguments usageText))
else
- other arg;
+ otherArgs arg;
incr cursor
findMatchingArg specs
- static member Usage (specs,?usage) =
+ static member Usage (arguments,?usage) =
let usage = defaultArg usage ""
- System.Console.Error.WriteLine (getUsage (Seq.toList specs) usage)
+ System.Console.Error.WriteLine (getUsage (Seq.toList arguments) usage)
#if FX_NO_COMMAND_LINE_ARGS
#else
- static member Parse (specs,?other,?usageText) =
+ static member Parse (arguments,?otherArgs,?usageText) =
let current = ref 0
let argv = System.Environment.GetCommandLineArgs()
- try ArgParser.ParsePartial (current, argv, specs, ?other=other, ?usageText=usageText)
+ try ArgParser.ParsePartial (current, argv, arguments, ?otherArgs=otherArgs, ?usageText=usageText)
with
| Bad h
| HelpText h ->
diff --git a/src/buildtools/fsyacc/Parsing.fsi b/src/buildtools/fsyacc/Parsing.fsi
index 2fef45975a8..f4d12606462 100644
--- a/src/buildtools/fsyacc/Parsing.fsi
+++ b/src/buildtools/fsyacc/Parsing.fsi
@@ -100,7 +100,7 @@ type Tables<'tok> =
/// Interpret the parser table taking input from the given lexer, using the given lex buffer, and the given start state.
/// Returns an object indicating the final synthesized value for the parse.
- member Interpret : lexer:(LexBuffer<'char> -> 'tok) * lexbuf:LexBuffer<'char> * startState:int -> obj
+ member Interpret : lexer:(LexBuffer<'char> -> 'tok) * lexbuf:LexBuffer<'char> * initialState:int -> obj
#if INTERNALIZED_FSLEXYACC_RUNTIME
exception internal Accept of obj
diff --git a/src/fsharp/CheckComputationExpressions.fs b/src/fsharp/CheckComputationExpressions.fs
index 3383ca42585..bb55978424a 100644
--- a/src/fsharp/CheckComputationExpressions.fs
+++ b/src/fsharp/CheckComputationExpressions.fs
@@ -1918,7 +1918,7 @@ let TcArrayOrListSequenceExpression (cenv: cenv) env overallTy tpenv (isArray, c
if nelems > 0 && List.forall (function SynExpr.Const (SynConst.UInt16 _, _) -> true | _ -> false) elems
then SynExpr.Const (SynConst.UInt16s (Array.ofList (List.map (function SynExpr.Const (SynConst.UInt16 x, _) -> x | _ -> failwith "unreachable") elems)), m)
elif nelems > 0 && List.forall (function SynExpr.Const (SynConst.Byte _, _) -> true | _ -> false) elems
- then SynExpr.Const (SynConst.Bytes (Array.ofList (List.map (function SynExpr.Const (SynConst.Byte x, _) -> x | _ -> failwith "unreachable") elems), m), m)
+ then SynExpr.Const (SynConst.Bytes (Array.ofList (List.map (function SynExpr.Const (SynConst.Byte x, _) -> x | _ -> failwith "unreachable") elems), SynByteStringKind.Regular, m), m)
else SynExpr.ArrayOrList (isArray, elems, m)
else
if elems.Length > 500 then
diff --git a/src/fsharp/CheckDeclarations.fs b/src/fsharp/CheckDeclarations.fs
index 6d2d38ef198..7ef13ee1000 100644
--- a/src/fsharp/CheckDeclarations.fs
+++ b/src/fsharp/CheckDeclarations.fs
@@ -3165,7 +3165,7 @@ module EstablishTypeDefinitionCores =
[ for def in defs do
match def with
| SynModuleDecl.Types (typeSpecs, _) ->
- for (TypeDefn(ComponentInfo(_, typars, _, ids, _, _, _, _), trepr, _, _)) in typeSpecs do
+ for (TypeDefn(ComponentInfo(_, typars, _, ids, _, _, _, _), trepr, _, _, _)) in typeSpecs do
if isNil typars then
match trepr with
| SynTypeDefnRepr.ObjectModel(TyconAugmentation, _, _) -> ()
@@ -4642,7 +4642,7 @@ module TcDeclarations =
/// where simpleRepr can contain inherit type, declared fields and virtual slots.
/// body = members
/// where members contain methods/overrides, also implicit ctor, inheritCall and local definitions.
- let rec private SplitTyconDefn (TypeDefn(synTyconInfo, trepr, extraMembers, _)) =
+ let rec private SplitTyconDefn (TypeDefn(synTyconInfo, trepr, extraMembers, _, _)) =
let implements1 = List.choose (function SynMemberDefn.Interface (ty, _, _) -> Some(ty, ty.Range) | _ -> None) extraMembers
match trepr with
| SynTypeDefnRepr.ObjectModel(kind, cspec, m) ->
@@ -5528,7 +5528,7 @@ and TcModuleOrNamespaceElementsMutRec (cenv: cenv) parent typeNames m envInitial
| SynModuleDecl.Exception (SynExceptionDefn(repr, members, _), _m) ->
let (SynExceptionDefnRepr(synAttrs, UnionCase(_, id, _args, _, _, _), _repr, doc, vis, m)) = repr
let compInfo = ComponentInfo(synAttrs, [], [], [id], doc, false, vis, id.idRange)
- let decls = [ MutRecShape.Tycon(SynTypeDefn.TypeDefn(compInfo, SynTypeDefnRepr.Exception repr, members, m)) ]
+ let decls = [ MutRecShape.Tycon(SynTypeDefn.TypeDefn(compInfo, SynTypeDefnRepr.Exception repr, members, None, m)) ]
decls, (false, false, attrs)
| SynModuleDecl.HashDirective _ ->
diff --git a/src/fsharp/CheckExpressions.fs b/src/fsharp/CheckExpressions.fs
index d6abb2ebb64..8c960a1de2e 100644
--- a/src/fsharp/CheckExpressions.fs
+++ b/src/fsharp/CheckExpressions.fs
@@ -853,7 +853,7 @@ let TcConst cenv (overallTy: TType) m env c =
| SynConst.Measure(SynConst.UInt64 i, _) when expandedMeasurablesEnabled -> unifyMeasureArg (i=0UL) cenv.g.puint64_tcr c; Const.UInt64 i
| SynConst.Measure(SynConst.UIntPtr i, _) when expandedMeasurablesEnabled -> unifyMeasureArg (i=0UL) cenv.g.punativeint_tcr c; Const.UIntPtr i
| SynConst.Char c -> unif cenv.g.char_ty; Const.Char c
- | SynConst.String (s, _) -> unif cenv.g.string_ty; Const.String s
+ | SynConst.String (s, _, _) -> unif cenv.g.string_ty; Const.String s
| SynConst.UserNum _ -> error (InternalError(FSComp.SR.tcUnexpectedBigRationalConstant(), m))
| SynConst.Measure _ -> error (Error(FSComp.SR.tcInvalidTypeForUnitsOfMeasure(), m))
| SynConst.UInt16s _ -> error (InternalError(FSComp.SR.tcUnexpectedConstUint16Array(), m))
@@ -4457,7 +4457,7 @@ and TcStaticConstantParameter cenv (env: TcEnv) tpenv kind (StripParenTypes v) i
| SynConst.Single n when typeEquiv g g.float32_ty kind -> record(g.float32_ty); box (n: single)
| SynConst.Double n when typeEquiv g g.float_ty kind -> record(g.float_ty); box (n: double)
| SynConst.Char n when typeEquiv g g.char_ty kind -> record(g.char_ty); box (n: char)
- | SynConst.String (s, _) when s <> null && typeEquiv g g.string_ty kind -> record(g.string_ty); box (s: string)
+ | SynConst.String (s, _, _) when s <> null && typeEquiv g g.string_ty kind -> record(g.string_ty); box (s: string)
| SynConst.Bool b when typeEquiv g g.bool_ty kind -> record(g.bool_ty); box (b: bool)
| _ -> fail()
v, tpenv
@@ -4837,7 +4837,7 @@ and TcPat warnOnUpper cenv env topValInfo vFlags (tpenv, names, takenNames) ty p
match pat with
| SynPat.Const (c, m) ->
match c with
- | SynConst.Bytes (bytes, m) ->
+ | SynConst.Bytes (bytes, _, m) ->
UnifyTypes cenv env m ty (mkByteArrayTy cenv.g)
TcPat warnOnUpper cenv env None vFlags (tpenv, names, takenNames) ty (SynPat.ArrayOrList (true, [ for b in bytes -> SynPat.Const(SynConst.Byte b, m) ], m))
@@ -5513,11 +5513,11 @@ and TcExprUndelayed cenv (overallTy: OverallTy) env tpenv (synExpr: SynExpr) =
| SynExpr.DotIndexedGet _ | SynExpr.DotIndexedSet _
| SynExpr.TypeApp _ | SynExpr.Ident _ | SynExpr.LongIdent _ | SynExpr.App _ | SynExpr.DotGet _ -> error(Error(FSComp.SR.tcExprUndelayed(), synExpr.Range))
- | SynExpr.Const (SynConst.String (s, m), _mWholeExpr) ->
+ | SynExpr.Const (SynConst.String (s, _, m), _) ->
CallExprHasTypeSink cenv.tcSink (m, env.NameEnv, overallTy.Commit, env.AccessRights)
TcConstStringExpr cenv overallTy env m tpenv s
- | SynExpr.InterpolatedString (parts, m) ->
+ | SynExpr.InterpolatedString (parts, _, m) ->
checkLanguageFeatureError cenv.g.langVersion LanguageFeature.StringInterpolation m
CallExprHasTypeSink cenv.tcSink (m, env.NameEnv, overallTy.Commit, env.AccessRights)
@@ -6921,7 +6921,7 @@ and TcConstExpr cenv (overallTy: OverallTy) env m tpenv c =
match c with
// NOTE: these aren't "really" constants
- | SynConst.Bytes (bytes, m) ->
+ | SynConst.Bytes (bytes, _, m) ->
TcExprLeafProtect cenv overallTy env true m <| fun overallTy ->
UnifyTypes cenv env m overallTy (mkByteArrayTy cenv.g)
Expr.Op (TOp.Bytes bytes, [], [], m), tpenv
@@ -6950,7 +6950,7 @@ and TcConstExpr cenv (overallTy: OverallTy) env m tpenv c =
let i64 = int64 s
SynExpr.App (ExprAtomicFlag.Atomic, false, mkSynLidGet m [modName] "FromInt64", SynExpr.Const (SynConst.Int64 i64, m), m)
with _ ->
- SynExpr.App (ExprAtomicFlag.Atomic, false, mkSynLidGet m [modName] "FromString", SynExpr.Const (SynConst.String (s, m), m), m)
+ SynExpr.App (ExprAtomicFlag.Atomic, false, mkSynLidGet m [modName] "FromString", SynExpr.Const (SynConst.String (s, SynStringKind.Regular, m), m), m)
if suffix <> "I" then
expr
diff --git a/src/fsharp/FxResolver.fs b/src/fsharp/FxResolver.fs
index 665f142b4d0..31e8307c2fb 100644
--- a/src/fsharp/FxResolver.fs
+++ b/src/fsharp/FxResolver.fs
@@ -295,7 +295,6 @@ type internal FxResolver(assumeDotNetFramework: bool option, projectDir: string,
let startPos =
let startPos = file.IndexOf(pattern, StringComparison.OrdinalIgnoreCase)
if startPos >= 0 then startPos + (pattern.Length) else startPos
-
let length =
if startPos >= 0 then
let ep = file.IndexOf("\"", startPos)
@@ -305,16 +304,21 @@ type internal FxResolver(assumeDotNetFramework: bool option, projectDir: string,
| -1, _
| _, -1 ->
if isRunningOnCoreClr then
- // Running on coreclr but no deps.json was deployed with the host so default to 3.1
- Some "netcoreapp3.1"
+ // Running on coreclr but no deps.json was deployed with the host so default to 5.0
+ Some "net5.0"
else
// Running on desktop
None
| pos, length ->
// use value from the deps.json file
- Some ("netcoreapp" + file.Substring(pos, length))
-
- // Tries to figure out the tfm for the compiler instance on the Windows desktop.
+ let suffix = file.Substring(pos, length)
+ let prefix =
+ match Double.TryParse(suffix) with
+ | true, value when value < 5.0 -> "netcoreapp"
+ | _ -> "net"
+ Some (prefix + suffix)
+
+ // Tries to figure out the tfm for the compiler instance on the Windows desktop
// On full clr it uses the mscorlib version number
let getRunningDotNetFrameworkTfm () =
let defaultMscorlibVersion = 4,8,3815,0
diff --git a/src/fsharp/SyntaxTree.fs b/src/fsharp/SyntaxTree.fs
index 568cde006d5..c58276b519b 100644
--- a/src/fsharp/SyntaxTree.fs
+++ b/src/fsharp/SyntaxTree.fs
@@ -81,6 +81,19 @@ type SynTypar =
| Typar(id, _, _) ->
id.idRange
+/// Indicate if the string had a special format
+[]
+type SynStringKind =
+ | Regular
+ | Verbatim
+ | TripleQuote
+
+/// Indicate if the byte string had a special format
+[]
+type SynByteStringKind =
+ | Regular
+ | Verbatim
+
/// The unchecked abstract syntax tree of constants in F# types and expressions.
[]
type SynConst =
@@ -139,13 +152,13 @@ type SynConst =
| UserNum of value: string * suffix: string
/// F# syntax: verbatim or regular string, e.g. "abc"
- | String of text: string * range: range
+ | String of text: string * synStringKind :SynStringKind * range: range
/// F# syntax: verbatim or regular byte string, e.g. "abc"B.
///
/// Also used internally in the typechecker once an array of unit16 constants
/// is detected, to allow more efficient processing of large arrays of uint16 constants.
- | Bytes of bytes: byte[] * range: range
+ | Bytes of bytes: byte[] * synByteStringKind: SynByteStringKind * range: range
/// Used internally in the typechecker once an array of unit16 constants
/// is detected, to allow more efficient processing of large arrays of uint16 constants.
@@ -157,7 +170,7 @@ type SynConst =
/// Gets the syntax range of this construct
member c.Range dflt =
match c with
- | SynConst.String (_, m0) | SynConst.Bytes (_, m0) -> m0
+ | SynConst.String (_, _, m0) | SynConst.Bytes (_, _, m0) -> m0
| _ -> dflt
/// Represents an unchecked syntax tree of F# unit of measure annotations.
@@ -1016,6 +1029,7 @@ type SynExpr =
/// Note the string ranges include the quotes, verbatim markers, dollar sign and braces
| InterpolatedString of
contents: SynInterpolatedStringPart list *
+ synStringKind :SynStringKind *
range: range
/// Gets the syntax range of this construct
@@ -1878,6 +1892,7 @@ type SynTypeDefn =
typeInfo: SynComponentInfo *
typeRepr: SynTypeDefnRepr *
members: SynMemberDefns *
+ implicitConstructor: SynMemberDefn option *
range: range
/// Gets the syntax range of this construct
diff --git a/src/fsharp/SyntaxTreeOps.fs b/src/fsharp/SyntaxTreeOps.fs
index c225b139808..46572b517da 100644
--- a/src/fsharp/SyntaxTreeOps.fs
+++ b/src/fsharp/SyntaxTreeOps.fs
@@ -736,7 +736,7 @@ let rec synExprContainsError inpExpr =
| SynExpr.LetOrUseBang (rhs=e1;body=e2;andBangs=es) ->
walkExpr e1 || walkExprs [ for (_,_,_,_,e,_) in es do yield e ] || walkExpr e2
- | SynExpr.InterpolatedString (parts, _m) ->
+ | SynExpr.InterpolatedString (parts, _, _m) ->
walkExprs
(parts |> List.choose (function
| SynInterpolatedStringPart.String _ -> None
diff --git a/src/fsharp/fsi/fsi.fs b/src/fsharp/fsi/fsi.fs
index 0e9cf33fbee..788c3d006eb 100644
--- a/src/fsharp/fsi/fsi.fs
+++ b/src/fsharp/fsi/fsi.fs
@@ -1880,11 +1880,10 @@ module internal MagicAssemblyResolution =
// Special case: Mono Windows Forms attempts to load an assembly called something like "Windows.Forms.resources"
// We can't resolve this, so don't try.
// REVIEW: Suggest 4481, delete this special case.
- if simpleAssemName.EndsWith(".resources",StringComparison.OrdinalIgnoreCase) ||
- // See F# 1.0 Product Studio bug 1171
- simpleAssemName.EndsWith(".XmlSerializers",StringComparison.OrdinalIgnoreCase) ||
- (runningOnMono && simpleAssemName = "UIAutomationWinforms") then null else
-
+ if (runningOnMono && simpleAssemName.EndsWith(".resources",StringComparison.OrdinalIgnoreCase)) ||
+ simpleAssemName.EndsWith(".XmlSerializers", StringComparison.OrdinalIgnoreCase) ||
+ (runningOnMono && simpleAssemName = "UIAutomationWinforms") then null
+ else
// Special case: Is this the global unique dynamic assembly for FSI code? In this case just
// return the dynamic assembly itself.
if fsiDynamicCompiler.DynamicAssemblyName = simpleAssemName then fsiDynamicCompiler.DynamicAssembly else
diff --git a/src/fsharp/fsi/fsi.fsproj b/src/fsharp/fsi/fsi.fsproj
index 900a5fb4e30..b390ca63921 100644
--- a/src/fsharp/fsi/fsi.fsproj
+++ b/src/fsharp/fsi/fsi.fsproj
@@ -9,7 +9,7 @@
netcoreapp3.1
$(NoWarn);45;55;62;75;1204
true
- --warnon:1182 --maxerrors:20 --extraoptimizationloops:1
+ $(OtherFlags) --warnon:1182 --maxerrors:20 --extraoptimizationloops:1
fsi.res
true
true
diff --git a/src/fsharp/lex.fsl b/src/fsharp/lex.fsl
index 8317f4f5a92..e48cb044552 100644
--- a/src/fsharp/lex.fsl
+++ b/src/fsharp/lex.fsl
@@ -136,25 +136,35 @@ let startString args (lexbuf: UnicodeLexing.Lexbuf) =
let m = lexbuf.LexemeRange
let startp = lexbuf.StartPos
let fin =
- LexerStringFinisher (fun buf kind isPart cont ->
+ LexerStringFinisher (fun buf kind context cont ->
// Adjust the start-of-token mark back to the true start of the token
lexbuf.StartPos <- startp
- if kind.IsByteString then
+ let isPart = context.HasFlag(LexerStringFinisherContext.InterpolatedPart)
+ let isVerbatim = context.HasFlag(LexerStringFinisherContext.Verbatim)
+ let isTripleQuote = context.HasFlag(LexerStringFinisherContext.TripleQuote)
+
+ if kind.IsByteString then
+ let synByteStringKind = if isVerbatim then SynByteStringKind.Verbatim else SynByteStringKind.Regular
if kind.IsInterpolated then
fail args lexbuf (FSComp.SR.lexByteStringMayNotBeInterpolated()) ()
- BYTEARRAY (Lexhelp.stringBufferAsBytes buf, cont)
+ BYTEARRAY (Lexhelp.stringBufferAsBytes buf, synByteStringKind, cont)
elif Lexhelp.stringBufferIsBytes buf then
- BYTEARRAY (Lexhelp.stringBufferAsBytes buf, cont)
+ BYTEARRAY (Lexhelp.stringBufferAsBytes buf, synByteStringKind, cont)
else
fail args lexbuf (FSComp.SR.lexByteArrayCannotEncode()) ()
- BYTEARRAY (Lexhelp.stringBufferAsBytes buf, cont)
+ BYTEARRAY (Lexhelp.stringBufferAsBytes buf, synByteStringKind, cont)
elif kind.IsInterpolated then
let s = Lexhelp.stringBufferAsString buf
- if kind.IsInterpolatedFirst then
+ if kind.IsInterpolatedFirst then
+ let synStringKind =
+ if isTripleQuote then
+ SynStringKind.TripleQuote
+ else
+ SynStringKind.Regular
if isPart then
- INTERP_STRING_BEGIN_PART (s, cont)
+ INTERP_STRING_BEGIN_PART (s, synStringKind, cont)
else
- INTERP_STRING_BEGIN_END (s, cont)
+ INTERP_STRING_BEGIN_END (s, synStringKind, cont)
else
if isPart then
INTERP_STRING_PART (s, cont)
@@ -162,7 +172,14 @@ let startString args (lexbuf: UnicodeLexing.Lexbuf) =
INTERP_STRING_END (s, cont)
else
let s = Lexhelp.stringBufferAsString buf
- STRING (s, cont))
+ let synStringKind =
+ if isVerbatim then
+ SynStringKind.Verbatim
+ elif isTripleQuote then
+ SynStringKind.TripleQuote
+ else
+ SynStringKind.Regular
+ STRING (s, synStringKind, cont))
buf,fin,m
@@ -1124,13 +1141,13 @@ and singleQuoteString sargs skip = parse
| '"'
{ let (buf, fin, _m, kind, args) = sargs
let cont = LexCont.Token(args.ifdefStack, args.stringNest)
- fin.Finish buf kind false cont
+ fin.Finish buf kind (enum(0)) cont
}
| '"''B'
{ let (buf, fin, _m, kind, args) = sargs
let cont = LexCont.Token(args.ifdefStack, args.stringNest)
- fin.Finish buf { kind with IsByteString = true } false cont
+ fin.Finish buf { kind with IsByteString = true } (enum(0)) cont
}
| ("{{" | "}}")
@@ -1147,7 +1164,7 @@ and singleQuoteString sargs skip = parse
let m2 = lexbuf.LexemeRange
args.stringNest <- (1, LexerStringStyle.SingleQuote, m2) :: args.stringNest
let cont = LexCont.Token(args.ifdefStack, args.stringNest)
- fin.Finish buf kind true cont
+ fin.Finish buf kind LexerStringFinisherContext.InterpolatedPart cont
else
addUnicodeString buf (lexeme lexbuf)
if not skip then STRING_TEXT (LexCont.String(args.ifdefStack, args.stringNest, LexerStringStyle.SingleQuote, kind, m))
@@ -1214,13 +1231,13 @@ and verbatimString sargs skip = parse
| '"'
{ let (buf, fin, _m, kind, args) = sargs
let cont = LexCont.Token(args.ifdefStack, args.stringNest)
- fin.Finish buf kind false cont
+ fin.Finish buf kind LexerStringFinisherContext.Verbatim cont
}
| '"''B'
{ let (buf, fin, _m, kind, args) = sargs
let cont = LexCont.Token(args.ifdefStack, args.stringNest)
- fin.Finish buf { kind with IsByteString = true } false cont
+ fin.Finish buf { kind with IsByteString = true } LexerStringFinisherContext.Verbatim cont
}
| newline
@@ -1244,7 +1261,7 @@ and verbatimString sargs skip = parse
let m2 = lexbuf.LexemeRange
args.stringNest <- (1, LexerStringStyle.Verbatim, m2) :: args.stringNest
let cont = LexCont.Token(args.ifdefStack, args.stringNest)
- fin.Finish buf kind true cont
+ fin.Finish buf kind (enum(3)) cont
else
addUnicodeString buf (lexeme lexbuf)
if not skip then STRING_TEXT (LexCont.String(args.ifdefStack, args.stringNest, LexerStringStyle.Verbatim, kind, m))
@@ -1297,7 +1314,7 @@ and tripleQuoteString sargs skip = parse
| '"' '"' '"'
{ let (buf, fin, _m, kind, args) = sargs
let cont = LexCont.Token(args.ifdefStack, args.stringNest)
- fin.Finish buf kind false cont }
+ fin.Finish buf kind (enum(4)) cont }
| newline
{ let (buf, _fin, m, kind, args) = sargs
@@ -1340,7 +1357,7 @@ and tripleQuoteString sargs skip = parse
let m2 = lexbuf.LexemeRange
args.stringNest <- (1, LexerStringStyle.TripleQuote, m2) :: args.stringNest
let cont = LexCont.Token(args.ifdefStack, args.stringNest)
- fin.Finish buf kind true cont
+ fin.Finish buf kind (enum(5)) cont
else
addUnicodeString buf (lexeme lexbuf)
if not skip then STRING_TEXT (LexCont.String(args.ifdefStack, args.stringNest, LexerStringStyle.TripleQuote, kind, m))
diff --git a/src/fsharp/lexhelp.fs b/src/fsharp/lexhelp.fs
index 767dcae116f..fe86184e0eb 100644
--- a/src/fsharp/lexhelp.fs
+++ b/src/fsharp/lexhelp.fs
@@ -18,6 +18,7 @@ open FSharp.Compiler.SourceCodeServices
open FSharp.Compiler.SourceCodeServices.PrettyNaming
open FSharp.Compiler.Text
open FSharp.Compiler.Text.Range
+open FSharp.Compiler.SyntaxTree
/// The "mock" filename used by fsi.exe when reading from stdin.
/// Has special treatment by the lexer, i.e. __SOURCE_DIRECTORY__ becomes GetCurrentDirectory()
@@ -119,31 +120,54 @@ let stringBufferAsBytes (buf: ByteBuffer) =
let bytes = buf.Close()
Array.init (bytes.Length / 2) (fun i -> bytes.[i*2])
+[]
+type LexerStringFinisherContext =
+ | InterpolatedPart = 1
+ | Verbatim = 2
+ | TripleQuote = 4
+
type LexerStringFinisher =
- | LexerStringFinisher of (ByteBuffer -> LexerStringKind -> bool -> LexerContinuation -> token)
+ | LexerStringFinisher of (ByteBuffer -> LexerStringKind -> LexerStringFinisherContext -> LexerContinuation -> token)
- member fin.Finish (buf: ByteBuffer) kind isInterpolatedStringPart cont =
+ member fin.Finish (buf: ByteBuffer) kind context cont =
let (LexerStringFinisher f) = fin
- f buf kind isInterpolatedStringPart cont
+ f buf kind context cont
static member Default =
- LexerStringFinisher (fun buf kind isPart cont ->
+ LexerStringFinisher (fun buf kind context cont ->
+ let isPart = context.HasFlag(LexerStringFinisherContext.InterpolatedPart)
+ let isVerbatim = context.HasFlag(LexerStringFinisherContext.Verbatim)
+ let isTripleQuote = context.HasFlag(LexerStringFinisherContext.TripleQuote)
+
if kind.IsInterpolated then
let s = stringBufferAsString buf
- if kind.IsInterpolatedFirst then
+ if kind.IsInterpolatedFirst then
+ let synStringKind =
+ if isTripleQuote then
+ SynStringKind.TripleQuote
+ else
+ SynStringKind.Regular
if isPart then
- INTERP_STRING_BEGIN_PART (s, cont)
+ INTERP_STRING_BEGIN_PART (s, synStringKind, cont)
else
- INTERP_STRING_BEGIN_END (s, cont)
+ INTERP_STRING_BEGIN_END (s, synStringKind, cont)
else
if isPart then
INTERP_STRING_PART (s, cont)
else
INTERP_STRING_END (s, cont)
- elif kind.IsByteString then
- BYTEARRAY (stringBufferAsBytes buf, cont)
+ elif kind.IsByteString then
+ let synByteStringKind = if isVerbatim then SynByteStringKind.Verbatim else SynByteStringKind.Regular
+ BYTEARRAY (stringBufferAsBytes buf, synByteStringKind, cont)
else
- STRING (stringBufferAsString buf, cont)
+ let synStringKind =
+ if isVerbatim then
+ SynStringKind.Verbatim
+ elif isTripleQuote then
+ SynStringKind.TripleQuote
+ else
+ SynStringKind.Regular
+ STRING (stringBufferAsString buf, synStringKind, cont)
)
let addUnicodeString (buf: ByteBuffer) (x:string) =
diff --git a/src/fsharp/lexhelp.fsi b/src/fsharp/lexhelp.fsi
index f7cf0b25d6d..e3f1053fb24 100644
--- a/src/fsharp/lexhelp.fsi
+++ b/src/fsharp/lexhelp.fsi
@@ -54,10 +54,15 @@ val reusingLexbufForParsing: UnicodeLexing.Lexbuf -> (unit -> 'a) -> 'a
val usingLexbufForParsing: UnicodeLexing.Lexbuf * string -> (UnicodeLexing.Lexbuf -> 'a) -> 'a
+type LexerStringFinisherContext =
+ | InterpolatedPart = 1
+ | Verbatim = 2
+ | TripleQuote = 4
+
type LexerStringFinisher =
- | LexerStringFinisher of (ByteBuffer -> LexerStringKind -> bool -> LexerContinuation -> token)
+ | LexerStringFinisher of (ByteBuffer -> LexerStringKind -> LexerStringFinisherContext -> LexerContinuation -> token)
- member Finish: buf: ByteBuffer -> kind: LexerStringKind -> isInterpolatedStringPart: bool -> cont: LexerContinuation -> token
+ member Finish: buf: ByteBuffer -> kind: LexerStringKind -> context: LexerStringFinisherContext -> cont: LexerContinuation -> token
static member Default: LexerStringFinisher
diff --git a/src/fsharp/pars.fsy b/src/fsharp/pars.fsy
index a00c45c9274..2d6a82852dc 100644
--- a/src/fsharp/pars.fsy
+++ b/src/fsharp/pars.fsy
@@ -195,10 +195,10 @@ let rangeOfLongIdent(lid:LongIdent) =
%}
// Producing these changes the lex state, e.g. string --> token, or nesting level of braces in interpolated strings
-%token BYTEARRAY
-%token STRING
-%token INTERP_STRING_BEGIN_END
-%token INTERP_STRING_BEGIN_PART
+%token BYTEARRAY
+%token STRING
+%token INTERP_STRING_BEGIN_END
+%token INTERP_STRING_BEGIN_PART
%token INTERP_STRING_PART
%token INTERP_STRING_END
%token LBRACE RBRACE
@@ -647,7 +647,8 @@ hashDirectiveArgs:
/* One argument to a #directive */
hashDirectiveArg:
| stringOrKeywordString
- { $1 }
+ { let s, _ = $1
+ s }
/*--------------------------------------------------------------------------*/
@@ -1271,8 +1272,8 @@ moduleDefn:
/* 'type' definitions */
| opt_attributes opt_declVisibility typeKeyword tyconDefn tyconDefnList
{ if Option.isSome $2 then errorR(Error(FSComp.SR.parsVisibilityDeclarationsShouldComePriorToIdentifier(), rhs parseState 2))
- let (TypeDefn(ComponentInfo(cas, a, cs, b, c, d, d2, d3), e, f, g)) = $4
- let tc = (TypeDefn(ComponentInfo($1@cas, a, cs, b, c, d, d2, d3), e, f, g))
+ let (TypeDefn(ComponentInfo(cas, a, cs, b, c, d, d2, d3), e, f, g, h)) = $4
+ let tc = (TypeDefn(ComponentInfo($1@cas, a, cs, b, c, d, d2, d3), e, f, g, h))
let types = tc :: $5
[ SynModuleDecl.Types(types, (rhs parseState 3, types) ||> unionRangeWithListBy (fun t -> t.Range) ) ] }
@@ -1499,7 +1500,7 @@ tyconDefnList:
/* A type definition */
tyconDefn:
| typeNameInfo
- { TypeDefn($1, SynTypeDefnRepr.Simple(SynTypeDefnSimpleRepr.None($1.Range), $1.Range), [], $1.Range) }
+ { TypeDefn($1, SynTypeDefnRepr.Simple(SynTypeDefnSimpleRepr.None($1.Range), $1.Range), [], None, $1.Range) }
| typeNameInfo opt_equals tyconDefnRhsBlock
{ if not $2 then (
@@ -1512,11 +1513,11 @@ tyconDefn:
let (tcDefRepr:SynTypeDefnRepr), members = $3 nameRange
let declRange = unionRanges (rhs parseState 1) tcDefRepr.Range
let mWhole = (declRange, members) ||> unionRangeWithListBy (fun (mem:SynMemberDefn) -> mem.Range)
- TypeDefn($1, tcDefRepr, members, mWhole) }
+ TypeDefn($1, tcDefRepr, members, None, mWhole) }
| typeNameInfo tyconDefnAugmentation
{ let m = (rhs parseState 1, $2) ||> unionRangeWithListBy (fun mem -> mem.Range)
- TypeDefn($1, SynTypeDefnRepr.ObjectModel(TyconAugmentation, [], m), $2, m) }
+ TypeDefn($1, SynTypeDefnRepr.ObjectModel(TyconAugmentation, [], m), $2, None, m) }
| typeNameInfo opt_attributes opt_declVisibility opt_HIGH_PRECEDENCE_APP simplePatterns optAsSpec EQUALS tyconDefnRhsBlock
{ let vis, spats, az = $3, $5, $6
@@ -1533,7 +1534,7 @@ tyconDefn:
let declRange = unionRanges (rhs parseState 1) tcDefRepr.Range
let mWhole = (declRange, members) ||> unionRangeWithListBy (fun (mem:SynMemberDefn) -> mem.Range)
- TypeDefn($1, tcDefRepr, members, mWhole) }
+ TypeDefn($1, tcDefRepr, members, Some memberCtorPattern, mWhole) }
/* The right-hand-side of a type definition */
@@ -2239,8 +2240,9 @@ braceBarFieldDeclListCore:
inlineAssemblyTyconRepr:
| HASH stringOrKeywordString HASH
{ libraryOnlyError (lhs parseState)
- let lhsm = lhs parseState
- let ilType = ParseAssemblyCodeType $2 parseState.LexBuffer.SupportsFeature (rhs parseState 2)
+ let lhsm = lhs parseState
+ let s, _ = $2
+ let ilType = ParseAssemblyCodeType s parseState.LexBuffer.SupportsFeature (rhs parseState 2)
SynTypeDefnSimpleRepr.LibraryOnlyILAssembly (box ilType, lhsm) }
classOrInterfaceOrStruct:
@@ -2665,7 +2667,7 @@ cPrototype:
let rhsExpr = SynExpr.App (ExprAtomicFlag.NonAtomic,
false,
SynExpr.Ident (ident("failwith", rhs parseState 6)),
- SynExpr.Const (SynConst.String("extern was not given a DllImport attribute", rhs parseState 8), rhs parseState 8),
+ SynExpr.Const (SynConst.String("extern was not given a DllImport attribute", SynStringKind.Regular, rhs parseState 8), rhs parseState 8),
mRhs)
(fun attrs _ ->
let bindingId = SynPat.LongIdent (LongIdentWithDots([nm], []), None, Some noInferredTypars, SynArgPats.Pats [SynPat.Tuple(false, args, argsm)], vis, nmm)
@@ -2909,10 +2911,12 @@ rawConstant:
{ SynConst.UserNum $1 }
| stringOrKeywordString
- { SynConst.String ($1, lhs parseState) }
+ { let s, synStringKind = $1
+ SynConst.String (s, synStringKind, lhs parseState) }
| BYTEARRAY
- { SynConst.Bytes (fst $1, lhs parseState) }
+ { let (v, synByteStringKind, _) = $1
+ SynConst.Bytes (v, synByteStringKind, lhs parseState) }
rationalConstant:
| INT32 INFIX_STAR_DIV_MOD_OP INT32
@@ -3851,7 +3855,7 @@ declExpr:
dynamicArg:
| IDENT
- { let con = SynConst.String ($1, rhs parseState 1)
+ { let con = SynConst.String ($1, SynStringKind.Regular, rhs parseState 1)
let arg2 = SynExpr.Const (con, con.Range (rhs parseState 1))
arg2 }
@@ -4246,7 +4250,8 @@ atomicExprAfterType:
{ $1 }
| interpolatedString
- { SynExpr.InterpolatedString($1, rhs parseState 1) }
+ { let parts, synStringKind = $1
+ SynExpr.InterpolatedString(parts, synStringKind, rhs parseState 1) }
| NULL
{ SynExpr.Null (lhs parseState) }
@@ -4491,7 +4496,7 @@ forLoopDirection:
inlineAssemblyExpr:
| HASH stringOrKeywordString opt_inlineAssemblyTypeArg optCurriedArgExprs optInlineAssemblyReturnTypes HASH
{ libraryOnlyWarning (lhs parseState)
- let s, sm = $2, rhs parseState 2
+ let (s, _), sm = $2, rhs parseState 2
(fun m ->
let ilInstrs = ParseAssemblyCodeInstructions s parseState.LexBuffer.SupportsFeature sm
SynExpr.LibraryOnlyILAssembly (box ilInstrs, $3, List.rev $4, $5, m)) }
@@ -5072,7 +5077,7 @@ atomType:
| NULL
{ let m = rhs parseState 1
- SynType.StaticConstant(SynConst.String (null, m), m) }
+ SynType.StaticConstant(SynConst.String (null, SynStringKind.Regular, m), m) }
| CONST atomicExpr
{ let e, _ = $2
@@ -5528,8 +5533,10 @@ colonOrEquals:
/* A literal string or a string from a keyword like __SOURCE_FILE__ */
stringOrKeywordString:
- | STRING { fst $1 }
- | KEYWORD_STRING { $1 }
+ | STRING
+ { let (s, synStringKind, _) = $1
+ s, synStringKind }
+ | KEYWORD_STRING { $1, SynStringKind.Regular }
interpolatedStringFill:
| declExpr
@@ -5557,17 +5564,20 @@ interpolatedStringParts:
/* INTERP_STRING_BEGIN_PART int32 INTERP_STRING_PART int32 INTERP_STRING_END */
interpolatedString:
| INTERP_STRING_BEGIN_PART interpolatedStringFill interpolatedStringParts
- { SynInterpolatedStringPart.String (fst $1, rhs parseState 1) :: SynInterpolatedStringPart.FillExpr $2 :: $3 }
+ { let s, synStringKind, _ = $1
+ SynInterpolatedStringPart.String (s, rhs parseState 1) :: SynInterpolatedStringPart.FillExpr $2 :: $3, synStringKind }
| INTERP_STRING_BEGIN_END
- { [ SynInterpolatedStringPart.String (fst $1, rhs parseState 1) ] }
+ { let s, synStringKind, _ = $1
+ [ SynInterpolatedStringPart.String (s, rhs parseState 1) ], synStringKind }
| INTERP_STRING_BEGIN_PART interpolatedStringParts
{
+ let s, synStringKind, _ = $1
let rbrace = parseState.InputEndPosition 1
let lbrace = parseState.InputStartPosition 2
reportParseErrorAt (mkSynRange rbrace lbrace) (FSComp.SR.parsEmptyFillInInterpolatedString())
- SynInterpolatedStringPart.String (fst $1, rhs parseState 1) :: $2 }
+ SynInterpolatedStringPart.String (s, rhs parseState 1) :: $2, synStringKind }
opt_HIGH_PRECEDENCE_APP:
| HIGH_PRECEDENCE_BRACK_APP { }
diff --git a/src/fsharp/service/ServiceAssemblyContent.fs b/src/fsharp/service/ServiceAssemblyContent.fs
index 19d32a754bd..376efd25bef 100644
--- a/src/fsharp/service/ServiceAssemblyContent.fs
+++ b/src/fsharp/service/ServiceAssemblyContent.fs
@@ -753,7 +753,7 @@ module ParsedInput =
| SynTypeDefnSigRepr.Simple(defn, _) -> walkTypeDefnSimple defn
| SynTypeDefnSigRepr.Exception _ -> ()
- and walkTypeDefn (TypeDefn (info, repr, members, _)) =
+ and walkTypeDefn (TypeDefn (info, repr, members, _, _)) =
let isTypeExtensionOrAlias =
match repr with
| SynTypeDefnRepr.ObjectModel (SynTypeDefnKind.TyconAugmentation, _, _)
diff --git a/src/fsharp/service/ServiceInterfaceStubGenerator.fs b/src/fsharp/service/ServiceInterfaceStubGenerator.fs
index c4ff4cebd26..1a23f0273fb 100644
--- a/src/fsharp/service/ServiceInterfaceStubGenerator.fs
+++ b/src/fsharp/service/ServiceInterfaceStubGenerator.fs
@@ -702,7 +702,7 @@ module InterfaceStubGenerator =
| SynModuleDecl.Open _ ->
None
- and walkSynTypeDefn(TypeDefn(_componentInfo, representation, members, range)) =
+ and walkSynTypeDefn(TypeDefn(_componentInfo, representation, members, _, range)) =
if not <| rangeContainsPos range pos then
None
else
diff --git a/src/fsharp/service/ServiceLexing.fs b/src/fsharp/service/ServiceLexing.fs
index 2e8931a697e..6747a94ee82 100755
--- a/src/fsharp/service/ServiceLexing.fs
+++ b/src/fsharp/service/ServiceLexing.fs
@@ -24,6 +24,7 @@ open FSharp.Compiler.SourceCodeServices
open FSharp.Compiler.Text
open FSharp.Compiler.Text.Pos
open FSharp.Compiler.Text.Range
+open FSharp.Compiler.SyntaxTree
open Internal.Utilities
@@ -34,12 +35,12 @@ type Positions = Position * Position
module FSharpTokenTag =
let Identifier = tagOfToken (IDENT "a")
- let String = tagOfToken (STRING ("a", LexCont.Default))
+ let String = tagOfToken (STRING ("a", SynStringKind.Regular, LexCont.Default))
let IDENT = tagOfToken (IDENT "a")
let STRING = String
- let INTERP_STRING_BEGIN_END = tagOfToken (INTERP_STRING_BEGIN_END ("a", LexCont.Default))
- let INTERP_STRING_BEGIN_PART = tagOfToken (INTERP_STRING_BEGIN_PART ("a", LexCont.Default))
+ let INTERP_STRING_BEGIN_END = tagOfToken (INTERP_STRING_BEGIN_END ("a", SynStringKind.Regular, LexCont.Default))
+ let INTERP_STRING_BEGIN_PART = tagOfToken (INTERP_STRING_BEGIN_PART ("a", SynStringKind.Regular, LexCont.Default))
let INTERP_STRING_PART = tagOfToken (INTERP_STRING_PART ("a", LexCont.Default))
let INTERP_STRING_END = tagOfToken (INTERP_STRING_END ("a", LexCont.Default))
let LPAREN = tagOfToken LPAREN
@@ -379,14 +380,14 @@ module internal LexerStateEncoding =
| LINE_COMMENT cont
| STRING_TEXT cont
| EOF cont
- | INTERP_STRING_BEGIN_PART (_, cont)
+ | INTERP_STRING_BEGIN_PART (_, _, cont)
| INTERP_STRING_PART (_, cont)
- | INTERP_STRING_BEGIN_END (_, cont)
+ | INTERP_STRING_BEGIN_END (_, _, cont)
| INTERP_STRING_END (_, cont)
| LBRACE cont
| RBRACE cont
- | BYTEARRAY (_, cont)
- | STRING (_, cont) -> cont
+ | BYTEARRAY (_, _, cont)
+ | STRING (_, _, cont) -> cont
| _ -> prevLexcont
// Note that this will discard all lexcont state, including the ifdefStack.
diff --git a/src/fsharp/service/ServiceNavigation.fs b/src/fsharp/service/ServiceNavigation.fs
index 6483fcf04c0..17446936050 100755
--- a/src/fsharp/service/ServiceNavigation.fs
+++ b/src/fsharp/service/ServiceNavigation.fs
@@ -173,7 +173,7 @@ module NavigationImpl =
let nested = processMembers membDefns FSharpEnclosingEntityKind.Exception |> snd
processExnDefnRepr baseName nested repr
- and processTycon baseName (TypeDefn(ComponentInfo(_, _, _, lid, _, _, access, _), repr, membDefns, m)) =
+ and processTycon baseName (TypeDefn(ComponentInfo(_, _, _, lid, _, _, access, _), repr, membDefns, _, m)) =
let topMembers = processMembers membDefns FSharpEnclosingEntityKind.Class |> snd
match repr with
| SynTypeDefnRepr.Exception repr -> processExnDefnRepr baseName [] repr
@@ -686,7 +686,7 @@ module NavigateTo =
| SynModuleDecl.HashDirective _
| SynModuleDecl.Open _ -> ()
- and walkSynTypeDefn(TypeDefn(componentInfo, representation, members, _)) container =
+ and walkSynTypeDefn(TypeDefn(componentInfo, representation, members, _, _)) container =
let container = addComponentInfo ContainerType.Type NavigableItemKind.Type componentInfo false container
walkSynTypeDefnRepr representation container
for m in members do
diff --git a/src/fsharp/service/ServiceParseTreeWalk.fs b/src/fsharp/service/ServiceParseTreeWalk.fs
index 4bdd61a9ea9..b496bf8f680 100755
--- a/src/fsharp/service/ServiceParseTreeWalk.fs
+++ b/src/fsharp/service/ServiceParseTreeWalk.fs
@@ -214,7 +214,7 @@ module public AstTraversal =
| SynExpr.Const (_synConst, _range) -> None
- | SynExpr.InterpolatedString (parts, _) ->
+ | SynExpr.InterpolatedString (parts, _, _) ->
[ for part in parts do
match part with
| SynInterpolatedStringPart.String _ -> ()
@@ -653,7 +653,7 @@ module public AstTraversal =
#endif
)
- and traverseSynTypeDefn path (SynTypeDefn.TypeDefn(synComponentInfo, synTypeDefnRepr, synMemberDefns, tRange) as tydef) =
+ and traverseSynTypeDefn path (SynTypeDefn.TypeDefn(synComponentInfo, synTypeDefnRepr, synMemberDefns, _, tRange) as tydef) =
let path = TraverseStep.TypeDefn tydef :: path
match visitor.VisitComponentInfo synComponentInfo with
diff --git a/src/fsharp/service/ServiceStructure.fs b/src/fsharp/service/ServiceStructure.fs
index 9e1580a3878..6c544f910d5 100644
--- a/src/fsharp/service/ServiceStructure.fs
+++ b/src/fsharp/service/ServiceStructure.fs
@@ -537,7 +537,7 @@ module Structure =
parseAttributes attrs
| _ -> ()
- and parseTypeDefn (TypeDefn(ComponentInfo(_, typeArgs, _, _, _, _, _, r), objectModel, members, fullrange)) =
+ and parseTypeDefn (TypeDefn(ComponentInfo(_, typeArgs, _, _, _, _, _, r), objectModel, members, _, fullrange)) =
let typeArgsRange = rangeOfTypeArgsElse r typeArgs
let collapse = Range.endToEnd (Range.modEnd 1 typeArgsRange) fullrange
match objectModel with
diff --git a/src/fsharp/service/ServiceUntypedParse.fs b/src/fsharp/service/ServiceUntypedParse.fs
index d83e04a7323..ed20cf62356 100755
--- a/src/fsharp/service/ServiceUntypedParse.fs
+++ b/src/fsharp/service/ServiceUntypedParse.fs
@@ -170,14 +170,18 @@ type FSharpParseFileResults(errors: FSharpDiagnostic[], input: ParsedInput optio
member _.VisitExpr(_, _, defaultTraverse, expr) =
match expr with
| SynExpr.App (_, _, SynExpr.App(_, true, SynExpr.Ident ident, _, _), argExpr, _) when rangeContainsPos argExpr.Range pos ->
- if ident.idText = "op_PipeRight" then
- Some (ident, 1)
- elif ident.idText = "op_PipeRight2" then
- Some (ident, 2)
- elif ident.idText = "op_PipeRight3" then
- Some (ident, 3)
- else
+ match argExpr with
+ | SynExpr.App(_, _, _, SynExpr.Paren(expr, _, _, _), _) when rangeContainsPos expr.Range pos ->
None
+ | _ ->
+ if ident.idText = "op_PipeRight" then
+ Some (ident, 1)
+ elif ident.idText = "op_PipeRight2" then
+ Some (ident, 2)
+ elif ident.idText = "op_PipeRight3" then
+ Some (ident, 3)
+ else
+ None
| _ -> defaultTraverse expr
})
| None -> None
@@ -216,6 +220,10 @@ type FSharpParseFileResults(errors: FSharpDiagnostic[], input: ParsedInput optio
match argExpr with
| SynExpr.App (_, _, _, _, range) when rangeContainsPos range pos ->
getIdentRangeForFuncExprInApp traverseSynExpr argExpr pos
+
+ | SynExpr.Paren(SynExpr.Lambda(_, _, _args, body, _, _), _, _, _) when rangeContainsPos body.Range pos ->
+ getIdentRangeForFuncExprInApp traverseSynExpr body pos
+
| _ ->
match funcExpr with
| SynExpr.App (_, true, _, _, _) when rangeContainsPos argExpr.Range pos ->
@@ -227,6 +235,17 @@ type FSharpParseFileResults(errors: FSharpDiagnostic[], input: ParsedInput optio
// Generally, we want to dive into the func expr to get the range
// of the identifier of the function we're after
getIdentRangeForFuncExprInApp traverseSynExpr funcExpr pos
+
+ | SynExpr.LetOrUse(_, _, bindings, body, range) when rangeContainsPos range pos ->
+ let binding =
+ bindings
+ |> List.tryFind (fun x -> rangeContainsPos x.RangeOfBindingAndRhs pos)
+ match binding with
+ | Some(SynBinding.Binding(_, _, _, _, _, _, _, _, _, expr, _, _)) ->
+ getIdentRangeForFuncExprInApp traverseSynExpr expr pos
+ | None ->
+ getIdentRangeForFuncExprInApp traverseSynExpr body pos
+
| expr ->
traverseSynExpr expr
|> Option.map (fun expr -> expr)
@@ -445,7 +464,7 @@ type FSharpParseFileResults(errors: FSharpDiagnostic[], input: ParsedInput optio
| SynExpr.Paren (e, _, _, _) ->
yield! walkExpr false e
- | SynExpr.InterpolatedString (parts, _) ->
+ | SynExpr.InterpolatedString (parts, _, _) ->
yield! walkExprs [ for part in parts do
match part with
| SynInterpolatedStringPart.String _ -> ()
@@ -581,7 +600,7 @@ type FSharpParseFileResults(errors: FSharpDiagnostic[], input: ParsedInput optio
yield! walkExpr true e ]
// Process a class declaration or F# type declaration
- let rec walkTycon (TypeDefn(ComponentInfo(_, _, _, _, _, _, _, _), repr, membDefns, m)) =
+ let rec walkTycon (TypeDefn(ComponentInfo(_, _, _, _, _, _, _, _), repr, membDefns, _, m)) =
if not (isMatchRange m) then [] else
[ for memb in membDefns do yield! walkMember memb
match repr with
@@ -1217,7 +1236,7 @@ module UntypedParseImpl =
| SynTypeDefnSigRepr.Simple(defn, _) -> walkTypeDefnSimple defn
| SynTypeDefnSigRepr.Exception(_) -> None
- and walkTypeDefn (TypeDefn (info, repr, members, _)) =
+ and walkTypeDefn (TypeDefn (info, repr, members, _, _)) =
walkComponentInfo false info
|> Option.orElse (walkTypeDefnRepr repr)
|> Option.orElse (List.tryPick walkMember members)
@@ -1470,7 +1489,7 @@ module UntypedParseImpl =
let contextFromTreePath completionPath =
// detect records usage in constructor
match path with
- | TS.Expr(_) :: TS.Binding(_) :: TS.MemberDefn(_) :: TS.TypeDefn(SynTypeDefn.TypeDefn(ComponentInfo(_, _, _, [id], _, _, _, _), _, _, _)) :: _ ->
+ | TS.Expr(_) :: TS.Binding(_) :: TS.MemberDefn(_) :: TS.TypeDefn(SynTypeDefn.TypeDefn(ComponentInfo(_, _, _, [id], _, _, _, _), _, _, _, _)) :: _ ->
RecordContext.Constructor(id.idText)
| _ -> RecordContext.New completionPath
match field with
diff --git a/src/fsharp/service/ServiceXmlDocParser.fs b/src/fsharp/service/ServiceXmlDocParser.fs
index 222ebdfa2b4..7c1342eb050 100644
--- a/src/fsharp/service/ServiceXmlDocParser.fs
+++ b/src/fsharp/service/ServiceXmlDocParser.fs
@@ -96,7 +96,7 @@ module XmlDocParsing =
and getXmlDocablesSynModuleOrNamespace (SynModuleOrNamespace(_, _, _, synModuleDecls, _, _, _, _)) =
(synModuleDecls |> List.collect getXmlDocablesSynModuleDecl)
- and getXmlDocablesSynTypeDefn (SynTypeDefn.TypeDefn(ComponentInfo(synAttributes, _, _, _, preXmlDoc, _, _, compRange), synTypeDefnRepr, synMemberDefns, tRange)) =
+ and getXmlDocablesSynTypeDefn (SynTypeDefn.TypeDefn(ComponentInfo(synAttributes, _, _, _, preXmlDoc, _, _, compRange), synTypeDefnRepr, synMemberDefns, _, tRange)) =
let stuff =
match synTypeDefnRepr with
| SynTypeDefnRepr.ObjectModel(_, synMemberDefns, _) -> (synMemberDefns |> List.collect getXmlDocablesSynMemberDefn)
diff --git a/tests/FSharp.Compiler.Private.Scripting.UnitTests/FSharpScriptTests.fs b/tests/FSharp.Compiler.Private.Scripting.UnitTests/FSharpScriptTests.fs
index c218cc2f408..431ac983ec4 100644
--- a/tests/FSharp.Compiler.Private.Scripting.UnitTests/FSharpScriptTests.fs
+++ b/tests/FSharp.Compiler.Private.Scripting.UnitTests/FSharpScriptTests.fs
@@ -317,6 +317,19 @@ typeof.Assembly.Location
// Only Windows/Linux supported.
()
+ []
+ member _.``Reference -- Azure.ResourceManager.Resources``() =
+ let code = """
+#r "nuget: Azure.Identity, 1.3.0"
+#r "nuget: Azure.ResourceManager.Resources, 1.0.0-preview.2"
+let creds = Azure.Identity.DefaultAzureCredential()
+let client = Azure.ResourceManager.Resources.ResourcesManagementClient("mySubscriptionId", creds)
+true"""
+ use script = new FSharpScript(additionalArgs=[|"/langversion:preview"|])
+ let opt = script.Eval(code) |> getValue
+ let value = opt.Value
+ Assert.True(true = downcast value.ReflectionValue)
+
[]
member _.``Simple pinvoke should not be impacted by native resolver``() =
let code = @"
diff --git a/tests/FSharp.Compiler.Service.Tests/SurfaceArea.netstandard.fs b/tests/FSharp.Compiler.Service.Tests/SurfaceArea.netstandard.fs
index 3ddf8d74e84..b0a13114c88 100644
--- a/tests/FSharp.Compiler.Service.Tests/SurfaceArea.netstandard.fs
+++ b/tests/FSharp.Compiler.Service.Tests/SurfaceArea.netstandard.fs
@@ -6466,6 +6466,28 @@ FSharp.Compiler.SyntaxTree+SynBindingReturnInfo: SynBindingReturnInfo NewSynBind
FSharp.Compiler.SyntaxTree+SynBindingReturnInfo: SynType get_typeName()
FSharp.Compiler.SyntaxTree+SynBindingReturnInfo: SynType typeName
FSharp.Compiler.SyntaxTree+SynBindingReturnInfo: System.String ToString()
+FSharp.Compiler.SyntaxTree+SynByteStringKind+Tags: Int32 Regular
+FSharp.Compiler.SyntaxTree+SynByteStringKind+Tags: Int32 Verbatim
+FSharp.Compiler.SyntaxTree+SynByteStringKind: Boolean Equals(SynByteStringKind)
+FSharp.Compiler.SyntaxTree+SynByteStringKind: Boolean Equals(System.Object)
+FSharp.Compiler.SyntaxTree+SynByteStringKind: Boolean Equals(System.Object, System.Collections.IEqualityComparer)
+FSharp.Compiler.SyntaxTree+SynByteStringKind: Boolean IsRegular
+FSharp.Compiler.SyntaxTree+SynByteStringKind: Boolean IsVerbatim
+FSharp.Compiler.SyntaxTree+SynByteStringKind: Boolean get_IsRegular()
+FSharp.Compiler.SyntaxTree+SynByteStringKind: Boolean get_IsVerbatim()
+FSharp.Compiler.SyntaxTree+SynByteStringKind: FSharp.Compiler.SyntaxTree+SynByteStringKind+Tags
+FSharp.Compiler.SyntaxTree+SynByteStringKind: Int32 CompareTo(SynByteStringKind)
+FSharp.Compiler.SyntaxTree+SynByteStringKind: Int32 CompareTo(System.Object)
+FSharp.Compiler.SyntaxTree+SynByteStringKind: Int32 CompareTo(System.Object, System.Collections.IComparer)
+FSharp.Compiler.SyntaxTree+SynByteStringKind: Int32 GetHashCode()
+FSharp.Compiler.SyntaxTree+SynByteStringKind: Int32 GetHashCode(System.Collections.IEqualityComparer)
+FSharp.Compiler.SyntaxTree+SynByteStringKind: Int32 Tag
+FSharp.Compiler.SyntaxTree+SynByteStringKind: Int32 get_Tag()
+FSharp.Compiler.SyntaxTree+SynByteStringKind: SynByteStringKind Regular
+FSharp.Compiler.SyntaxTree+SynByteStringKind: SynByteStringKind Verbatim
+FSharp.Compiler.SyntaxTree+SynByteStringKind: SynByteStringKind get_Regular()
+FSharp.Compiler.SyntaxTree+SynByteStringKind: SynByteStringKind get_Verbatim()
+FSharp.Compiler.SyntaxTree+SynByteStringKind: System.String ToString()
FSharp.Compiler.SyntaxTree+SynComponentInfo: Boolean get_preferPostfix()
FSharp.Compiler.SyntaxTree+SynComponentInfo: Boolean preferPostfix
FSharp.Compiler.SyntaxTree+SynComponentInfo: FSharp.Compiler.Text.Range Range
@@ -6496,6 +6518,8 @@ FSharp.Compiler.SyntaxTree+SynConst+Bytes: Byte[] bytes
FSharp.Compiler.SyntaxTree+SynConst+Bytes: Byte[] get_bytes()
FSharp.Compiler.SyntaxTree+SynConst+Bytes: FSharp.Compiler.Text.Range get_range()
FSharp.Compiler.SyntaxTree+SynConst+Bytes: FSharp.Compiler.Text.Range range
+FSharp.Compiler.SyntaxTree+SynConst+Bytes: SynByteStringKind get_synByteStringKind()
+FSharp.Compiler.SyntaxTree+SynConst+Bytes: SynByteStringKind synByteStringKind
FSharp.Compiler.SyntaxTree+SynConst+Char: Char Item
FSharp.Compiler.SyntaxTree+SynConst+Char: Char get_Item()
FSharp.Compiler.SyntaxTree+SynConst+Decimal: System.Decimal Item
@@ -6520,6 +6544,8 @@ FSharp.Compiler.SyntaxTree+SynConst+Single: Single Item
FSharp.Compiler.SyntaxTree+SynConst+Single: Single get_Item()
FSharp.Compiler.SyntaxTree+SynConst+String: FSharp.Compiler.Text.Range get_range()
FSharp.Compiler.SyntaxTree+SynConst+String: FSharp.Compiler.Text.Range range
+FSharp.Compiler.SyntaxTree+SynConst+String: SynStringKind get_synStringKind()
+FSharp.Compiler.SyntaxTree+SynConst+String: SynStringKind synStringKind
FSharp.Compiler.SyntaxTree+SynConst+String: System.String get_text()
FSharp.Compiler.SyntaxTree+SynConst+String: System.String text
FSharp.Compiler.SyntaxTree+SynConst+Tags: Int32 Bool
@@ -6625,7 +6651,7 @@ FSharp.Compiler.SyntaxTree+SynConst: Int32 Tag
FSharp.Compiler.SyntaxTree+SynConst: Int32 get_Tag()
FSharp.Compiler.SyntaxTree+SynConst: SynConst NewBool(Boolean)
FSharp.Compiler.SyntaxTree+SynConst: SynConst NewByte(Byte)
-FSharp.Compiler.SyntaxTree+SynConst: SynConst NewBytes(Byte[], FSharp.Compiler.Text.Range)
+FSharp.Compiler.SyntaxTree+SynConst: SynConst NewBytes(Byte[], SynByteStringKind, FSharp.Compiler.Text.Range)
FSharp.Compiler.SyntaxTree+SynConst: SynConst NewChar(Char)
FSharp.Compiler.SyntaxTree+SynConst: SynConst NewDecimal(System.Decimal)
FSharp.Compiler.SyntaxTree+SynConst: SynConst NewDouble(Double)
@@ -6636,7 +6662,7 @@ FSharp.Compiler.SyntaxTree+SynConst: SynConst NewIntPtr(Int64)
FSharp.Compiler.SyntaxTree+SynConst: SynConst NewMeasure(SynConst, SynMeasure)
FSharp.Compiler.SyntaxTree+SynConst: SynConst NewSByte(SByte)
FSharp.Compiler.SyntaxTree+SynConst: SynConst NewSingle(Single)
-FSharp.Compiler.SyntaxTree+SynConst: SynConst NewString(System.String, FSharp.Compiler.Text.Range)
+FSharp.Compiler.SyntaxTree+SynConst: SynConst NewString(System.String, SynStringKind, FSharp.Compiler.Text.Range)
FSharp.Compiler.SyntaxTree+SynConst: SynConst NewUInt16(UInt16)
FSharp.Compiler.SyntaxTree+SynConst: SynConst NewUInt16s(UInt16[])
FSharp.Compiler.SyntaxTree+SynConst: SynConst NewUInt32(UInt32)
@@ -6890,6 +6916,8 @@ FSharp.Compiler.SyntaxTree+SynExpr+InterpolatedString: FSharp.Compiler.Text.Rang
FSharp.Compiler.SyntaxTree+SynExpr+InterpolatedString: FSharp.Compiler.Text.Range range
FSharp.Compiler.SyntaxTree+SynExpr+InterpolatedString: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.SyntaxTree+SynInterpolatedStringPart] contents
FSharp.Compiler.SyntaxTree+SynExpr+InterpolatedString: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.SyntaxTree+SynInterpolatedStringPart] get_contents()
+FSharp.Compiler.SyntaxTree+SynExpr+InterpolatedString: SynStringKind get_synStringKind()
+FSharp.Compiler.SyntaxTree+SynExpr+InterpolatedString: SynStringKind synStringKind
FSharp.Compiler.SyntaxTree+SynExpr+JoinIn: FSharp.Compiler.Text.Range get_lhsRange()
FSharp.Compiler.SyntaxTree+SynExpr+JoinIn: FSharp.Compiler.Text.Range get_range()
FSharp.Compiler.SyntaxTree+SynExpr+JoinIn: FSharp.Compiler.Text.Range lhsRange
@@ -7482,7 +7510,7 @@ FSharp.Compiler.SyntaxTree+SynExpr: SynExpr NewIfThenElse(SynExpr, SynExpr, Micr
FSharp.Compiler.SyntaxTree+SynExpr: SynExpr NewImplicitZero(FSharp.Compiler.Text.Range)
FSharp.Compiler.SyntaxTree+SynExpr: SynExpr NewInferredDowncast(SynExpr, FSharp.Compiler.Text.Range)
FSharp.Compiler.SyntaxTree+SynExpr: SynExpr NewInferredUpcast(SynExpr, FSharp.Compiler.Text.Range)
-FSharp.Compiler.SyntaxTree+SynExpr: SynExpr NewInterpolatedString(Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.SyntaxTree+SynInterpolatedStringPart], FSharp.Compiler.Text.Range)
+FSharp.Compiler.SyntaxTree+SynExpr: SynExpr NewInterpolatedString(Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.SyntaxTree+SynInterpolatedStringPart], SynStringKind, FSharp.Compiler.Text.Range)
FSharp.Compiler.SyntaxTree+SynExpr: SynExpr NewJoinIn(SynExpr, FSharp.Compiler.Text.Range, SynExpr, FSharp.Compiler.Text.Range)
FSharp.Compiler.SyntaxTree+SynExpr: SynExpr NewLambda(Boolean, Boolean, SynSimplePats, SynExpr, Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`2[Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.SyntaxTree+SynPat],FSharp.Compiler.SyntaxTree+SynExpr]], FSharp.Compiler.Text.Range)
FSharp.Compiler.SyntaxTree+SynExpr: SynExpr NewLazy(SynExpr, FSharp.Compiler.Text.Range)
@@ -8538,6 +8566,33 @@ FSharp.Compiler.SyntaxTree+SynStaticOptimizationConstraint: Int32 get_Tag()
FSharp.Compiler.SyntaxTree+SynStaticOptimizationConstraint: SynStaticOptimizationConstraint NewWhenTyparIsStruct(SynTypar, FSharp.Compiler.Text.Range)
FSharp.Compiler.SyntaxTree+SynStaticOptimizationConstraint: SynStaticOptimizationConstraint NewWhenTyparTyconEqualsTycon(SynTypar, SynType, FSharp.Compiler.Text.Range)
FSharp.Compiler.SyntaxTree+SynStaticOptimizationConstraint: System.String ToString()
+FSharp.Compiler.SyntaxTree+SynStringKind+Tags: Int32 Regular
+FSharp.Compiler.SyntaxTree+SynStringKind+Tags: Int32 TripleQuote
+FSharp.Compiler.SyntaxTree+SynStringKind+Tags: Int32 Verbatim
+FSharp.Compiler.SyntaxTree+SynStringKind: Boolean Equals(SynStringKind)
+FSharp.Compiler.SyntaxTree+SynStringKind: Boolean Equals(System.Object)
+FSharp.Compiler.SyntaxTree+SynStringKind: Boolean Equals(System.Object, System.Collections.IEqualityComparer)
+FSharp.Compiler.SyntaxTree+SynStringKind: Boolean IsRegular
+FSharp.Compiler.SyntaxTree+SynStringKind: Boolean IsTripleQuote
+FSharp.Compiler.SyntaxTree+SynStringKind: Boolean IsVerbatim
+FSharp.Compiler.SyntaxTree+SynStringKind: Boolean get_IsRegular()
+FSharp.Compiler.SyntaxTree+SynStringKind: Boolean get_IsTripleQuote()
+FSharp.Compiler.SyntaxTree+SynStringKind: Boolean get_IsVerbatim()
+FSharp.Compiler.SyntaxTree+SynStringKind: FSharp.Compiler.SyntaxTree+SynStringKind+Tags
+FSharp.Compiler.SyntaxTree+SynStringKind: Int32 CompareTo(SynStringKind)
+FSharp.Compiler.SyntaxTree+SynStringKind: Int32 CompareTo(System.Object)
+FSharp.Compiler.SyntaxTree+SynStringKind: Int32 CompareTo(System.Object, System.Collections.IComparer)
+FSharp.Compiler.SyntaxTree+SynStringKind: Int32 GetHashCode()
+FSharp.Compiler.SyntaxTree+SynStringKind: Int32 GetHashCode(System.Collections.IEqualityComparer)
+FSharp.Compiler.SyntaxTree+SynStringKind: Int32 Tag
+FSharp.Compiler.SyntaxTree+SynStringKind: Int32 get_Tag()
+FSharp.Compiler.SyntaxTree+SynStringKind: SynStringKind Regular
+FSharp.Compiler.SyntaxTree+SynStringKind: SynStringKind TripleQuote
+FSharp.Compiler.SyntaxTree+SynStringKind: SynStringKind Verbatim
+FSharp.Compiler.SyntaxTree+SynStringKind: SynStringKind get_Regular()
+FSharp.Compiler.SyntaxTree+SynStringKind: SynStringKind get_TripleQuote()
+FSharp.Compiler.SyntaxTree+SynStringKind: SynStringKind get_Verbatim()
+FSharp.Compiler.SyntaxTree+SynStringKind: System.String ToString()
FSharp.Compiler.SyntaxTree+SynTypar: Boolean get_isCompGen()
FSharp.Compiler.SyntaxTree+SynTypar: Boolean isCompGen
FSharp.Compiler.SyntaxTree+SynTypar: FSharp.Compiler.Text.Range Range
@@ -8872,7 +8927,9 @@ FSharp.Compiler.SyntaxTree+SynTypeDefn: Microsoft.FSharp.Collections.FSharpList`
FSharp.Compiler.SyntaxTree+SynTypeDefn: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.SyntaxTree+SynMemberDefn] members
FSharp.Compiler.SyntaxTree+SynTypeDefn: SynComponentInfo get_typeInfo()
FSharp.Compiler.SyntaxTree+SynTypeDefn: SynComponentInfo typeInfo
-FSharp.Compiler.SyntaxTree+SynTypeDefn: SynTypeDefn NewTypeDefn(SynComponentInfo, SynTypeDefnRepr, Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.SyntaxTree+SynMemberDefn], FSharp.Compiler.Text.Range)
+FSharp.Compiler.SyntaxTree+SynTypeDefn: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.SyntaxTree+SynMemberDefn] get_implicitConstructor()
+FSharp.Compiler.SyntaxTree+SynTypeDefn: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.SyntaxTree+SynMemberDefn] implicitConstructor
+FSharp.Compiler.SyntaxTree+SynTypeDefn: SynTypeDefn NewTypeDefn(SynComponentInfo, SynTypeDefnRepr, Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.SyntaxTree+SynMemberDefn], Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.SyntaxTree+SynMemberDefn], FSharp.Compiler.Text.Range)
FSharp.Compiler.SyntaxTree+SynTypeDefn: SynTypeDefnRepr get_typeRepr()
FSharp.Compiler.SyntaxTree+SynTypeDefn: SynTypeDefnRepr typeRepr
FSharp.Compiler.SyntaxTree+SynTypeDefn: System.String ToString()
@@ -9269,6 +9326,7 @@ FSharp.Compiler.SyntaxTree: FSharp.Compiler.SyntaxTree+SynAttributeList
FSharp.Compiler.SyntaxTree: FSharp.Compiler.SyntaxTree+SynBinding
FSharp.Compiler.SyntaxTree: FSharp.Compiler.SyntaxTree+SynBindingKind
FSharp.Compiler.SyntaxTree: FSharp.Compiler.SyntaxTree+SynBindingReturnInfo
+FSharp.Compiler.SyntaxTree: FSharp.Compiler.SyntaxTree+SynByteStringKind
FSharp.Compiler.SyntaxTree: FSharp.Compiler.SyntaxTree+SynComponentInfo
FSharp.Compiler.SyntaxTree: FSharp.Compiler.SyntaxTree+SynConst
FSharp.Compiler.SyntaxTree: FSharp.Compiler.SyntaxTree+SynEnumCase
@@ -9297,6 +9355,7 @@ FSharp.Compiler.SyntaxTree: FSharp.Compiler.SyntaxTree+SynSimplePat
FSharp.Compiler.SyntaxTree: FSharp.Compiler.SyntaxTree+SynSimplePatAlternativeIdInfo
FSharp.Compiler.SyntaxTree: FSharp.Compiler.SyntaxTree+SynSimplePats
FSharp.Compiler.SyntaxTree: FSharp.Compiler.SyntaxTree+SynStaticOptimizationConstraint
+FSharp.Compiler.SyntaxTree: FSharp.Compiler.SyntaxTree+SynStringKind
FSharp.Compiler.SyntaxTree: FSharp.Compiler.SyntaxTree+SynTypar
FSharp.Compiler.SyntaxTree: FSharp.Compiler.SyntaxTree+SynTyparDecl
FSharp.Compiler.SyntaxTree: FSharp.Compiler.SyntaxTree+SynType
diff --git a/tests/FSharp.Test.Utilities/TestFramework.fs b/tests/FSharp.Test.Utilities/TestFramework.fs
index f2f8b2c5679..9aa5ea0a40d 100644
--- a/tests/FSharp.Test.Utilities/TestFramework.fs
+++ b/tests/FSharp.Test.Utilities/TestFramework.fs
@@ -5,6 +5,7 @@ module TestFramework
open Microsoft.Win32
open System
open System.IO
+open System.Reflection
open System.Text.RegularExpressions
open System.Diagnostics
open Scripting
@@ -55,8 +56,17 @@ module Commands =
else
p.WaitForExit()
#if DEBUG
- File.WriteAllLines(Path.Combine(workingDir, "StandardOutput.txt"), outputList)
- File.WriteAllLines(Path.Combine(workingDir, "StandardError.txt"), errorsList)
+ let workingDir' =
+ if workingDir = ""
+ then
+ // Assign working dir to prevent default to C:\Windows\System32
+ let executionLocation = Assembly.GetExecutingAssembly().Location
+ Path.GetDirectoryName executionLocation
+ else
+ workingDir
+
+ File.WriteAllLines(Path.Combine(workingDir', "StandardOutput.txt"), outputList)
+ File.WriteAllLines(Path.Combine(workingDir', "StandardError.txt"), errorsList)
#endif
p.ExitCode, outputList.ToArray(), errorsList.ToArray()
| None -> -1, Array.empty, Array.empty
diff --git a/tests/fsharp/Compiler/Language/StringInterpolation.fs b/tests/fsharp/Compiler/Language/StringInterpolation.fs
index fed6b2aeb76..f448704f978 100644
--- a/tests/fsharp/Compiler/Language/StringInterpolation.fs
+++ b/tests/fsharp/Compiler/Language/StringInterpolation.fs
@@ -325,16 +325,16 @@ check "fwejwflpej2" (fmt $"abc") "abc"
check "fwejwflpej3" (fmt $"abc{1}") "abc1"
check "fwejwflpej6" (fmt_us $"abc {30000} def") "abc 30000 def"
check "fwejwflpej7" (fmt_de $"abc {30000} def") "abc 30000 def"
-check "fwejwflpej8" (fmt_us $"abc {30000:N} def") "abc 30,000.00 def"
-check "fwejwflpej9" (fmt_de $"abc {30000:N} def") "abc 30.000,00 def"
+check "fwejwflpej8" (fmt_us $"abc {30000:N2} def") "abc 30,000.00 def"
+check "fwejwflpej9" (fmt_de $"abc {30000:N2} def") "abc 30.000,00 def"
check "fwejwflpej10" (fmt_us $"abc {30000} def {40000} hij") "abc 30000 def 40000 hij"
check "fwejwflpej11" (fmt_us $"abc {30000,-10} def {40000} hij") "abc 30000 def 40000 hij"
check "fwejwflpej12" (fmt_us $"abc {30000,10} def {40000} hij") "abc 30000 def 40000 hij"
check "fwejwflpej13" (fmt_de $"abc {30000} def {40000} hij") "abc 30000 def 40000 hij"
-check "fwejwflpej14" (fmt_us $"abc {30000:N} def {40000:N} hij") "abc 30,000.00 def 40,000.00 hij"
-check "fwejwflpej15" (fmt_de $"abc {30000:N} def {40000:N} hij") "abc 30.000,00 def 40.000,00 hij"
-check "fwejwflpej16" (fmt_de $"abc {30000,10:N} def {40000:N} hij") "abc 30.000,00 def 40.000,00 hij"
-check "fwejwflpej17" (fmt_de $"abc {30000,-10:N} def {40000:N} hij") "abc 30.000,00 def 40.000,00 hij"
+check "fwejwflpej14" (fmt_us $"abc {30000:N2} def {40000:N2} hij") "abc 30,000.00 def 40,000.00 hij"
+check "fwejwflpej15" (fmt_de $"abc {30000:N2} def {40000:N2} hij") "abc 30.000,00 def 40.000,00 hij"
+check "fwejwflpej16" (fmt_de $"abc {30000,10:N2} def {40000:N2} hij") "abc 30.000,00 def 40.000,00 hij"
+check "fwejwflpej17" (fmt_de $"abc {30000,-10:N2} def {40000:N2} hij") "abc 30.000,00 def 40.000,00 hij"
"""
@@ -354,16 +354,16 @@ check "fwejwflpej2" (fmt $"abc") "abc"
check "fwejwflpej3" (fmt $"abc{1}") "abc1"
check "fwejwflpej6" (fmt_us $"abc {30000} def") "abc 30000 def"
check "fwejwflpej7" (fmt_de $"abc {30000} def") "abc 30000 def"
-check "fwejwflpej8" (fmt_us $"abc {30000:N} def") "abc 30,000.00 def"
-check "fwejwflpej9" (fmt_de $"abc {30000:N} def") "abc 30.000,00 def"
+check "fwejwflpej8" (fmt_us $"abc {30000:N2} def") "abc 30,000.00 def"
+check "fwejwflpej9" (fmt_de $"abc {30000:N2} def") "abc 30.000,00 def"
check "fwejwflpej10" (fmt_us $"abc {30000} def {40000} hij") "abc 30000 def 40000 hij"
check "fwejwflpej11" (fmt_us $"abc {30000,-10} def {40000} hij") "abc 30000 def 40000 hij"
check "fwejwflpej12" (fmt_us $"abc {30000,10} def {40000} hij") "abc 30000 def 40000 hij"
check "fwejwflpej13" (fmt_de $"abc {30000} def {40000} hij") "abc 30000 def 40000 hij"
-check "fwejwflpej14" (fmt_us $"abc {30000:N} def {40000:N} hij") "abc 30,000.00 def 40,000.00 hij"
-check "fwejwflpej15" (fmt_de $"abc {30000:N} def {40000:N} hij") "abc 30.000,00 def 40.000,00 hij"
-check "fwejwflpej16" (fmt_de $"abc {30000,10:N} def {40000:N} hij") "abc 30.000,00 def 40.000,00 hij"
-check "fwejwflpej17" (fmt_de $"abc {30000,-10:N} def {40000:N} hij") "abc 30.000,00 def 40.000,00 hij"
+check "fwejwflpej14" (fmt_us $"abc {30000:N2} def {40000:N2} hij") "abc 30,000.00 def 40,000.00 hij"
+check "fwejwflpej15" (fmt_de $"abc {30000:N2} def {40000:N2} hij") "abc 30.000,00 def 40.000,00 hij"
+check "fwejwflpej16" (fmt_de $"abc {30000,10:N2} def {40000:N2} hij") "abc 30.000,00 def 40.000,00 hij"
+check "fwejwflpej17" (fmt_de $"abc {30000,-10:N2} def {40000:N2} hij") "abc 30.000,00 def 40.000,00 hij"
"""
diff --git a/tests/fsharp/Compiler/Stress/LargeExprTests.fs b/tests/fsharp/Compiler/Stress/LargeExprTests.fs
index 9be3574c000..5eaf926ef6d 100644
--- a/tests/fsharp/Compiler/Stress/LargeExprTests.fs
+++ b/tests/fsharp/Compiler/Stress/LargeExprTests.fs
@@ -9,6 +9,9 @@ open FSharp.Test.Utilities
module LargeExprTests =
[]
+#if NETCOREAPP
+ []
+#endif
let LargeRecordDoesNotStackOverflow() =
CompilerAssert.CompileExe
"""
diff --git a/tests/service/InteractiveCheckerTests.fs b/tests/service/InteractiveCheckerTests.fs
index 3f24bd79df7..fbaed2c1bf7 100644
--- a/tests/service/InteractiveCheckerTests.fs
+++ b/tests/service/InteractiveCheckerTests.fs
@@ -31,7 +31,7 @@ let internal identsAndRanges (input: ParsedInput) =
// TODO : attrs, typarDecls and typarConstraints
[identAndRange (longIdentToString longIdent) range]
let extractFromTypeDefn (typeDefn: SynTypeDefn) =
- let (SynTypeDefn.TypeDefn(componentInfo, _repr, _members, _)) = typeDefn
+ let (SynTypeDefn.TypeDefn(componentInfo, _repr, _members, _, _)) = typeDefn
// TODO : repr and members
extractFromComponentInfo componentInfo
let rec extractFromModuleDecl (moduleDecl: SynModuleDecl) =
diff --git a/tests/service/ServiceUntypedParseTests.fs b/tests/service/ServiceUntypedParseTests.fs
index c9edab7d3f9..7c13d54ae44 100644
--- a/tests/service/ServiceUntypedParseTests.fs
+++ b/tests/service/ServiceUntypedParseTests.fs
@@ -199,7 +199,7 @@ module TypeMemberRanges =
let getTypeMemberRange source =
let (SynModuleOrNamespace (decls = decls)) = parseSourceCodeAndGetModule source
match decls with
- | [ SynModuleDecl.Types ([ TypeDefn (_, SynTypeDefnRepr.ObjectModel (_, memberDecls, _), _, _) ], _) ] ->
+ | [ SynModuleDecl.Types ([ TypeDefn (_, SynTypeDefnRepr.ObjectModel (_, memberDecls, _), _, _, _) ], _) ] ->
memberDecls |> List.map (fun memberDecl -> getRangeCoords memberDecl.Range)
| _ -> failwith "Could not get member"
@@ -835,6 +835,26 @@ async {
|> tups
|> shouldEqual ((4, 11), (4, 16))
+ []
+ let ``TryRangeOfFunctionOrMethodBeingApplied - inside lambda``() =
+ let source = """
+let add n1 n2 = n1 + n2
+let lst = [1; 2; 3]
+let mapped =
+ lst |> List.map (fun n ->
+ let sum = add
+ n.ToString()
+ )
+"""
+ let parseFileResults, _ = getParseAndCheckResults source
+ let res = parseFileResults.TryRangeOfFunctionOrMethodBeingApplied (mkPos 6 21)
+ match res with
+ | None -> Assert.Fail("Expected 'add' but got nothing")
+ | Some range ->
+ range
+ |> tups
+ |> shouldEqual ((6, 18), (6, 21))
+
module PipelinesAndArgs =
[]
let ``TryIdentOfPipelineContainingPosAndNumArgsApplied - No pipeline, no infix app``() =
@@ -897,6 +917,21 @@ let square x = x *
| None ->
Assert.Fail("No pipeline found")
+ []
+ let ``TryIdentOfPipelineContainingPosAndNumArgsApplied - none when inside lambda``() =
+ let source = """
+let add n1 n2 = n1 + n2
+let lst = [1; 2; 3]
+let mapped =
+ lst |> List.map (fun n ->
+ let sum = add 1
+ n.ToString()
+ )
+ """
+ let parseFileResults, _ = getParseAndCheckResults source
+ let res = parseFileResults.TryIdentOfPipelineContainingPosAndNumArgsApplied (mkPos 6 22)
+ Assert.IsTrue(res.IsNone, "Inside a lambda but counted the pipeline outside of that lambda.")
+
[]
let ``TryRangeOfExprInYieldOrReturn - not contained``() =
let source = """
diff --git a/tests/service/Symbols.fs b/tests/service/Symbols.fs
index 983d9555c8f..fe957fb4317 100644
--- a/tests/service/Symbols.fs
+++ b/tests/service/Symbols.fs
@@ -287,4 +287,127 @@ module SyntaxExpressions =
assertRange 2 4 3 14 doRange
assertRange 4 4 5 18 doBangRange
| _ ->
- failwith "Could not find SynExpr.Do"
\ No newline at end of file
+ failwith "Could not find SynExpr.Do"
+
+module Strings =
+ let getBindingExpressionValue (parseResults: ParsedInput option) =
+ parseResults
+ |> Option.bind
+ (fun tree ->
+ match tree with
+ | ParsedInput.ImplFile (ParsedImplFileInput (modules = modules)) ->
+ modules
+ |> List.tryPick
+ (function
+ | SynModuleOrNamespace (decls = decls) ->
+ decls
+ |> List.tryPick
+ (function
+ | SynModuleDecl.Let (bindings = bindings) ->
+ bindings
+ |> List.tryPick
+ (function
+ | SynBinding.Binding (_,
+ _,
+ _,
+ _,
+ _,
+ _,
+ _,
+ SynPat.Named _,
+ _,
+ e,
+ _,
+ _) -> Some e
+ | _ -> None)
+ | _ -> None))
+ | _ -> None)
+
+ let getBindingConstValue parseResults =
+ match getBindingExpressionValue parseResults with
+ | Some (SynExpr.Const(c,_)) -> Some c
+ | _ -> None
+
+ []
+ let ``SynConst.String with SynStringKind.Regular`` () =
+ let parseResults =
+ getParseResults
+ """
+ let s = "yo"
+ """
+
+ match getBindingConstValue parseResults with
+ | Some (SynConst.String (_, kind, _)) -> kind |> should equal SynStringKind.Regular
+ | _ -> failwithf "Couldn't find const"
+
+ []
+ let ``SynConst.String with SynStringKind.Verbatim`` () =
+ let parseResults =
+ getParseResults
+ """
+ let s = @"yo"
+ """
+
+ match getBindingConstValue parseResults with
+ | Some (SynConst.String (_, kind, _)) -> kind |> should equal SynStringKind.Verbatim
+ | _ -> failwithf "Couldn't find const"
+
+ []
+ let ``SynConst.String with SynStringKind.TripleQuote`` () =
+ let parseResults =
+ getParseResults
+ "
+ let s = \"\"\"yo\"\"\"
+ "
+
+ match getBindingConstValue parseResults with
+ | Some (SynConst.String (_, kind, _)) -> kind |> should equal SynStringKind.TripleQuote
+ | _ -> failwithf "Couldn't find const"
+
+ []
+ let ``SynConst.Bytes with SynByteStringKind.Regular`` () =
+ let parseResults =
+ getParseResults
+ """
+let bytes = "yo"B
+ """
+
+ match getBindingConstValue parseResults with
+ | Some (SynConst.Bytes (_, kind, _)) -> kind |> should equal SynByteStringKind.Regular
+ | _ -> failwithf "Couldn't find const"
+
+ []
+ let ``SynConst.Bytes with SynByteStringKind.Verbatim`` () =
+ let parseResults =
+ getParseResults
+ """
+let bytes = @"yo"B
+ """
+
+ match getBindingConstValue parseResults with
+ | Some (SynConst.Bytes (_, kind, _)) -> kind |> should equal SynByteStringKind.Verbatim
+ | _ -> failwithf "Couldn't find const"
+
+ []
+ let ``SynExpr.InterpolatedString with SynStringKind.TripleQuote`` () =
+ let parseResults =
+ getParseResults
+ "
+ let s = $\"\"\"yo {42}\"\"\"
+ "
+
+ match getBindingExpressionValue parseResults with
+ | Some (SynExpr.InterpolatedString(_, kind, _)) -> kind |> should equal SynStringKind.TripleQuote
+ | _ -> failwithf "Couldn't find const"
+
+ []
+ let ``SynExpr.InterpolatedString with SynStringKind.Regular`` () =
+ let parseResults =
+ getParseResults
+ """
+ let s = $"yo {42}"
+ """
+
+ match getBindingExpressionValue parseResults with
+ | Some (SynExpr.InterpolatedString(_, kind, _)) -> kind |> should equal SynStringKind.Regular
+ | _ -> failwithf "Couldn't find const"
\ No newline at end of file
diff --git a/tests/service/data/TestTP/TestTP.fsproj b/tests/service/data/TestTP/TestTP.fsproj
index 4343a1d8a4a..442fc909f7a 100644
--- a/tests/service/data/TestTP/TestTP.fsproj
+++ b/tests/service/data/TestTP/TestTP.fsproj
@@ -5,7 +5,7 @@
net472
true
nunit
- --nowarn:3390 --nowarn:3218
+ $(OtherFlags) --nowarn:3390 --nowarn:3218
diff --git a/vsintegration/src/FSharp.Editor/CodeFix/UseMutationWhenValueIsMutable.fs b/vsintegration/src/FSharp.Editor/CodeFix/UseMutationWhenValueIsMutable.fs
index 3a3ea50cb5d..a0d423ca149 100644
--- a/vsintegration/src/FSharp.Editor/CodeFix/UseMutationWhenValueIsMutable.fs
+++ b/vsintegration/src/FSharp.Editor/CodeFix/UseMutationWhenValueIsMutable.fs
@@ -2,6 +2,7 @@
namespace Microsoft.VisualStudio.FSharp.Editor
+open System
open System.Composition
open System.Threading
open System.Threading.Tasks
@@ -36,20 +37,29 @@ type internal FSharpUseMutationWhenValueIsMutableFixProvider
let document = context.Document
do! Option.guard (not(isSignatureFile document.FilePath))
- let position = context.Span.Start
let checker = checkerProvider.Checker
let! parsingOptions, projectOptions = projectInfoManager.TryGetOptionsForEditingDocumentOrProject(document, CancellationToken.None, userOpName)
let! sourceText = document.GetTextAsync () |> liftTaskAsync
let defines = CompilerEnvironment.GetCompilationDefinesForEditing parsingOptions
- let textLine = sourceText.Lines.GetLineFromPosition position
- let textLinePos = sourceText.Lines.GetLinePosition position
+
+ let adjustedPosition =
+ let rec loop ch pos =
+ if Char.IsWhiteSpace(ch) then
+ pos
+ else
+ loop sourceText.[pos + 1] (pos + 1)
+
+ loop sourceText.[context.Span.Start] context.Span.Start
+
+ let textLine = sourceText.Lines.GetLineFromPosition adjustedPosition
+ let textLinePos = sourceText.Lines.GetLinePosition adjustedPosition
let fcsTextLineNumber = Line.fromZ textLinePos.Line
let! _, _, checkFileResults = checker.ParseAndCheckDocument (document, projectOptions, sourceText=sourceText, userOpName=userOpName)
- let! lexerSymbol = Tokenizer.getSymbolAtPosition (document.Id, sourceText, position, document.FilePath, defines, SymbolLookupKind.Greedy, false, false)
+ let! lexerSymbol = Tokenizer.getSymbolAtPosition (document.Id, sourceText, adjustedPosition, document.FilePath, defines, SymbolLookupKind.Greedy, false, false)
let! symbolUse = checkFileResults.GetSymbolUseAtLocation(fcsTextLineNumber, lexerSymbol.Ident.idRange.EndColumn, textLine.ToString(), lexerSymbol.FullIsland)
match symbolUse.Symbol with
- | :? FSharpMemberOrFunctionOrValue as mfv when mfv.IsValue && mfv.IsMutable ->
+ | :? FSharpMemberOrFunctionOrValue as mfv when mfv.IsMutable || mfv.HasSetterMethod ->
let title = SR.UseMutationWhenValueIsMutable()
let! symbolSpan = RoslynHelpers.TryFSharpRangeToTextSpan(sourceText, symbolUse.RangeAlternate)
let mutable pos = symbolSpan.End
diff --git a/vsintegration/src/FSharp.Editor/Completion/SignatureHelp.fs b/vsintegration/src/FSharp.Editor/Completion/SignatureHelp.fs
index 650d4ab25e4..0be70e446ae 100644
--- a/vsintegration/src/FSharp.Editor/Completion/SignatureHelp.fs
+++ b/vsintegration/src/FSharp.Editor/Completion/SignatureHelp.fs
@@ -33,12 +33,17 @@ type SignatureHelpItem =
Parameters: SignatureHelpParameterInfo[]
MainDescription: ResizeArray }
+type CurrentSignatureHelpSessionKind =
+ | FunctionApplication
+ | MethodCall
+
type SignatureHelpData =
{ SignatureHelpItems: SignatureHelpItem[]
ApplicableSpan: TextSpan
ArgumentIndex: int
ArgumentCount: int
- ArgumentName: string option }
+ ArgumentName: string option
+ CurrentSignatureHelpSessionKind: CurrentSignatureHelpSessionKind }
[]
[)>]
@@ -56,6 +61,8 @@ type internal FSharpSignatureHelpProvider
static let oneColAfter (lp: LinePosition) = LinePosition(lp.Line,lp.Character+1)
static let oneColBefore (lp: LinePosition) = LinePosition(lp.Line,max 0 (lp.Character-1))
+ let mutable possibleCurrentSignatureHelpSessionKind = None
+
static member internal ProvideMethodsAsyncAux
(
caretLinePos: LinePosition,
@@ -212,7 +219,8 @@ type internal FSharpSignatureHelpProvider
ApplicableSpan = applicableSpan
ArgumentIndex = argumentIndex
ArgumentCount = argumentCount
- ArgumentName = argumentName }
+ ArgumentName = argumentName
+ CurrentSignatureHelpSessionKind = MethodCall }
return! Some data
}
@@ -425,7 +433,8 @@ type internal FSharpSignatureHelpProvider
ApplicableSpan = TextSpan(symbolSpan.End, caretPosition - symbolSpan.End)
ArgumentIndex = argumentIndex
ArgumentCount = displayArgs.Count
- ArgumentName = None }
+ ArgumentName = None
+ CurrentSignatureHelpSessionKind = FunctionApplication }
return! Some data
| _ ->
@@ -443,7 +452,8 @@ type internal FSharpSignatureHelpProvider
options: FSharpProjectOptions,
filePath: string,
textVersionHash: int,
- triggerTypedChar: char option
+ triggerTypedChar: char option,
+ possibleCurrentSignatureHelpSessionKind: CurrentSignatureHelpSessionKind option
) =
asyncMaybe {
let textLines = sourceText.Lines
@@ -463,11 +473,23 @@ type internal FSharpSignatureHelpProvider
let adjustedColumnChar = sourceText.[adjustedColumnInSource]
- match triggerTypedChar with
+ match triggerTypedChar, possibleCurrentSignatureHelpSessionKind with
// Generally ' ' indicates a function application, but it's also used commonly after a comma in a method call.
// This means that the adjusted position relative to the caret could be a ',' or a '(' or '<',
// which would mean we're already inside of a method call - not a function argument. So we bail if that's the case.
- | Some ' ' when adjustedColumnChar <> ',' && adjustedColumnChar <> '(' && adjustedColumnChar <> '<' ->
+ | Some ' ', None when adjustedColumnChar <> ',' && adjustedColumnChar <> '(' && adjustedColumnChar <> '<' ->
+ return!
+ FSharpSignatureHelpProvider.ProvideParametersAsyncAux(
+ parseResults,
+ checkFileResults,
+ document.Id,
+ defines,
+ documentationBuilder,
+ sourceText,
+ caretPosition,
+ adjustedColumnInSource,
+ filePath)
+ | _, Some FunctionApplication when adjustedColumnChar <> ',' && adjustedColumnChar <> '(' && adjustedColumnChar <> '<' ->
return!
FSharpSignatureHelpProvider.ProvideParametersAsyncAux(
parseResults,
@@ -510,46 +532,63 @@ type internal FSharpSignatureHelpProvider
Some triggerInfo.TriggerCharacter.Value
else None
- let! signatureHelpData =
- FSharpSignatureHelpProvider.ProvideSignatureHelp(
- document,
- defines,
- checker,
- documentationBuilder,
- sourceText,
- position,
- projectOptions,
- document.FilePath,
- textVersion.GetHashCode(),
- triggerTypedChar)
- let items =
- signatureHelpData.SignatureHelpItems
- |> Array.map (fun item ->
- let parameters =
- item.Parameters
- |> Array.map (fun paramInfo ->
- FSharpSignatureHelpParameter(
- paramInfo.ParameterName,
- paramInfo.IsOptional,
- documentationFactory = (fun _ -> paramInfo.Documentation :> seq<_>),
- displayParts = paramInfo.DisplayParts))
+ let doWork () =
+ async {
+ let! signatureHelpDataOpt =
+ FSharpSignatureHelpProvider.ProvideSignatureHelp(
+ document,
+ defines,
+ checker,
+ documentationBuilder,
+ sourceText,
+ position,
+ projectOptions,
+ document.FilePath,
+ textVersion.GetHashCode(),
+ triggerTypedChar,
+ possibleCurrentSignatureHelpSessionKind)
+ match signatureHelpDataOpt with
+ | None ->
+ possibleCurrentSignatureHelpSessionKind <- None
+ return None
+ | Some signatureHelpData ->
+ let items =
+ signatureHelpData.SignatureHelpItems
+ |> Array.map (fun item ->
+ let parameters =
+ item.Parameters
+ |> Array.map (fun paramInfo ->
+ FSharpSignatureHelpParameter(
+ paramInfo.ParameterName,
+ paramInfo.IsOptional,
+ documentationFactory = (fun _ -> paramInfo.Documentation :> seq<_>),
+ displayParts = paramInfo.DisplayParts))
- FSharpSignatureHelpItem(
- isVariadic=item.HasParamArrayArg,
- documentationFactory=(fun _ -> item.Documentation :> seq<_>),
- prefixParts=item.PrefixParts,
- separatorParts=item.SeparatorParts,
- suffixParts=item.SuffixParts,
- parameters=parameters,
- descriptionParts=item.MainDescription))
-
- return
- FSharpSignatureHelpItems(
- items,
- signatureHelpData.ApplicableSpan,
- signatureHelpData.ArgumentIndex,
- signatureHelpData.ArgumentCount,
- Option.toObj signatureHelpData.ArgumentName)
+ FSharpSignatureHelpItem(
+ isVariadic=item.HasParamArrayArg,
+ documentationFactory=(fun _ -> item.Documentation :> seq<_>),
+ prefixParts=item.PrefixParts,
+ separatorParts=item.SeparatorParts,
+ suffixParts=item.SuffixParts,
+ parameters=parameters,
+ descriptionParts=item.MainDescription))
+
+ match signatureHelpData.CurrentSignatureHelpSessionKind with
+ | MethodCall ->
+ possibleCurrentSignatureHelpSessionKind <- Some MethodCall
+ | FunctionApplication ->
+ possibleCurrentSignatureHelpSessionKind <- Some FunctionApplication
+
+ return
+ FSharpSignatureHelpItems(
+ items,
+ signatureHelpData.ApplicableSpan,
+ signatureHelpData.ArgumentIndex,
+ signatureHelpData.ArgumentCount,
+ Option.toObj signatureHelpData.ArgumentName)
+ |> Some
+ }
+ return! doWork ()
}
|> Async.map Option.toObj
|> RoslynHelpers.StartAsyncAsTask cancellationToken
diff --git a/vsintegration/src/FSharp.Editor/FSharp.Editor.fsproj b/vsintegration/src/FSharp.Editor/FSharp.Editor.fsproj
index 474b952c478..5b81796d8d5 100644
--- a/vsintegration/src/FSharp.Editor/FSharp.Editor.fsproj
+++ b/vsintegration/src/FSharp.Editor/FSharp.Editor.fsproj
@@ -46,6 +46,7 @@
+
diff --git a/vsintegration/src/FSharp.Editor/LanguageService/FSharpCheckerProvider.fs b/vsintegration/src/FSharp.Editor/LanguageService/FSharpCheckerProvider.fs
index 56c074d78b2..f3212db489f 100644
--- a/vsintegration/src/FSharp.Editor/LanguageService/FSharpCheckerProvider.fs
+++ b/vsintegration/src/FSharp.Editor/LanguageService/FSharpCheckerProvider.fs
@@ -26,6 +26,8 @@ type internal FSharpCheckerProvider
settings: EditorOptions
) =
+ let metadataAsSource = FSharpMetadataAsSourceService()
+
let tryGetMetadataSnapshot (path, timeStamp) =
try
let md = Microsoft.CodeAnalysis.ExternalAccess.FSharp.LanguageServices.FSharpVisualStudioWorkspaceExtensions.GetMetadata(workspace, path, timeStamp)
@@ -85,3 +87,5 @@ type internal FSharpCheckerProvider
member this.Checker = checker.Value
+ member _.MetadataAsSource = metadataAsSource
+
diff --git a/vsintegration/src/FSharp.Editor/LanguageService/FSharpProjectOptionsManager.fs b/vsintegration/src/FSharp.Editor/LanguageService/FSharpProjectOptionsManager.fs
index a35323f9de2..c077def059a 100644
--- a/vsintegration/src/FSharp.Editor/LanguageService/FSharpProjectOptionsManager.fs
+++ b/vsintegration/src/FSharp.Editor/LanguageService/FSharpProjectOptionsManager.fs
@@ -433,3 +433,5 @@ type internal FSharpProjectOptionsManager
reactor.SetCpsCommandLineOptions(projectId, sourcePaths, options.ToArray())
member _.Checker = checkerProvider.Checker
+
+ member _.MetadataAsSource = checkerProvider.MetadataAsSource
diff --git a/vsintegration/src/FSharp.Editor/LanguageService/MetadataAsSource.fs b/vsintegration/src/FSharp.Editor/LanguageService/MetadataAsSource.fs
new file mode 100644
index 00000000000..b1e0df38153
--- /dev/null
+++ b/vsintegration/src/FSharp.Editor/LanguageService/MetadataAsSource.fs
@@ -0,0 +1,156 @@
+// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information.
+
+namespace Microsoft.VisualStudio.FSharp.Editor
+
+open System
+open System.Threading
+open System.Collections.Immutable
+open System.Diagnostics
+open System.IO
+open System.Linq
+open System.Text
+open System.Runtime.InteropServices
+open System.Reflection.PortableExecutable
+
+open Microsoft.CodeAnalysis
+open Microsoft.CodeAnalysis.FindSymbols
+open Microsoft.CodeAnalysis.Text
+open Microsoft.CodeAnalysis.Navigation
+open Microsoft.CodeAnalysis.ExternalAccess.FSharp.Navigation
+open Microsoft.VisualStudio.ComponentModelHost
+
+open Microsoft.VisualStudio
+open Microsoft.VisualStudio.Editor
+open Microsoft.VisualStudio.Threading
+open Microsoft.VisualStudio.Shell
+open Microsoft.VisualStudio.Shell.Interop
+open Microsoft.VisualStudio.TextManager.Interop
+
+open FSharp.Compiler.SourceCodeServices
+open FSharp.Compiler.Text
+
+module internal MetadataAsSource =
+
+ open Microsoft.CodeAnalysis.CSharp
+ open ICSharpCode.Decompiler
+ open ICSharpCode.Decompiler.CSharp
+ open ICSharpCode.Decompiler.Metadata
+ open ICSharpCode.Decompiler.CSharp.Transforms
+ open ICSharpCode.Decompiler.TypeSystem
+
+ let generateTemporaryCSharpDocument (asmIdentity: AssemblyIdentity, name: string, metadataReferences) =
+ let rootPath = Path.Combine(Path.GetTempPath(), "MetadataAsSource")
+ let extension = ".cs"
+ let directoryName = Guid.NewGuid().ToString("N")
+ let temporaryFilePath = Path.Combine(rootPath, directoryName, name + extension)
+
+ let projectId = ProjectId.CreateNewId()
+
+ let parseOptions = CSharpParseOptions.Default.WithLanguageVersion(Microsoft.CodeAnalysis.CSharp.LanguageVersion.Preview)
+ // Just say it's always a DLL since we probably won't have a Main method
+ let compilationOptions = Microsoft.CodeAnalysis.CSharp.CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary)
+
+ // We need to include the version information of the assembly so InternalsVisibleTo and stuff works
+ let assemblyInfoDocumentId = DocumentId.CreateNewId(projectId)
+ let assemblyInfoFileName = "AssemblyInfo" + extension
+ let assemblyInfoString = String.Format(@"[assembly: System.Reflection.AssemblyVersion(""{0}"")]", asmIdentity.Version)
+
+ let assemblyInfoSourceTextContainer = SourceText.From(assemblyInfoString, Encoding.UTF8).Container
+
+ let assemblyInfoDocument =
+ DocumentInfo.Create(
+ assemblyInfoDocumentId,
+ assemblyInfoFileName,
+ loader = TextLoader.From(assemblyInfoSourceTextContainer, VersionStamp.Default))
+
+ let generatedDocumentId = DocumentId.CreateNewId(projectId)
+ let documentInfo =
+ DocumentInfo.Create(
+ generatedDocumentId,
+ Path.GetFileName(temporaryFilePath),
+ filePath = temporaryFilePath,
+ loader = FileTextLoader(temporaryFilePath, Encoding.UTF8))
+
+ let projectInfo =
+ ProjectInfo.Create(
+ projectId,
+ VersionStamp.Default,
+ name = asmIdentity.Name,
+ assemblyName = asmIdentity.Name,
+ language = LanguageNames.CSharp,
+ compilationOptions = compilationOptions,
+ parseOptions = parseOptions,
+ documents = [|assemblyInfoDocument;documentInfo|],
+ metadataReferences = metadataReferences)
+
+ (projectInfo, documentInfo)
+
+ let decompileCSharp (symbolFullTypeName: string, assemblyLocation: string) =
+ let logger = new StringBuilder()
+
+ // Initialize a decompiler with default settings.
+ let decompiler = CSharpDecompiler(assemblyLocation, DecompilerSettings())
+ // Escape invalid identifiers to prevent Roslyn from failing to parse the generated code.
+ // (This happens for example, when there is compiler-generated code that is not yet recognized/transformed by the decompiler.)
+ decompiler.AstTransforms.Add(new EscapeInvalidIdentifiers())
+
+ let fullTypeName = FullTypeName(symbolFullTypeName)
+
+ // Try to decompile; if an exception is thrown the caller will handle it
+ let text = decompiler.DecompileTypeAsString(fullTypeName)
+
+ let text = text + "#if false // " + Environment.NewLine
+ let text = text + logger.ToString()
+ let text = text + "#endif" + Environment.NewLine
+
+ SourceText.From(text)
+
+ let showDocument (filePath, name, serviceProvider: IServiceProvider) =
+ let vsRunningDocumentTable4 = serviceProvider.GetService()
+ let fileAlreadyOpen = vsRunningDocumentTable4.IsMonikerValid(filePath)
+
+ let openDocumentService = serviceProvider.GetService()
+
+ let (_, _, _, _, windowFrame) = openDocumentService.OpenDocumentViaProject(filePath, ref VSConstants.LOGVIEWID.TextView_guid)
+
+ let componentModel = serviceProvider.GetService()
+ let editorAdaptersFactory = componentModel.GetService();
+ let documentCookie = vsRunningDocumentTable4.GetDocumentCookie(filePath)
+ let vsTextBuffer = vsRunningDocumentTable4.GetDocumentData(documentCookie) :?> IVsTextBuffer
+ let textBuffer = editorAdaptersFactory.GetDataBuffer(vsTextBuffer)
+
+ if not fileAlreadyOpen then
+ ErrorHandler.ThrowOnFailure(windowFrame.SetProperty(int __VSFPROPID5.VSFPROPID_IsProvisional, true)) |> ignore
+ ErrorHandler.ThrowOnFailure(windowFrame.SetProperty(int __VSFPROPID5.VSFPROPID_OverrideCaption, name)) |> ignore
+ ErrorHandler.ThrowOnFailure(windowFrame.SetProperty(int __VSFPROPID5.VSFPROPID_OverrideToolTip, name)) |> ignore
+
+ windowFrame.Show() |> ignore
+
+ let textContainer = textBuffer.AsTextContainer()
+ let mutable workspace = Unchecked.defaultof<_>
+ if Workspace.TryGetWorkspace(textContainer, &workspace) then
+ let solution = workspace.CurrentSolution
+ let documentId = workspace.GetDocumentIdInCurrentContext(textContainer)
+ match box documentId with
+ | null -> None
+ | _ -> solution.GetDocument(documentId) |> Some
+ else
+ None
+
+[]
+type internal FSharpMetadataAsSourceService() =
+
+ member val CSharpFiles = System.Collections.Concurrent.ConcurrentDictionary(StringComparer.OrdinalIgnoreCase)
+
+ member this.ShowCSharpDocument(projInfo: ProjectInfo, docInfo: DocumentInfo, text: Text.SourceText) =
+ let _ =
+ let directoryName = Path.GetDirectoryName(docInfo.FilePath)
+ if Directory.Exists(directoryName) |> not then
+ Directory.CreateDirectory(directoryName) |> ignore
+ use fileStream = new FileStream(docInfo.FilePath, IO.FileMode.Create)
+ use writer = new StreamWriter(fileStream)
+ text.Write(writer)
+
+ this.CSharpFiles.[docInfo.FilePath] <- (projInfo, docInfo)
+
+ MetadataAsSource.showDocument(docInfo.FilePath, docInfo.Name, ServiceProvider.GlobalProvider)
\ No newline at end of file
diff --git a/vsintegration/src/FSharp.Editor/LanguageService/SingleFileWorkspaceMap.fs b/vsintegration/src/FSharp.Editor/LanguageService/SingleFileWorkspaceMap.fs
index 5947c59b8ae..0e565801fd3 100644
--- a/vsintegration/src/FSharp.Editor/LanguageService/SingleFileWorkspaceMap.fs
+++ b/vsintegration/src/FSharp.Editor/LanguageService/SingleFileWorkspaceMap.fs
@@ -33,11 +33,33 @@ type internal SingleFileWorkspaceMap(workspace: VisualStudioWorkspace,
projectContext.AddSourceFile(filePath, sourceCodeKind = createSourceCodeKind filePath)
projectContext
+ let createCSharpMetadataProjectContext (projInfo: ProjectInfo) (docInfo: DocumentInfo) =
+ let projectContext = projectContextFactory.CreateProjectContext(LanguageNames.CSharp, projInfo.Id.ToString(), projInfo.FilePath, Guid.NewGuid(), null, null)
+ projectContext.DisplayName <- projInfo.Name
+ projectContext.AddSourceFile(docInfo.FilePath, sourceCodeKind = SourceCodeKind.Regular)
+
+ for metaRef in projInfo.MetadataReferences do
+ match metaRef with
+ | :? PortableExecutableReference as peRef ->
+ projectContext.AddMetadataReference(peRef.FilePath, MetadataReferenceProperties.Assembly)
+ | _ ->
+ ()
+
+ projectContext
+
do
miscFilesWorkspace.DocumentOpened.Add(fun args ->
let document = args.Document
+
if document.Project.Language = FSharpConstants.FSharpLanguageName && workspace.CurrentSolution.GetDocumentIdsWithFilePath(document.FilePath).Length = 0 then
files.[document.FilePath] <- createProjectContext document.FilePath
+
+ if optionsManager.MetadataAsSource.CSharpFiles.ContainsKey(document.FilePath) && workspace.CurrentSolution.GetDocumentIdsWithFilePath(document.FilePath).Length = 0 then
+ match optionsManager.MetadataAsSource.CSharpFiles.TryGetValue(document.FilePath) with
+ | true, (projInfo, docInfo) ->
+ files.[document.FilePath] <- createCSharpMetadataProjectContext projInfo docInfo
+ | _ ->
+ ()
)
workspace.DocumentOpened.Add(fun args ->
@@ -57,6 +79,8 @@ type internal SingleFileWorkspaceMap(workspace: VisualStudioWorkspace,
optionsManager.ClearSingleFileOptionsCache(document.Id)
projectContext.Dispose()
| _ -> ()
+
+ optionsManager.MetadataAsSource.CSharpFiles.TryRemove(document.FilePath) |> ignore
)
do
diff --git a/vsintegration/src/FSharp.Editor/Navigation/GoToDefinition.fs b/vsintegration/src/FSharp.Editor/Navigation/GoToDefinition.fs
index 00b8152934f..d5166440213 100644
--- a/vsintegration/src/FSharp.Editor/Navigation/GoToDefinition.fs
+++ b/vsintegration/src/FSharp.Editor/Navigation/GoToDefinition.fs
@@ -8,19 +8,28 @@ open System.Collections.Immutable
open System.Diagnostics
open System.IO
open System.Linq
+open System.Text
open System.Runtime.InteropServices
+open System.Reflection.PortableExecutable
open Microsoft.CodeAnalysis
open Microsoft.CodeAnalysis.FindSymbols
open Microsoft.CodeAnalysis.Text
open Microsoft.CodeAnalysis.Navigation
open Microsoft.CodeAnalysis.ExternalAccess.FSharp.Navigation
+open Microsoft.VisualStudio.ComponentModelHost
+open Microsoft.VisualStudio
+open Microsoft.VisualStudio.Editor
+open Microsoft.VisualStudio.Threading
+open Microsoft.VisualStudio.Shell
open Microsoft.VisualStudio.Shell.Interop
+open Microsoft.VisualStudio.TextManager.Interop
open FSharp.Compiler.SourceCodeServices
open FSharp.Compiler.Text
+
module private Symbol =
let fullName (root: ISymbol) : string =
let rec inner parts (sym: ISymbol) =
@@ -145,6 +154,11 @@ type internal StatusBar(statusBar: IVsStatusbar) =
type internal FSharpGoToDefinitionNavigableItem(document, sourceSpan) =
inherit FSharpNavigableItem(Glyph.BasicFile, ImmutableArray.Empty, document, sourceSpan)
+[]
+type internal FSharpGoToDefinitionResult =
+ | NavigableItem of FSharpNavigableItem
+ | ExternalAssembly of ProjectInfo * DocumentInfo * FSharpSymbolUse * FSharpExternalSymbol
+
type internal GoToDefinition(checker: FSharpChecker, projectInfoManager: FSharpProjectOptionsManager) =
let userOpName = "GoToDefinition"
@@ -241,23 +255,28 @@ type internal GoToDefinition(checker: FSharpChecker, projectInfoManager: FSharpP
match declarations with
| FSharpFindDeclResult.ExternalDecl (assembly, targetExternalSym) ->
- let! project = originDocument.Project.Solution.Projects |> Seq.tryFind (fun p -> p.AssemblyName.Equals(assembly, StringComparison.OrdinalIgnoreCase))
- let! symbols = SymbolFinder.FindSourceDeclarationsAsync(project, fun _ -> true)
-
- let roslynSymbols =
- symbols
- |> Seq.collect ExternalSymbol.ofRoslynSymbol
- |> Array.ofSeq
-
- let! symbol =
- roslynSymbols
- |> Seq.tryPick (fun (sym, externalSym) ->
- if externalSym = targetExternalSym then Some sym
- else None
- )
-
- let! location = symbol.Locations |> Seq.tryHead
- return (FSharpGoToDefinitionNavigableItem(project.GetDocument(location.SourceTree), location.SourceSpan), idRange)
+ let projectOpt = originDocument.Project.Solution.Projects |> Seq.tryFind (fun p -> p.AssemblyName.Equals(assembly, StringComparison.OrdinalIgnoreCase))
+ match projectOpt with
+ | Some project ->
+ let! symbols = SymbolFinder.FindSourceDeclarationsAsync(project, fun _ -> true)
+
+ let roslynSymbols =
+ symbols
+ |> Seq.collect ExternalSymbol.ofRoslynSymbol
+ |> Array.ofSeq
+
+ let! symbol =
+ roslynSymbols
+ |> Seq.tryPick (fun (sym, externalSym) ->
+ if externalSym = targetExternalSym then Some sym
+ else None
+ )
+
+ let! location = symbol.Locations |> Seq.tryHead
+ return (FSharpGoToDefinitionResult.NavigableItem(FSharpGoToDefinitionNavigableItem(project.GetDocument(location.SourceTree), location.SourceSpan)), idRange)
+ | _ ->
+ let tmpProjInfo, tmpDocId = MetadataAsSource.generateTemporaryCSharpDocument(AssemblyIdentity(targetSymbolUse.Symbol.Assembly.QualifiedName), targetSymbolUse.Symbol.DisplayName, originDocument.Project.MetadataReferences)
+ return (FSharpGoToDefinitionResult.ExternalAssembly(tmpProjInfo, tmpDocId, targetSymbolUse, targetExternalSym), idRange)
| FSharpFindDeclResult.DeclFound targetRange ->
// if goto definition is called at we are alread at the declaration location of a symbol in
@@ -275,7 +294,7 @@ type internal GoToDefinition(checker: FSharpChecker, projectInfoManager: FSharpP
let! implTextSpan = RoslynHelpers.TryFSharpRangeToTextSpan (implSourceText, targetRange)
let navItem = FSharpGoToDefinitionNavigableItem (implDocument, implTextSpan)
- return (navItem, idRange)
+ return (FSharpGoToDefinitionResult.NavigableItem(navItem), idRange)
else // jump from implementation to the corresponding signature
let declarations = checkFileResults.GetDeclarationLocation (fcsTextLineNumber, lexerSymbol.Ident.idRange.EndColumn, textLineString, lexerSymbol.FullIsland, true)
match declarations with
@@ -284,7 +303,7 @@ type internal GoToDefinition(checker: FSharpChecker, projectInfoManager: FSharpP
let! sigSourceText = sigDocument.GetTextAsync () |> liftTaskAsync
let! sigTextSpan = RoslynHelpers.TryFSharpRangeToTextSpan (sigSourceText, targetRange)
let navItem = FSharpGoToDefinitionNavigableItem (sigDocument, sigTextSpan)
- return (navItem, idRange)
+ return (FSharpGoToDefinitionResult.NavigableItem(navItem), idRange)
| _ ->
return! None
// when the target range is different follow the navigation convention of
@@ -297,7 +316,7 @@ type internal GoToDefinition(checker: FSharpChecker, projectInfoManager: FSharpP
// if the gotodef call originated from a signature and the returned target is a signature, navigate there
if isSignatureFile targetRange.FileName && preferSignature then
let navItem = FSharpGoToDefinitionNavigableItem (sigDocument, sigTextSpan)
- return (navItem, idRange)
+ return (FSharpGoToDefinitionResult.NavigableItem(navItem), idRange)
else // we need to get an FSharpSymbol from the targetRange found in the signature
// that symbol will be used to find the destination in the corresponding implementation file
let implFilePath =
@@ -314,7 +333,7 @@ type internal GoToDefinition(checker: FSharpChecker, projectInfoManager: FSharpP
let! implTextSpan = RoslynHelpers.TryFSharpRangeToTextSpan (implSourceText, targetRange)
let navItem = FSharpGoToDefinitionNavigableItem (implDocument, implTextSpan)
- return (navItem, idRange)
+ return (FSharpGoToDefinitionResult.NavigableItem(navItem), idRange)
| _ ->
return! None
}
@@ -330,8 +349,7 @@ type internal GoToDefinition(checker: FSharpChecker, projectInfoManager: FSharpP
member this.FindDefinitionsForPeekTask(originDocument: Document, position: int, cancellationToken: CancellationToken) =
this.FindDefinitionAtPosition(originDocument, position)
|> Async.map (
- Option.map (fun (navItem, _) -> navItem :> FSharpNavigableItem)
- >> Option.toArray
+ Option.toArray
>> Array.toSeq)
|> RoslynHelpers.StartAsyncAsTask cancellationToken
@@ -343,7 +361,7 @@ type internal GoToDefinition(checker: FSharpChecker, projectInfoManager: FSharpP
/// Navigate to the positon of the textSpan in the provided document
/// used by quickinfo link navigation when the tooltip contains the correct destination range.
- member _.TryNavigateToTextSpan(document: Document, textSpan: TextSpan, statusBar: StatusBar) =
+ member _.TryNavigateToTextSpan(document: Document, textSpan: Microsoft.CodeAnalysis.Text.TextSpan, statusBar: StatusBar) =
let navigableItem = FSharpGoToDefinitionNavigableItem(document, textSpan)
let workspace = document.Project.Solution.Workspace
let navigationService = workspace.Services.GetService()
diff --git a/vsintegration/src/FSharp.Editor/Navigation/GoToDefinitionService.fs b/vsintegration/src/FSharp.Editor/Navigation/GoToDefinitionService.fs
index e8bb0d1fdc9..ba377a3929a 100644
--- a/vsintegration/src/FSharp.Editor/Navigation/GoToDefinitionService.fs
+++ b/vsintegration/src/FSharp.Editor/Navigation/GoToDefinitionService.fs
@@ -2,18 +2,24 @@
namespace Microsoft.VisualStudio.FSharp.Editor
+open System
open System.Composition
+open System.IO
open System.Threading
open System.Threading.Tasks
open Microsoft.CodeAnalysis
+open Microsoft.CodeAnalysis.Text
open Microsoft.CodeAnalysis.Editor
open Microsoft.CodeAnalysis.Host.Mef
open Microsoft.CodeAnalysis.ExternalAccess.FSharp.Editor
+open Microsoft.CodeAnalysis.ExternalAccess.FSharp.Navigation
open Microsoft.VisualStudio.Shell
open Microsoft.VisualStudio.Shell.Interop
-open System
+open Microsoft.VisualStudio.LanguageServices
+
+open FSharp.Compiler.SourceCodeServices
[)>]
[)>]
@@ -25,12 +31,22 @@ type internal FSharpGoToDefinitionService
) =
let gtd = GoToDefinition(checkerProvider.Checker, projectInfoManager)
- let statusBar = StatusBar(ServiceProvider.GlobalProvider.GetService())
+ let statusBar = StatusBar(ServiceProvider.GlobalProvider.GetService())
+ let metadataAsSourceService = checkerProvider.MetadataAsSource
interface IFSharpGoToDefinitionService with
/// Invoked with Peek Definition.
member _.FindDefinitionsAsync (document: Document, position: int, cancellationToken: CancellationToken) =
- gtd.FindDefinitionsForPeekTask(document, position, cancellationToken)
+ let task = gtd.FindDefinitionsForPeekTask(document, position, cancellationToken)
+ task.Wait(cancellationToken)
+ let results = task.Result
+ results
+ |> Seq.choose(fun (result, _) ->
+ match result with
+ | FSharpGoToDefinitionResult.NavigableItem(navItem) -> Some navItem
+ | _ -> None
+ )
+ |> Task.FromResult
/// Invoked with Go to Definition.
/// Try to navigate to the definiton of the symbol at the symbolRange in the originDocument
@@ -44,13 +60,44 @@ type internal FSharpGoToDefinitionService
// Task.Wait throws an exception if the task is cancelled, so be sure to catch it.
try
// This call to Wait() is fine because we want to be able to provide the error message in the status bar.
- gtdTask.Wait()
+ gtdTask.Wait(cancellationToken)
if gtdTask.Status = TaskStatus.RanToCompletion && gtdTask.Result.IsSome then
- let item, _ = gtdTask.Result.Value
- gtd.NavigateToItem(item, statusBar)
+ let result, _ = gtdTask.Result.Value
+ match result with
+ | FSharpGoToDefinitionResult.NavigableItem(navItem) ->
+ gtd.NavigateToItem(navItem, statusBar)
+ // 'true' means do it, like Sheev Palpatine would want us to.
+ true
+ | FSharpGoToDefinitionResult.ExternalAssembly(tmpProjInfo, tmpDocInfo, targetSymbolUse, targetExternalSymbol) ->
+ match targetSymbolUse.Symbol.Assembly.FileName with
+ | Some targetSymbolAssemblyFileName ->
+ try
+ let symbolFullTypeName =
+ match targetExternalSymbol with
+ | FSharpExternalSymbol.Constructor(tyName, _)
+ | FSharpExternalSymbol.Event(tyName, _)
+ | FSharpExternalSymbol.Field(tyName, _)
+ | FSharpExternalSymbol.Method(tyName, _, _, _)
+ | FSharpExternalSymbol.Property(tyName, _)
+ | FSharpExternalSymbol.Type(tyName) -> tyName
- // 'true' means do it, like Sheev Palpatine would want us to.
- true
+ let text = MetadataAsSource.decompileCSharp(symbolFullTypeName, targetSymbolAssemblyFileName)
+ let tmpShownDocOpt = metadataAsSourceService.ShowCSharpDocument(tmpProjInfo, tmpDocInfo, text)
+ match tmpShownDocOpt with
+ | Some tmpShownDoc ->
+ let navItem = FSharpGoToDefinitionNavigableItem(tmpShownDoc, TextSpan())
+ gtd.NavigateToItem(navItem, statusBar)
+ true
+ | _ ->
+ statusBar.TempMessage (SR.CannotDetermineSymbol())
+ false
+ with
+ | _ ->
+ statusBar.TempMessage (SR.CannotDetermineSymbol())
+ false
+ | _ ->
+ statusBar.TempMessage (SR.CannotDetermineSymbol())
+ false
else
statusBar.TempMessage (SR.CannotDetermineSymbol())
false
diff --git a/vsintegration/src/FSharp.Editor/Navigation/NavigableSymbolsService.fs b/vsintegration/src/FSharp.Editor/Navigation/NavigableSymbolsService.fs
index 2c7b1b7a894..941a9c30e6e 100644
--- a/vsintegration/src/FSharp.Editor/Navigation/NavigableSymbolsService.fs
+++ b/vsintegration/src/FSharp.Editor/Navigation/NavigableSymbolsService.fs
@@ -58,13 +58,17 @@ type internal FSharpNavigableSymbolSource(checkerProvider: FSharpCheckerProvider
statusBar.Clear()
if gtdTask.Status = TaskStatus.RanToCompletion && gtdTask.Result.IsSome then
- let navigableItem, range = gtdTask.Result.Value
+ let result, range = gtdTask.Result.Value
let declarationTextSpan = RoslynHelpers.FSharpRangeToTextSpan(sourceText, range)
let declarationSpan = Span(declarationTextSpan.Start, declarationTextSpan.Length)
let symbolSpan = SnapshotSpan(snapshot, declarationSpan)
- return FSharpNavigableSymbol(navigableItem, symbolSpan, gtd, statusBar) :> INavigableSymbol
+ match result with
+ | FSharpGoToDefinitionResult.NavigableItem(navItem) ->
+ return FSharpNavigableSymbol(navItem, symbolSpan, gtd, statusBar) :> INavigableSymbol
+ | _ ->
+ return null
else
statusBar.TempMessage(SR.CannotDetermineSymbol())
diff --git a/vsintegration/tests/MockTypeProviders/DummyProviderForLanguageServiceTesting/DummyProviderForLanguageServiceTesting.fsproj b/vsintegration/tests/MockTypeProviders/DummyProviderForLanguageServiceTesting/DummyProviderForLanguageServiceTesting.fsproj
index 5bdfd8af56f..84b50e8a6a7 100644
--- a/vsintegration/tests/MockTypeProviders/DummyProviderForLanguageServiceTesting/DummyProviderForLanguageServiceTesting.fsproj
+++ b/vsintegration/tests/MockTypeProviders/DummyProviderForLanguageServiceTesting/DummyProviderForLanguageServiceTesting.fsproj
@@ -5,7 +5,7 @@
net472
true
- --nowarn:3390 --nowarn:3218
+ $(OtherFlags) --nowarn:3390 --nowarn:3218