diff --git a/.gitignore b/.gitignore index 964cde2fc6..857182a3dc 100644 --- a/.gitignore +++ b/.gitignore @@ -1,12 +1,9 @@ -# Downloaded packages and build tools. -/lkg -/packages -/Tools +# output location +artifacts/ + +packages/ /tests/scripts/current -/release -/debug -/Proto # Patches that may have been generated by scripts. # (These aren't generally useful to commit directly; if anything, they should be applied.) @@ -218,7 +215,6 @@ times /tests/fsharpqa/testenv/bin/System.ValueTuple.dll source_link.json .vs/ -/VSRelease/net40/bin System.ValueTuple.dll tests/fsharpqa/testenv/bin/System.ValueTuple.dll lib/netcore/fsc/bin/ diff --git a/.vsts-pr.yaml b/.vsts-pr.yaml index 67f78e6df0..44c277a394 100644 --- a/.vsts-pr.yaml +++ b/.vsts-pr.yaml @@ -1,31 +1,34 @@ -phases: -- phase: Linux - queue: - name: Hosted Linux Preview - timeoutInMinutes: 90 - parallel: 2 +jobs: +- job: Linux + pool: + vmImage: ubuntu-16.04 + timeoutInMinutes: 90 + strategy: + maxParallel: 2 matrix: - release_default: - _command: ./mono/cibuild.sh - _args: release + dotnet_sdk: + _command: make + _args: Configuration=release + # disabled until it can be properly fixed release_fcs: _command: ./fcs/build.sh _args: Build steps: - - script: $(_command) $(_args) - - task: PublishBuildArtifacts@1 - inputs: - PathtoPublish: '$(Build.SourcesDirectory)/tests/TestResults' - ArtifactName: 'Linux $(_command) $(_args)' - publishLocation: Container - continueOnError: true - condition: failed() + - script: $(_command) $(_args) + - task: PublishBuildArtifacts@1 + inputs: + PathtoPublish: '$(Build.SourcesDirectory)/artifacts/TestResults' + ArtifactName: 'Linux $(_command) $(_args)' + publishLocation: Container + continueOnError: true + condition: failed() -- phase: Windows - queue: - name: Hosted VS2017 - timeoutInMinutes: 90 - parallel: 7 +- job: Windows + pool: + vmImage: vs2017-win2016 + timeoutInMinutes: 120 + strategy: + maxParallel: 7 matrix: ci_part1: _command: build.cmd @@ -49,11 +52,11 @@ phases: _command: fcs\build.cmd _args: TestAndNuget steps: - - script: $(_command) $(_args) - - task: PublishBuildArtifacts@1 - inputs: - PathtoPublish: '$(Build.SourcesDirectory)\tests\TestResults' - ArtifactName: 'Windows $(_command) $(_args)' - publishLocation: Container - continueOnError: true - condition: failed() + - script: $(_command) $(_args) + - task: PublishBuildArtifacts@1 + inputs: + PathtoPublish: '$(Build.SourcesDirectory)\artifacts\TestResults' + ArtifactName: 'Windows $(_command) $(_args)' + publishLocation: Container + continueOnError: true + condition: failed() diff --git a/CoordinateXlif.targets b/CoordinateXlif.targets new file mode 100644 index 0000000000..ea1ed17aaa --- /dev/null +++ b/CoordinateXlif.targets @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/FSharp.Directory.Build.props b/FSharp.Directory.Build.props new file mode 100644 index 0000000000..e9c2a5c5e9 --- /dev/null +++ b/FSharp.Directory.Build.props @@ -0,0 +1,6 @@ + + + + + + diff --git a/FSharp.Directory.Build.targets b/FSharp.Directory.Build.targets new file mode 100644 index 0000000000..84125426d5 --- /dev/null +++ b/FSharp.Directory.Build.targets @@ -0,0 +1,7 @@ + + + + + + + diff --git a/FSharp.Profiles.props b/FSharp.Profiles.props new file mode 100644 index 0000000000..2e2edb7370 --- /dev/null +++ b/FSharp.Profiles.props @@ -0,0 +1,53 @@ + + + + + + $(DefineConstants);CROSS_PLATFORM_COMPILER + $(DefineConstants);ENABLE_MONO_SUPPORT + $(DefineConstants);BE_SECURITY_TRANSPARENT + $(DefineConstants);FX_LCIDFROMCODEPAGE + + + + $(DefineConstants);NETSTANDARD + $(DefineConstants);NETSTANDARD1_6 + $(DefineConstants);FX_NO_APP_DOMAINS + $(DefineConstants);FX_NO_ARRAY_LONG_LENGTH + $(DefineConstants);FX_NO_BEGINEND_READWRITE + $(DefineConstants);FX_NO_BINARY_SERIALIZATION + $(DefineConstants);FX_NO_CONVERTER + $(DefineConstants);FX_NO_DEFAULT_DEPENDENCY_TYPE + $(DefineConstants);FX_NO_CORHOST_SIGNER + $(DefineConstants);FX_NO_EVENTWAITHANDLE_IDISPOSABLE + $(DefineConstants);FX_NO_EXIT_CONTEXT_FLAGS + $(DefineConstants);FX_NO_HEAPTERMINATION + $(DefineConstants);FX_NO_LINKEDRESOURCES + $(DefineConstants);FX_NO_LOADER_OPTIMIZATION + $(DefineConstants);FX_NO_PARAMETERIZED_THREAD_START + $(DefineConstants);FX_NO_PDB_READER + $(DefineConstants);FX_NO_PDB_WRITER + $(DefineConstants);FX_NO_REFLECTION_MODULE_HANDLES + $(DefineConstants);FX_NO_REFLECTION_ONLY + $(DefineConstants);FX_NO_RUNTIMEENVIRONMENT + $(DefineConstants);FX_NO_SECURITY_PERMISSIONS + $(DefineConstants);FX_NO_SERVERCODEPAGES + $(DefineConstants);FX_NO_SYMBOLSTORE + $(DefineConstants);FX_NO_SYSTEM_CONFIGURATION + $(DefineConstants);FX_NO_THREAD + $(DefineConstants);FX_NO_THREADABORT + $(DefineConstants);FX_NO_WAITONE_MILLISECONDS + $(DefineConstants);FX_NO_WEB_CLIENT + $(DefineConstants);FX_NO_WIN_REGISTRY + $(DefineConstants);FX_NO_WINFORMS + $(DefineConstants);FX_NO_INDENTED_TEXT_WRITER + $(DefineConstants);FX_REDUCED_EXCEPTIONS + $(DefineConstants);FX_REDUCED_CONSOLE + $(DefineConstants);FX_RESHAPED_REFEMIT + $(DefineConstants);FX_RESHAPED_GLOBALIZATION + $(DefineConstants);FX_RESHAPED_REFLECTION + $(DefineConstants);FX_RESHAPED_MSBUILD + $(OtherFlags) --simpleresolution + + + diff --git a/FSharpBuild.Directory.Build.props b/FSharpBuild.Directory.Build.props new file mode 100644 index 0000000000..c5e4108181 --- /dev/null +++ b/FSharpBuild.Directory.Build.props @@ -0,0 +1,82 @@ + + + + + + + + + + Debug + $(MSBuildThisFileDirectory) + $(RepoRoot)src + $(RepoRoot)artifacts + $(ArtifactsDir)\toolset + $(ArtifactsDir)\bin + $(ArtifactsDir)\obj + $(ArtifactsDir)\packages + $(ArtifactsBinDir)\$(MSBuildProjectName) + $(ArtifactsObjDir)\$(MSBuildProjectName) + $(ArtifactsDir)\SymStore + $(ArtifactsBinDir)\fsc\Proto\net46 + $(ArtifactsBinDir)/fsc/Proto/netcoreapp2.1 + 4.4.0 + + + + + + $(NUGET_PACKAGES) + $(UserProfile)\.nuget\packages\ + $(HOME)/.nuget/packages/ + + $(NuGetPackageRoot)\ + $(NuGetPackageRoot)/ + + true + + + + + true + /usr/lib/mono/4.5-api + /usr/lib/mono/4.6-api + + + + + false + true + $(FSharpSourcesRoot)\fsharp\msft.pubkey + true + true + + + $(FSharpSourcesRoot)\fsharp\test.snk + false + STRONG_NAME_FSHARP_COMPILER_WITH_TEST_KEY;$(DefineConstants) + + + + + false + true + + + + + portable + fs + false + true + + + + + $(ProtoOutputPath)\Microsoft.FSharp.Targets + $(ProtoOutputPath)\Microsoft.FSharp.NetSdk.props + $(ProtoOutputPath)\Microsoft.FSharp.NetSdk.targets + $(ProtoOutputPath)\Microsoft.FSharp.Overrides.NetSdk.targets + + + diff --git a/FSharpBuild.Directory.Build.targets b/FSharpBuild.Directory.Build.targets new file mode 100644 index 0000000000..fa39d7498f --- /dev/null +++ b/FSharpBuild.Directory.Build.targets @@ -0,0 +1,42 @@ + + + + + + en;$(XlfLanguages) + + + + + $(AssetTargetFallback);net462 + + + + $(CompileDependsOn);CopyAndSubstituteTextFiles + + + + + <_ReplacementText>$([System.IO.File]::ReadAllText('%(CopyAndSubstituteText.FullPath)')) + <_ReplacementText Condition="'%(CopyAndSubstituteText.Pattern1)' != ''">$(_ReplacementText.Replace('%(CopyAndSubstituteText.Pattern1)', '%(CopyAndSubstituteText.Replacement1)')) + <_ReplacementText Condition="'%(CopyAndSubstituteText.Pattern2)' != ''">$(_ReplacementText.Replace('%(CopyAndSubstituteText.Pattern2)', '%(CopyAndSubstituteText.Replacement2)')) + + + + + + + + + + + + + + diff --git a/NuGet.Config b/NuGet.Config index f4c19635b0..8f21de1b15 100644 --- a/NuGet.Config +++ b/NuGet.Config @@ -1,13 +1,15 @@ - - - + + - + + - - \ No newline at end of file + + + + diff --git a/PublishToBlob.proj b/PublishToBlob.proj index 00bcee6335..21e8ec6eb6 100644 --- a/PublishToBlob.proj +++ b/PublishToBlob.proj @@ -10,26 +10,33 @@ Microsoft.DotNet.Build.Tasks.Feed - 2.1.0-prerelease-02419-02 + 2.2.0-beta.19066.1 - - + + + + $(MSBuildThisFileDirectory)artifacts\log\$(Configuration)\ + AnyCPU + $(Platform) + $(ArtifactsLogDir)AssetManifest\$(OS)-$(PlatformName).xml + + + AssetManifestPath="$(AssetManifestFilePath)" /> diff --git a/RoslynPackageVersion.txt b/RoslynPackageVersion.txt new file mode 100644 index 0000000000..593eafec19 --- /dev/null +++ b/RoslynPackageVersion.txt @@ -0,0 +1 @@ +2.9.0-beta8-63208-01 diff --git a/benchmarks/Benchmarks.sln b/benchmarks/Benchmarks.sln new file mode 100644 index 0000000000..5d339f7a99 --- /dev/null +++ b/benchmarks/Benchmarks.sln @@ -0,0 +1,37 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.28307.136 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "CompilerServiceBenchmarks", "CompilerServiceBenchmarks\CompilerServiceBenchmarks.fsproj", "{9A3C565C-B514-4AE0-8B01-CA80E8453EB0}" +EndProject +Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "FSharp.Core", "..\src\fsharp\FSharp.Core\FSharp.Core.fsproj", "{BB9EAE76-194A-49D8-9618-586CBE7031D9}" +EndProject +Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "FSharp.Compiler.Private", "..\src\fsharp\FSharp.Compiler.Private\FSharp.Compiler.Private.fsproj", "{F57B02B1-CF26-4D93-9211-8CEB4F1572F0}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {9A3C565C-B514-4AE0-8B01-CA80E8453EB0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {9A3C565C-B514-4AE0-8B01-CA80E8453EB0}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9A3C565C-B514-4AE0-8B01-CA80E8453EB0}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9A3C565C-B514-4AE0-8B01-CA80E8453EB0}.Release|Any CPU.Build.0 = Release|Any CPU + {BB9EAE76-194A-49D8-9618-586CBE7031D9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {BB9EAE76-194A-49D8-9618-586CBE7031D9}.Debug|Any CPU.Build.0 = Debug|Any CPU + {BB9EAE76-194A-49D8-9618-586CBE7031D9}.Release|Any CPU.ActiveCfg = Release|Any CPU + {BB9EAE76-194A-49D8-9618-586CBE7031D9}.Release|Any CPU.Build.0 = Release|Any CPU + {F57B02B1-CF26-4D93-9211-8CEB4F1572F0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F57B02B1-CF26-4D93-9211-8CEB4F1572F0}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F57B02B1-CF26-4D93-9211-8CEB4F1572F0}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F57B02B1-CF26-4D93-9211-8CEB4F1572F0}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {049A4D02-709F-418C-AD59-7FB0DBE956B1} + EndGlobalSection +EndGlobal diff --git a/benchmarks/CompilerServiceBenchmarks/CompilerServiceBenchmarks.fsproj b/benchmarks/CompilerServiceBenchmarks/CompilerServiceBenchmarks.fsproj new file mode 100644 index 0000000000..fcdd08995e --- /dev/null +++ b/benchmarks/CompilerServiceBenchmarks/CompilerServiceBenchmarks.fsproj @@ -0,0 +1,21 @@ + + + + Exe + net472 + + + + + + + + + + + + + + + + diff --git a/benchmarks/CompilerServiceBenchmarks/Program.fs b/benchmarks/CompilerServiceBenchmarks/Program.fs new file mode 100644 index 0000000000..d5e4527577 --- /dev/null +++ b/benchmarks/CompilerServiceBenchmarks/Program.fs @@ -0,0 +1,60 @@ +open System +open System.IO +open BenchmarkDotNet.Attributes +open BenchmarkDotNet.Running +open Microsoft.FSharp.Compiler.ErrorLogger +open Microsoft.FSharp.Compiler.SourceCodeServices +open System.Text + +[] +type CompilerServiceParsing() = + + let mutable checkerOpt = None + + let mutable sourceOpt = None + + let parsingOptions = + { + SourceFiles = [|"TypeChecker.fs"|] + ConditionalCompilationDefines = [] + ErrorSeverityOptions = FSharpErrorSeverityOptions.Default + IsInteractive = false + LightSyntax = None + CompilingFsLib = false + IsExe = false + } + + [] + member __.Setup() = + match checkerOpt with + | None -> checkerOpt <- Some(FSharpChecker.Create()) + | _ -> () + + match sourceOpt with + | None -> + let source = File.ReadAllText("""..\..\..\..\..\src\fsharp\TypeChecker.fs""") + sourceOpt <- Some(source) + | _ -> () + + [] + member __.ParsingSetup() = + match checkerOpt with + | None -> failwith "no checker" + | Some(checker) -> + checker.InvalidateAll() + checker.ClearLanguageServiceRootCachesAndCollectAndFinalizeAllTransients() + checker.ParseFile("dummy.fs", "dummy", parsingOptions) |> Async.RunSynchronously |> ignore + + [] + member __.Parsing() = + match checkerOpt, sourceOpt with + | None, _ -> failwith "no checker" + | _, None -> failwith "no source" + | Some(checker), Some(source) -> + let results = checker.ParseFile("TypeChecker.fs", source, parsingOptions) |> Async.RunSynchronously + if results.ParseHadErrors then failwithf "parse had errors: %A" results.Errors + +[] +let main argv = + let _ = BenchmarkRunner.Run() + 0 diff --git a/build/projects/Directory.Build.props b/build/projects/Directory.Build.props new file mode 100644 index 0000000000..bb8eac309b --- /dev/null +++ b/build/projects/Directory.Build.props @@ -0,0 +1,3 @@ + + + diff --git a/build/projects/Directory.Build.targets b/build/projects/Directory.Build.targets new file mode 100644 index 0000000000..ccd47cc0a9 --- /dev/null +++ b/build/projects/Directory.Build.targets @@ -0,0 +1,3 @@ + + + diff --git a/build/projects/Signing.proj b/build/projects/Signing.proj new file mode 100644 index 0000000000..9e981e135e --- /dev/null +++ b/build/projects/Signing.proj @@ -0,0 +1,27 @@ + + + + + net46 + $(NuGetPackageRoot)RoslynTools.SignTool\$(RoslynToolsSignToolPackageVersion)\tools\SignTool.exe + -msbuildPath "$(MSBuildBinPath)\msbuild.exe" -nugetPackagesPath "$(NuGetPackageRoot.TrimEnd('\'))" -config "$(ConfigFile)" + -testSign $(SignToolArgs) + -test $(SignToolArgs) + + + + + + + + + + + + + + + + + diff --git a/build/targets/AssemblyVersions.props b/build/targets/AssemblyVersions.props new file mode 100644 index 0000000000..b17f940a93 --- /dev/null +++ b/build/targets/AssemblyVersions.props @@ -0,0 +1,60 @@ + + + + + $([System.DateTime]::Now.ToString(yyyyMMdd.0)) + + $(BUILD_BUILDNUMBER.Replace(".DRAFT", "")) + + + <_Build_Year>$(BUILD_BUILDNUMBER.Substring(0, 4)) + <_Build_Month>$(BUILD_BUILDNUMBER.Substring(4, 2)) + <_Build_Day>$(BUILD_BUILDNUMBER.Substring(6, 2)) + <_Build_Number>$(BUILD_BUILDNUMBER.Substring(9)) + $(_Build_Year).$(_Build_Month).$(_Build_Day).$(_Build_Number) + + 4.5 + $(FSCoreMajorVersion).5 + $(FSCoreMajorVersion).0.0 + + 10.2 + $(FSPackageMajorVersion).3 + $(FSPackageVersion).0 + + 15 + 9 + $(VSMajorVersion).0 + $(VSMajorVersion).$(VSMinorVersion).0.0 + + + $(BUILD_BUILDNUMBER.Split('.')[0].Substring(2)) + $(BUILD_BUILDNUMBER.Split('.')[1].PadLeft(2, '0')) + $(BuildTimeStamp_Date)$(BuildTimeStamp_Number) + $(VSAssemblyVersion.Split('.')[0]).$(VSAssemblyVersion.Split('.')[1]).$(BUILD_BUILDNUMBER) + 42.42.42.42 + $(BuildTimeStamp_Date)-$(BuildTimeStamp_Number) + + + + + + diff --git a/build/targets/CommonPackages.targets b/build/targets/CommonPackages.targets new file mode 100644 index 0000000000..fad7b97612 --- /dev/null +++ b/build/targets/CommonPackages.targets @@ -0,0 +1,7 @@ + + + + + + + diff --git a/build/targets/ConvertPortablePdbs.targets b/build/targets/ConvertPortablePdbs.targets new file mode 100644 index 0000000000..c43042a499 --- /dev/null +++ b/build/targets/ConvertPortablePdbs.targets @@ -0,0 +1,38 @@ + + + + + + + + + $(NuGetPackageRoot)Pdb2Pdb\$(Pdb2PdbPackageVersion)\tools\Pdb2Pdb.exe + "$(TargetPath)" /out "$(SymStoreDirectory)\$(TargetName).pdb" /srcsvrvar SRC_INDEX=public + + + + + + + + + $(TargetDir)\$(TargetName).pdb + + + + + + + diff --git a/build/targets/GenerateAssemblyAttributes.targets b/build/targets/GenerateAssemblyAttributes.targets new file mode 100644 index 0000000000..7b747c9dd9 --- /dev/null +++ b/build/targets/GenerateAssemblyAttributes.targets @@ -0,0 +1,119 @@ + + + + + false + + + + + $(IntermediateOutputPath)$(MSBuildProjectName).AssemblyLevelAttributes$(DefaultLanguageSourceExtension) + + + $(NoWarn);2003 + + + + + + + + + + + + + + + + $(FSCoreVersion) + + + $(FSProductVersion) + + + $(VSAssemblyVersion) + + $(IntermediateOutputPath)$(MSBuildProjectName).AssemblyVersion$(DefaultLanguageSourceExtension) + + + + <_UseWriteCodeFragmentHack Condition="'$(OS)' == 'Unix' and '$(Language)' == 'F#'">true + + + + <_AssemblyVersionAttributes Include="System.Reflection.AssemblyCompanyAttribute"> + <_Parameter1>Microsoft Corporation + + <_AssemblyVersionAttributes Include="System.Reflection.AssemblyCopyrightAttribute"> + <_Parameter1>© Microsoft Corporation. All Rights Reserved. + + <_AssemblyVersionAttributes Include="System.Reflection.AssemblyDescriptionAttribute"> + <_Parameter1>$(AssemblyName) + + <_AssemblyVersionAttributes Include="System.Reflection.AssemblyFileVersionAttribute"> + <_Parameter1>$(Build_FileVersion) + + <_AssemblyVersionAttributes Include="System.Reflection.AssemblyInformationalVersionAttribute"> + <_Parameter1>$(MicroBuildAssemblyVersion). Commit Hash: $(GitHeadSha). + + <_AssemblyVersionAttributes Include="System.Reflection.AssemblyProductAttribute"> + <_Parameter1>Microsoft® F# + + <_AssemblyVersionAttributes Include="System.Reflection.AssemblyTitleAttribute"> + <_Parameter1>$(AssemblyName) + + <_AssemblyVersionAttributes Include="System.Reflection.AssemblyVersionAttribute"> + <_Parameter1>$(MicroBuildAssemblyVersion) + + + + + + + + + + + + + + + + + <_LinesToWrite Include="// <auto-generated>" /> + <_LinesToWrite Include="namespace FSharp" /> + <_LinesToWrite Include="open System" /> + <_LinesToWrite Include="open System.Reflection" /> + <_LinesToWrite Include="[<assembly: %(_AssemblyVersionAttributes.Identity)("%(_AssemblyVersionAttributes._Parameter1)")>]" /> + <_LinesToWrite Include="do()" /> + + + + + + + + + + + diff --git a/build/targets/GenerateInternalsVisibleTo.targets b/build/targets/GenerateInternalsVisibleTo.targets new file mode 100644 index 0000000000..4950837d36 --- /dev/null +++ b/build/targets/GenerateInternalsVisibleTo.targets @@ -0,0 +1,80 @@ + + + + $(IntermediateOutputPath)$(MSBuildProjectName).InternalsVisibleTo$(DefaultLanguageSourceExtension) + + + + + false + + + + + + <_PublicKey>002400000480000094000000060200000024000052534131000400000100010007D1FA57C4AED9F0A32E84AA0FAEFD0DE9E8FD6AEC8F87FB03766C834C99921EB23BE79AD9D5DCC1DD9AD236132102900B723CF980957FC4E177108FC607774F29E8320E92EA05ECE4E821C0A5EFE8F1645C4C0C93C1AB99285D622CAA652C1DFAD63D745D6F2DE5F17E5EAF0FC4963D261C8A12436518206DC093344D5AD293 + + + <_PublicKey>002400000480000094000000060200000024000052534131000400000100010077d32e043d184cf8cebf177201ec6fad091581a3a639a0534f1c4ebb3ab847a6b6636990224a04cf4bd1aec51ecec44cf0c8922eb5bb2ee65ec3fb9baa87e141042c96ce414f98af33508c7e24dab5b068aa802f6693881537ee0efcb5d3f1c9aaf8215ac42e92ba9a5a02574d6890d07464cb2f338b043b1c4ffe98efe069ee + + + <_InternalsVisibleToAttribute Include="System.Runtime.CompilerServices.InternalsVisibleToAttribute"> + <_Parameter1 Condition="'%(InternalsVisibleTo.Key)' != ''">%(InternalsVisibleTo.Identity), PublicKey=%(InternalsVisibleTo.Key) + <_Parameter1 Condition="'%(InternalsVisibleTo.Key)' == ''">%(InternalsVisibleTo.Identity), PublicKey=$(_PublicKey) + + + + + + + + + <_UseWriteCodeFragmentHack Condition="'$(OS)' == 'Unix' and '$(Language)' == 'F#'">true + + + + + + + + + + + + + <_LinesToWrite Include="// <auto-generated>" /> + <_LinesToWrite Include="namespace FSharp" /> + <_LinesToWrite Include="open System" /> + <_LinesToWrite Include="open System.Reflection" /> + <_LinesToWrite Include="[<assembly: %(_InternalsVisibleToAttribute.Identity)("%(_InternalsVisibleToAttribute._Parameter1)")>]" /> + <_LinesToWrite Include="do()" /> + + + + + + + + + diff --git a/build/targets/GitHash.props b/build/targets/GitHash.props new file mode 100644 index 0000000000..30f2d03b91 --- /dev/null +++ b/build/targets/GitHash.props @@ -0,0 +1,51 @@ + + + + + + + + + + $(MSBuildThisFileDirectory)..\..\ + + + + + + $(BUILD_SOURCEVERSION) + + + + + + $(GIT_COMMIT) + + + + + + <developer build> + + + + + + + <_DotGitDir>$(RepoRoot).git + <_HeadFileContent Condition="Exists('$(_DotGitDir)/HEAD')">$([System.IO.File]::ReadAllText('$(_DotGitDir)/HEAD').Trim()) + <_RefPath Condition="$(_HeadFileContent.StartsWith('ref: '))">$(_DotGitDir)/$(_HeadFileContent.Substring(5)) + $([System.IO.File]::ReadAllText('$(_RefPath)').Trim()) + $(_HeadFileContent) + + + + + diff --git a/build/targets/NGenOrCrossGen.targets b/build/targets/NGenOrCrossGen.targets new file mode 100644 index 0000000000..33dcaa3a63 --- /dev/null +++ b/build/targets/NGenOrCrossGen.targets @@ -0,0 +1,36 @@ + + + + + $(windir)\Microsoft.NET\Framework64\v4.0.30319\ngen.exe + $(windir)\Microsoft.NET\Framework\v4.0.30319\ngen.exe + + + + + + + + + + + + + + + + true + false + + + + diff --git a/build/targets/PackageVersions.props b/build/targets/PackageVersions.props new file mode 100644 index 0000000000..42a2305f6f --- /dev/null +++ b/build/targets/PackageVersions.props @@ -0,0 +1,144 @@ + + + + + + + $(RestoreSources); + https://www.myget.org/F/fsharp-daily/api/v3/index.json; + https://dotnet.myget.org/F/roslyn-master-nightly/api/v3/index.json; + https://dotnet.myget.org/F/dotnet-core/api/v3/index.json; + https://dotnet.myget.org/F/dotnet-buildtools/api/v3/index.json; + https://dotnet.myget.org/F/roslyn-tools/api/v3/index.json; + https://api.nuget.org/v3/index.json; + https://dotnet.myget.org/F/roslyn/api/v3/index.json; + https://dotnet.myget.org/F/symreader-converter/api/v3/index.json; + + + + $(PB_RestoreSource);$(RestoreSources) + $(MSBuildThisFileDirectory)..\..\artifacts\dependencyUptake\PackageVersions.props + + + $([System.IO.File]::ReadAllText('$(MSBuildThisFileDirectory)..\..\RoslynPackageVersion.txt').Trim()) + + + 1.5.0 + 4.3.0 + 4.3.0 + 4.3.0 + 4.3.0 + 4.3.0 + 4.3.0 + 4.5.0 + 4.3.0 + 4.3.0 + 4.3.0 + 1.6.0 + 4.3.0 + 1.5.0 + 4.3.0 + 4.3.0 + 4.3.0 + 4.3.0 + 4.3.0 + 4.3.0 + 4.3.0 + 4.3.0 + 4.3.0 + 4.3.0 + 4.3.0 + 4.4.0 + + + $(RoslynPackageVersion) + $(RoslynPackageVersion) + $(RoslynPackageVersion) + $(RoslynPackageVersion) + $(RoslynPackageVersion) + + + 15.8.166 + $(MicrosoftBuildOverallPackagesVersion) + $(MicrosoftBuildOverallPackagesVersion) + $(MicrosoftBuildOverallPackagesVersion) + $(MicrosoftBuildOverallPackagesVersion) + + + 8.0.1 + 14.0.25420 + 15.6.27740 + 15.0.26201-alpha + 1.1.4322 + 15.0.26201 + 15.0.26201 + 15.6.27740 + 15.6.27740 + 15.6.27740 + 8.0.50727 + 7.10.6071 + 15.0.26201 + 8.0.50727 + 2.3.6152103 + 14.3.25407 + 15.0.26201 + 15.0.26201 + 15.0.26201 + 10.0.30319 + 11.0.50727 + 15.0.25123-Dev15Preview + 7.10.6072 + 8.0.50727 + 9.0.30729 + 10.0.30319 + 11.0.61030 + 12.0.30110 + 15.6.27740 + 7.10.6071 + 8.0.50727 + 10.0.30319 + 12.0.30112 + 15.6.27740 + 15.6.27740 + 15.3.23 + 15.0.26201 + 15.3.15 + 9.0.30729 + 15.6.170 + 12.0.4 + 7.0.4 + 8.0.4 + 11.0.4 + 7.0.4 + + + 0.2.0 + 1.0.0 + 1.0.147 + 10.1.0 + 1.0.0 + + + 3.0.0-alpha3 + 1.0.30 + 1.1.0-beta1-63314-01 + 8.0.0-alpha + 2.7.0 + 2.0.3 + 15.8.0 + 1.0.0 + 4.3.0 + 9.0.1 + 3.10.1 + 3.10.0 + 3.10.1 + 1.0.0-beta2-dev3 + 5.22.2.1 + 0.2.0-beta-000081 + + + + + + + diff --git a/eng/common/CIBuild.cmd b/eng/common/CIBuild.cmd new file mode 100644 index 0000000000..56c2f25ac2 --- /dev/null +++ b/eng/common/CIBuild.cmd @@ -0,0 +1,2 @@ +@echo off +powershell -ExecutionPolicy ByPass -NoProfile -command "& """%~dp0Build.ps1""" -restore -build -test -sign -pack -publish -ci %*" \ No newline at end of file diff --git a/eng/common/PublishBuildAssets.cmd b/eng/common/PublishBuildAssets.cmd new file mode 100644 index 0000000000..3c6e4ff829 --- /dev/null +++ b/eng/common/PublishBuildAssets.cmd @@ -0,0 +1,3 @@ +@echo off +powershell -ExecutionPolicy ByPass -NoProfile -command "& """%~dp0sdk-task.ps1""" -msbuildEngine dotnet -restore -projects PublishBuildAssets.proj -ci %*" +exit /b %ErrorLevel% diff --git a/eng/common/PublishToPackageFeed.proj b/eng/common/PublishToPackageFeed.proj new file mode 100644 index 0000000000..7dc478d981 --- /dev/null +++ b/eng/common/PublishToPackageFeed.proj @@ -0,0 +1,37 @@ + + + + netcoreapp2.1 + + + + + + + + + + + + + + + + + + diff --git a/eng/common/README.md b/eng/common/README.md new file mode 100644 index 0000000000..ff49c37152 --- /dev/null +++ b/eng/common/README.md @@ -0,0 +1,28 @@ +# Don't touch this folder + + uuuuuuuuuuuuuuuuuuuu + u" uuuuuuuuuuuuuuuuuu "u + u" u$$$$$$$$$$$$$$$$$$$$u "u + u" u$$$$$$$$$$$$$$$$$$$$$$$$u "u + u" u$$$$$$$$$$$$$$$$$$$$$$$$$$$$u "u + u" u$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$u "u + u" u$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$u "u + $ $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ $ + $ $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ $ + $ $$$" ... "$... ...$" ... "$$$ ... "$$$ $ + $ $$$u `"$$$$$$$ $$$ $$$$$ $$ $$$ $$$ $ + $ $$$$$$uu "$$$$ $$$ $$$$$ $$ """ u$$$ $ + $ $$$""$$$ $$$$ $$$u "$$$" u$$ $$$$$$$$ $ + $ $$$$....,$$$$$..$$$$$....,$$$$..$$$$$$$$ $ + $ $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ $ + "u "$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$" u" + "u "$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$" u" + "u "$$$$$$$$$$$$$$$$$$$$$$$$$$$$" u" + "u "$$$$$$$$$$$$$$$$$$$$$$$$" u" + "u "$$$$$$$$$$$$$$$$$$$$" u" + "u """""""""""""""""" u" + """""""""""""""""""" + +!!! Changes made in this directory are subject to being overwritten by automation !!! + +The files in this directory are shared by all Arcade repos and managed by automation. If you need to make changes to these files, open an issue or submit a pull request to https://github.com/dotnet/arcade first. diff --git a/eng/common/build.ps1 b/eng/common/build.ps1 new file mode 100644 index 0000000000..8279dc7133 --- /dev/null +++ b/eng/common/build.ps1 @@ -0,0 +1,133 @@ +[CmdletBinding(PositionalBinding=$false)] +Param( + [string][Alias('c')]$configuration = "Debug", + [string] $projects, + [string][Alias('v')]$verbosity = "minimal", + [string] $msbuildEngine = $null, + [bool] $warnAsError = $true, + [bool] $nodeReuse = $true, + [switch][Alias('r')]$restore, + [switch] $deployDeps, + [switch][Alias('b')]$build, + [switch] $rebuild, + [switch] $deploy, + [switch] $test, + [switch] $integrationTest, + [switch] $performanceTest, + [switch] $sign, + [switch] $pack, + [switch] $publish, + [switch][Alias('bl')]$binaryLog, + [switch] $ci, + [switch] $prepareMachine, + [switch] $help, + [Parameter(ValueFromRemainingArguments=$true)][String[]]$properties +) + +. $PSScriptRoot\tools.ps1 + +function Print-Usage() { + Write-Host "Common settings:" + Write-Host " -configuration Build configuration: 'Debug' or 'Release' (short: -c)" + Write-Host " -verbosity Msbuild verbosity: q[uiet], m[inimal], n[ormal], d[etailed], and diag[nostic] (short: -v)" + Write-Host " -binaryLog Output binary log (short: -bl)" + Write-Host " -help Print help and exit" + Write-Host "" + + Write-Host "Actions:" + Write-Host " -restore Restore dependencies (short: -r)" + Write-Host " -build Build solution (short: -b)" + Write-Host " -rebuild Rebuild solution" + Write-Host " -deploy Deploy built VSIXes" + Write-Host " -deployDeps Deploy dependencies (e.g. VSIXes for integration tests)" + Write-Host " -test Run all unit tests in the solution" + Write-Host " -pack Package build outputs into NuGet packages and Willow components" + Write-Host " -integrationTest Run all integration tests in the solution" + Write-Host " -performanceTest Run all performance tests in the solution" + Write-Host " -sign Sign build outputs" + Write-Host " -publish Publish artifacts (e.g. symbols)" + Write-Host "" + + Write-Host "Advanced settings:" + Write-Host " -projects Semi-colon delimited list of sln/proj's to build. Globbing is supported (*.sln)" + Write-Host " -ci Set when running on CI server" + Write-Host " -prepareMachine Prepare machine for CI run" + Write-Host " -msbuildEngine Msbuild engine to use to run build ('dotnet', 'vs', or unspecified)." + Write-Host "" + Write-Host "Command line arguments not listed above are passed thru to msbuild." + Write-Host "The above arguments can be shortened as much as to be unambiguous (e.g. -co for configuration, -t for test, etc.)." +} + +function InitializeCustomToolset { + if (-not $restore) { + return + } + + $script = Join-Path $EngRoot "restore-toolset.ps1" + + if (Test-Path $script) { + . $script + } +} + +function Build { + $toolsetBuildProj = InitializeToolset + InitializeCustomToolset + + $bl = if ($binaryLog) { "/bl:" + (Join-Path $LogDir "Build.binlog") } else { "" } + + if ($projects) { + # Re-assign properties to a new variable because PowerShell doesn't let us append properties directly for unclear reasons. + # Explicitly set the type as string[] because otherwise PowerShell would make this char[] if $properties is empty. + [string[]] $msbuildArgs = $properties + $msbuildArgs += "/p:Projects=$projects" + $properties = $msbuildArgs + } + + MSBuild $toolsetBuildProj ` + $bl ` + /p:Configuration=$configuration ` + /p:RepoRoot=$RepoRoot ` + /p:Restore=$restore ` + /p:DeployDeps=$deployDeps ` + /p:Build=$build ` + /p:Rebuild=$rebuild ` + /p:Deploy=$deploy ` + /p:Test=$test ` + /p:Pack=$pack ` + /p:IntegrationTest=$integrationTest ` + /p:PerformanceTest=$performanceTest ` + /p:Sign=$sign ` + /p:Publish=$publish ` + /p:ContinuousIntegrationBuild=$ci ` + @properties +} + +try { + if ($help -or (($properties -ne $null) -and ($properties.Contains("/help") -or $properties.Contains("/?")))) { + Print-Usage + exit 0 + } + + if ($ci) { + $binaryLog = $true + $nodeReuse = $false + } + + # Import custom tools configuration, if present in the repo. + # Note: Import in global scope so that the script set top-level variables without qualification. + $configureToolsetScript = Join-Path $EngRoot "configure-toolset.ps1" + if (Test-Path $configureToolsetScript) { + . $configureToolsetScript + } + + Build +} +catch { + Write-Host $_ + Write-Host $_.Exception + Write-Host $_.ScriptStackTrace + ExitWithExitCode 1 +} + +ExitWithExitCode 0 diff --git a/eng/common/build.sh b/eng/common/build.sh new file mode 100755 index 0000000000..4fe8b41ed7 --- /dev/null +++ b/eng/common/build.sh @@ -0,0 +1,213 @@ +#!/usr/bin/env bash + +# Stop script if unbound variable found (use ${var:-} if intentional) +set -u + +# Stop script if command returns non-zero exit code. +# Prevents hidden errors caused by missing error code propagation. +set -e + +usage() +{ + echo "Common settings:" + echo " --configuration Build configuration: 'Debug' or 'Release' (short: --c)" + echo " --verbosity Msbuild verbosity: q[uiet], m[inimal], n[ormal], d[etailed], and diag[nostic] (short: -v)" + echo " --binaryLog Create MSBuild binary log (short: -bl)" + echo "" + echo "Actions:" + echo " --restore Restore dependencies (short: -r)" + echo " --build Build all projects (short: -b)" + echo " --rebuild Rebuild all projects" + echo " --test Run all unit tests (short: -t)" + echo " --sign Sign build outputs" + echo " --publish Publish artifacts (e.g. symbols)" + echo " --pack Package build outputs into NuGet packages and Willow components" + echo " --help Print help and exit (short: -h)" + echo "" + echo "Advanced settings:" + echo " --projects Project or solution file(s) to build" + echo " --ci Set when running on CI server" + echo " --prepareMachine Prepare machine for CI run, clean up processes after build" + echo " --nodeReuse Sets nodereuse msbuild parameter ('true' or 'false')" + echo " --warnAsError Sets warnaserror msbuild parameter ('true' or 'false')" + echo "" + echo "Command line arguments starting with '/p:' are passed through to MSBuild." +} + +source="${BASH_SOURCE[0]}" + +# resolve $source until the file is no longer a symlink +while [[ -h "$source" ]]; do + scriptroot="$( cd -P "$( dirname "$source" )" && pwd )" + source="$(readlink "$source")" + # if $source was a relative symlink, we need to resolve it relative to the path where the + # symlink file was located + [[ $source != /* ]] && source="$scriptroot/$source" +done +scriptroot="$( cd -P "$( dirname "$source" )" && pwd )" + +restore=false +build=false +rebuild=false +test=false +pack=false +publish=false +integration_test=false +performance_test=false +sign=false +public=false +ci=false + +warn_as_error=true +node_reuse=true +binary_log=false + +projects='' +configuration='Debug' +prepare_machine=false +verbosity='minimal' +properties='' + +while [[ $# > 0 ]]; do + opt="$(echo "$1" | awk '{print tolower($0)}')" + case "$opt" in + --help|-h) + usage + exit 0 + ;; + --configuration|-c) + configuration=$2 + shift + ;; + --verbosity|-v) + verbosity=$2 + shift + ;; + --binarylog|-bl) + binary_log=true + ;; + --restore|-r) + restore=true + ;; + --build|-b) + build=true + ;; + --rebuild) + rebuild=true + ;; + --pack) + pack=true + ;; + --test|-t) + test=true + ;; + --integrationtest) + integration_test=true + ;; + --performancetest) + performance_test=true + ;; + --sign) + sign=true + ;; + --publish) + publish=true + ;; + --preparemachine) + prepare_machine=true + ;; + --projects) + projects=$2 + shift + ;; + --ci) + ci=true + ;; + --warnaserror) + warn_as_error=$2 + shift + ;; + --nodereuse) + node_reuse=$2 + shift + ;; + /p:*) + properties="$properties $1" + ;; + /m:*) + properties="$properties $1" + ;; + /bl:*) + properties="$properties $1" + ;; + *) + echo "Invalid argument: $1" + usage + exit 1 + ;; + esac + + shift +done + +if [[ "$ci" == true ]]; then + binary_log=true + node_reuse=false +fi + +. "$scriptroot/tools.sh" + +function InitializeCustomToolset { + local script="$eng_root/restore-toolset.sh" + + if [[ -a "$script" ]]; then + . "$script" + fi +} + +function Build { + InitializeToolset + InitializeCustomToolset + + if [[ ! -z "$projects" ]]; then + properties="$properties /p:Projects=$projects" + fi + + local bl="" + if [[ "$binary_log" == true ]]; then + bl="/bl:\"$log_dir/Build.binlog\"" + fi + + MSBuild $_InitializeToolset \ + $bl \ + /p:Configuration=$configuration \ + /p:RepoRoot="$repo_root" \ + /p:Restore=$restore \ + /p:Build=$build \ + /p:Rebuild=$rebuild \ + /p:Test=$test \ + /p:Pack=$pack \ + /p:IntegrationTest=$integration_test \ + /p:PerformanceTest=$performance_test \ + /p:Sign=$sign \ + /p:Publish=$publish \ + /p:ContinuousIntegrationBuild=$ci \ + $properties + + ExitWithExitCode 0 +} + +# Import custom tools configuration, if present in the repo. +configure_toolset_script="$eng_root/configure-toolset.sh" +if [[ -a "$configure_toolset_script" ]]; then + . "$configure_toolset_script" +fi + +# TODO: https://github.com/dotnet/arcade/issues/1468 +# Temporary workaround to avoid breaking change. +# Remove once repos are updated. +if [[ -n "${useInstalledDotNetCli:-}" ]]; then + use_installed_dotnet_cli="$useInstalledDotNetCli" +fi + +Build diff --git a/eng/common/cibuild.sh b/eng/common/cibuild.sh new file mode 100755 index 0000000000..1a02c0dec8 --- /dev/null +++ b/eng/common/cibuild.sh @@ -0,0 +1,16 @@ +#!/usr/bin/env bash + +source="${BASH_SOURCE[0]}" + +# resolve $SOURCE until the file is no longer a symlink +while [[ -h $source ]]; do + scriptroot="$( cd -P "$( dirname "$source" )" && pwd )" + source="$(readlink "$source")" + + # if $source was a relative symlink, we need to resolve it relative to the path where + # the symlink file was located + [[ $source != /* ]] && source="$scriptroot/$source" +done +scriptroot="$( cd -P "$( dirname "$source" )" && pwd )" + +. "$scriptroot/build.sh" --restore --build --test --pack --publish --ci $@ \ No newline at end of file diff --git a/eng/common/cross/android/arm/toolchain.cmake b/eng/common/cross/android/arm/toolchain.cmake new file mode 100644 index 0000000000..a7e1c73501 --- /dev/null +++ b/eng/common/cross/android/arm/toolchain.cmake @@ -0,0 +1,41 @@ +set(CROSS_NDK_TOOLCHAIN $ENV{ROOTFS_DIR}/../) +set(CROSS_ROOTFS ${CROSS_NDK_TOOLCHAIN}/sysroot) +set(CLR_CMAKE_PLATFORM_ANDROID "Android") + +set(CMAKE_SYSTEM_NAME Linux) +set(CMAKE_SYSTEM_VERSION 1) +set(CMAKE_SYSTEM_PROCESSOR arm) + +## Specify the toolchain +set(TOOLCHAIN "arm-linux-androideabi") +set(CMAKE_PREFIX_PATH ${CROSS_NDK_TOOLCHAIN}) +set(TOOLCHAIN_PREFIX ${TOOLCHAIN}-) + +find_program(CMAKE_C_COMPILER ${TOOLCHAIN_PREFIX}clang) +find_program(CMAKE_CXX_COMPILER ${TOOLCHAIN_PREFIX}clang++) +find_program(CMAKE_ASM_COMPILER ${TOOLCHAIN_PREFIX}clang) +find_program(CMAKE_AR ${TOOLCHAIN_PREFIX}ar) +find_program(CMAKE_LD ${TOOLCHAIN_PREFIX}ar) +find_program(CMAKE_OBJCOPY ${TOOLCHAIN_PREFIX}objcopy) +find_program(CMAKE_OBJDUMP ${TOOLCHAIN_PREFIX}objdump) + +add_compile_options(--sysroot=${CROSS_ROOTFS}) +add_compile_options(-fPIE) +add_compile_options(-mfloat-abi=soft) +include_directories(SYSTEM ${CROSS_NDK_TOOLCHAIN}/include/c++/4.9.x/) +include_directories(SYSTEM ${CROSS_NDK_TOOLCHAIN}/include/c++/4.9.x/arm-linux-androideabi/) + +set(CROSS_LINK_FLAGS "${CROSS_LINK_FLAGS} -B ${CROSS_ROOTFS}/usr/lib/gcc/${TOOLCHAIN}") +set(CROSS_LINK_FLAGS "${CROSS_LINK_FLAGS} -L${CROSS_ROOTFS}/lib/${TOOLCHAIN}") +set(CROSS_LINK_FLAGS "${CROSS_LINK_FLAGS} --sysroot=${CROSS_ROOTFS}") +set(CROSS_LINK_FLAGS "${CROSS_LINK_FLAGS} -fPIE -pie") + +set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${CROSS_LINK_FLAGS}" CACHE STRING "" FORCE) +set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} ${CROSS_LINK_FLAGS}" CACHE STRING "" FORCE) +set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} ${CROSS_LINK_FLAGS}" CACHE STRING "" FORCE) + +set(CMAKE_FIND_ROOT_PATH "${CROSS_ROOTFS}") +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) +set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) diff --git a/eng/common/cross/android/arm64/toolchain.cmake b/eng/common/cross/android/arm64/toolchain.cmake new file mode 100644 index 0000000000..29415899c1 --- /dev/null +++ b/eng/common/cross/android/arm64/toolchain.cmake @@ -0,0 +1,42 @@ +set(CROSS_NDK_TOOLCHAIN $ENV{ROOTFS_DIR}/../) +set(CROSS_ROOTFS ${CROSS_NDK_TOOLCHAIN}/sysroot) +set(CLR_CMAKE_PLATFORM_ANDROID "Android") + +set(CMAKE_SYSTEM_NAME Linux) +set(CMAKE_SYSTEM_VERSION 1) +set(CMAKE_SYSTEM_PROCESSOR aarch64) + +## Specify the toolchain +set(TOOLCHAIN "aarch64-linux-android") +set(CMAKE_PREFIX_PATH ${CROSS_NDK_TOOLCHAIN}) +set(TOOLCHAIN_PREFIX ${TOOLCHAIN}-) + +find_program(CMAKE_C_COMPILER ${TOOLCHAIN_PREFIX}clang) +find_program(CMAKE_CXX_COMPILER ${TOOLCHAIN_PREFIX}clang++) +find_program(CMAKE_ASM_COMPILER ${TOOLCHAIN_PREFIX}clang) +find_program(CMAKE_AR ${TOOLCHAIN_PREFIX}ar) +find_program(CMAKE_LD ${TOOLCHAIN_PREFIX}ar) +find_program(CMAKE_OBJCOPY ${TOOLCHAIN_PREFIX}objcopy) +find_program(CMAKE_OBJDUMP ${TOOLCHAIN_PREFIX}objdump) + +add_compile_options(--sysroot=${CROSS_ROOTFS}) +add_compile_options(-fPIE) + +## Needed for Android or bionic specific conditionals +add_compile_options(-D__ANDROID__) +add_compile_options(-D__BIONIC__) + +set(CROSS_LINK_FLAGS "${CROSS_LINK_FLAGS} -B ${CROSS_ROOTFS}/usr/lib/gcc/${TOOLCHAIN}") +set(CROSS_LINK_FLAGS "${CROSS_LINK_FLAGS} -L${CROSS_ROOTFS}/lib/${TOOLCHAIN}") +set(CROSS_LINK_FLAGS "${CROSS_LINK_FLAGS} --sysroot=${CROSS_ROOTFS}") +set(CROSS_LINK_FLAGS "${CROSS_LINK_FLAGS} -fPIE -pie") + +set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${CROSS_LINK_FLAGS}" CACHE STRING "" FORCE) +set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} ${CROSS_LINK_FLAGS}" CACHE STRING "" FORCE) +set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} ${CROSS_LINK_FLAGS}" CACHE STRING "" FORCE) + +set(CMAKE_FIND_ROOT_PATH "${CROSS_ROOTFS}") +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) +set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) diff --git a/eng/common/cross/arm/sources.list.bionic b/eng/common/cross/arm/sources.list.bionic new file mode 100644 index 0000000000..2109557409 --- /dev/null +++ b/eng/common/cross/arm/sources.list.bionic @@ -0,0 +1,11 @@ +deb http://ports.ubuntu.com/ubuntu-ports/ bionic main restricted universe +deb-src http://ports.ubuntu.com/ubuntu-ports/ bionic main restricted universe + +deb http://ports.ubuntu.com/ubuntu-ports/ bionic-updates main restricted universe +deb-src http://ports.ubuntu.com/ubuntu-ports/ bionic-updates main restricted universe + +deb http://ports.ubuntu.com/ubuntu-ports/ bionic-backports main restricted +deb-src http://ports.ubuntu.com/ubuntu-ports/ bionic-backports main restricted + +deb http://ports.ubuntu.com/ubuntu-ports/ bionic-security main restricted universe multiverse +deb-src http://ports.ubuntu.com/ubuntu-ports/ bionic-security main restricted universe multiverse diff --git a/eng/common/cross/arm/sources.list.jessie b/eng/common/cross/arm/sources.list.jessie new file mode 100644 index 0000000000..4d142ac9b1 --- /dev/null +++ b/eng/common/cross/arm/sources.list.jessie @@ -0,0 +1,3 @@ +# Debian (sid) # UNSTABLE +deb http://ftp.debian.org/debian/ sid main contrib non-free +deb-src http://ftp.debian.org/debian/ sid main contrib non-free diff --git a/eng/common/cross/arm/sources.list.trusty b/eng/common/cross/arm/sources.list.trusty new file mode 100644 index 0000000000..07d8f88d82 --- /dev/null +++ b/eng/common/cross/arm/sources.list.trusty @@ -0,0 +1,11 @@ +deb http://ports.ubuntu.com/ubuntu-ports/ trusty main restricted universe +deb-src http://ports.ubuntu.com/ubuntu-ports/ trusty main restricted universe + +deb http://ports.ubuntu.com/ubuntu-ports/ trusty-updates main restricted universe +deb-src http://ports.ubuntu.com/ubuntu-ports/ trusty-updates main restricted universe + +deb http://ports.ubuntu.com/ubuntu-ports/ trusty-backports main restricted +deb-src http://ports.ubuntu.com/ubuntu-ports/ trusty-backports main restricted + +deb http://ports.ubuntu.com/ubuntu-ports/ trusty-security main restricted universe multiverse +deb-src http://ports.ubuntu.com/ubuntu-ports/ trusty-security main restricted universe multiverse \ No newline at end of file diff --git a/eng/common/cross/arm/sources.list.vivid b/eng/common/cross/arm/sources.list.vivid new file mode 100644 index 0000000000..0b1215e475 --- /dev/null +++ b/eng/common/cross/arm/sources.list.vivid @@ -0,0 +1,11 @@ +deb http://ports.ubuntu.com/ubuntu-ports/ vivid main restricted universe +deb-src http://ports.ubuntu.com/ubuntu-ports/ vivid main restricted universe + +deb http://ports.ubuntu.com/ubuntu-ports/ vivid-updates main restricted universe +deb-src http://ports.ubuntu.com/ubuntu-ports/ vivid-updates main restricted universe + +deb http://ports.ubuntu.com/ubuntu-ports/ vivid-backports main restricted +deb-src http://ports.ubuntu.com/ubuntu-ports/ vivid-backports main restricted + +deb http://ports.ubuntu.com/ubuntu-ports/ vivid-security main restricted universe multiverse +deb-src http://ports.ubuntu.com/ubuntu-ports/ vivid-security main restricted universe multiverse \ No newline at end of file diff --git a/eng/common/cross/arm/sources.list.wily b/eng/common/cross/arm/sources.list.wily new file mode 100644 index 0000000000..e23d1e02a0 --- /dev/null +++ b/eng/common/cross/arm/sources.list.wily @@ -0,0 +1,11 @@ +deb http://ports.ubuntu.com/ubuntu-ports/ wily main restricted universe +deb-src http://ports.ubuntu.com/ubuntu-ports/ wily main restricted universe + +deb http://ports.ubuntu.com/ubuntu-ports/ wily-updates main restricted universe +deb-src http://ports.ubuntu.com/ubuntu-ports/ wily-updates main restricted universe + +deb http://ports.ubuntu.com/ubuntu-ports/ wily-backports main restricted +deb-src http://ports.ubuntu.com/ubuntu-ports/ wily-backports main restricted + +deb http://ports.ubuntu.com/ubuntu-ports/ wily-security main restricted universe multiverse +deb-src http://ports.ubuntu.com/ubuntu-ports/ wily-security main restricted universe multiverse \ No newline at end of file diff --git a/eng/common/cross/arm/sources.list.xenial b/eng/common/cross/arm/sources.list.xenial new file mode 100644 index 0000000000..eacd86b7df --- /dev/null +++ b/eng/common/cross/arm/sources.list.xenial @@ -0,0 +1,11 @@ +deb http://ports.ubuntu.com/ubuntu-ports/ xenial main restricted universe +deb-src http://ports.ubuntu.com/ubuntu-ports/ xenial main restricted universe + +deb http://ports.ubuntu.com/ubuntu-ports/ xenial-updates main restricted universe +deb-src http://ports.ubuntu.com/ubuntu-ports/ xenial-updates main restricted universe + +deb http://ports.ubuntu.com/ubuntu-ports/ xenial-backports main restricted +deb-src http://ports.ubuntu.com/ubuntu-ports/ xenial-backports main restricted + +deb http://ports.ubuntu.com/ubuntu-ports/ xenial-security main restricted universe multiverse +deb-src http://ports.ubuntu.com/ubuntu-ports/ xenial-security main restricted universe multiverse \ No newline at end of file diff --git a/eng/common/cross/arm/sources.list.zesty b/eng/common/cross/arm/sources.list.zesty new file mode 100644 index 0000000000..ea2c14a787 --- /dev/null +++ b/eng/common/cross/arm/sources.list.zesty @@ -0,0 +1,11 @@ +deb http://ports.ubuntu.com/ubuntu-ports/ zesty main restricted universe +deb-src http://ports.ubuntu.com/ubuntu-ports/ zesty main restricted universe + +deb http://ports.ubuntu.com/ubuntu-ports/ zesty-updates main restricted universe +deb-src http://ports.ubuntu.com/ubuntu-ports/ zesty-updates main restricted universe + +deb http://ports.ubuntu.com/ubuntu-ports/ zesty-backports main restricted +deb-src http://ports.ubuntu.com/ubuntu-ports/ zesty-backports main restricted + +deb http://ports.ubuntu.com/ubuntu-ports/ zesty-security main restricted universe multiverse +deb-src http://ports.ubuntu.com/ubuntu-ports/ zesty-security main restricted universe multiverse diff --git a/eng/common/cross/arm/trusty-lttng-2.4.patch b/eng/common/cross/arm/trusty-lttng-2.4.patch new file mode 100644 index 0000000000..8e4dd7ae71 --- /dev/null +++ b/eng/common/cross/arm/trusty-lttng-2.4.patch @@ -0,0 +1,71 @@ +From e72c9d7ead60e3317bd6d1fade995c07021c947b Mon Sep 17 00:00:00 2001 +From: Mathieu Desnoyers +Date: Thu, 7 May 2015 13:25:04 -0400 +Subject: [PATCH] Fix: building probe providers with C++ compiler + +Robert Daniels wrote: +> > I'm attempting to use lttng userspace tracing with a C++ application +> > on an ARM platform. I'm using GCC 4.8.4 on Linux 3.14 with the 2.6 +> > release of lttng. I've compiled lttng-modules, lttng-ust, and +> > lttng-tools and have been able to get a simple test working with C +> > code. When I attempt to run the hello.cxx test on my target it will +> > segfault. +> +> +> I spent a little time digging into this issue and finally discovered the +> cause of my segfault with ARM C++ tracepoints. +> +> There is a struct called 'lttng_event' in ust-events.h which contains an +> empty union 'u'. This was the cause of my issue. Under C, this empty union +> compiles to a zero byte member while under C++ it compiles to a one byte +> member, and in my case was four-byte aligned which caused my C++ code to +> have the 'cds_list_head node' offset incorrectly by four bytes. This lead +> to an incorrect linked list structure which caused my issue. +> +> Since this union is empty, I simply removed it from the struct and everything +> worked correctly. +> +> I don't know the history or purpose behind this empty union so I'd like to +> know if this is a safe fix. If it is I can submit a patch with the union +> removed. + +That's a very nice catch! + +We do not support building tracepoint probe provider with +g++ yet, as stated in lttng-ust(3): + +"- Note for C++ support: although an application instrumented with + tracepoints can be compiled with g++, tracepoint probes should be + compiled with gcc (only tested with gcc so far)." + +However, if it works fine with this fix, then I'm tempted to take it, +especially because removing the empty union does not appear to affect +the layout of struct lttng_event as seen from liblttng-ust, which must +be compiled with a C compiler, and from probe providers compiled with +a C compiler. So all we are changing is the layout of a probe provider +compiled with a C++ compiler, which is anyway buggy at the moment, +because it is not compatible with the layout expected by liblttng-ust +compiled with a C compiler. + +Reported-by: Robert Daniels +Signed-off-by: Mathieu Desnoyers +--- + include/lttng/ust-events.h | 2 -- + 1 file changed, 2 deletions(-) + +diff --git a/usr/include/lttng/ust-events.h b/usr/include/lttng/ust-events.h +index 328a875..3d7a274 100644 +--- a/usr/include/lttng/ust-events.h ++++ b/usr/include/lttng/ust-events.h +@@ -407,8 +407,6 @@ struct lttng_event { + void *_deprecated1; + struct lttng_ctx *ctx; + enum lttng_ust_instrumentation instrumentation; +- union { +- } u; + struct cds_list_head node; /* Event list in session */ + struct cds_list_head _deprecated2; + void *_deprecated3; +-- +2.7.4 + diff --git a/eng/common/cross/arm/trusty.patch b/eng/common/cross/arm/trusty.patch new file mode 100644 index 0000000000..2f2972f8eb --- /dev/null +++ b/eng/common/cross/arm/trusty.patch @@ -0,0 +1,97 @@ +diff -u -r a/usr/include/urcu/uatomic/generic.h b/usr/include/urcu/uatomic/generic.h +--- a/usr/include/urcu/uatomic/generic.h 2014-03-28 06:04:42.000000000 +0900 ++++ b/usr/include/urcu/uatomic/generic.h 2017-02-13 10:35:21.189927116 +0900 +@@ -65,17 +65,17 @@ + switch (len) { + #ifdef UATOMIC_HAS_ATOMIC_BYTE + case 1: +- return __sync_val_compare_and_swap_1(addr, old, _new); ++ return __sync_val_compare_and_swap_1((uint8_t *) addr, old, _new); + #endif + #ifdef UATOMIC_HAS_ATOMIC_SHORT + case 2: +- return __sync_val_compare_and_swap_2(addr, old, _new); ++ return __sync_val_compare_and_swap_2((uint16_t *) addr, old, _new); + #endif + case 4: +- return __sync_val_compare_and_swap_4(addr, old, _new); ++ return __sync_val_compare_and_swap_4((uint32_t *) addr, old, _new); + #if (CAA_BITS_PER_LONG == 64) + case 8: +- return __sync_val_compare_and_swap_8(addr, old, _new); ++ return __sync_val_compare_and_swap_8((uint64_t *) addr, old, _new); + #endif + } + _uatomic_link_error(); +@@ -100,20 +100,20 @@ + switch (len) { + #ifdef UATOMIC_HAS_ATOMIC_BYTE + case 1: +- __sync_and_and_fetch_1(addr, val); ++ __sync_and_and_fetch_1((uint8_t *) addr, val); + return; + #endif + #ifdef UATOMIC_HAS_ATOMIC_SHORT + case 2: +- __sync_and_and_fetch_2(addr, val); ++ __sync_and_and_fetch_2((uint16_t *) addr, val); + return; + #endif + case 4: +- __sync_and_and_fetch_4(addr, val); ++ __sync_and_and_fetch_4((uint32_t *) addr, val); + return; + #if (CAA_BITS_PER_LONG == 64) + case 8: +- __sync_and_and_fetch_8(addr, val); ++ __sync_and_and_fetch_8((uint64_t *) addr, val); + return; + #endif + } +@@ -139,20 +139,20 @@ + switch (len) { + #ifdef UATOMIC_HAS_ATOMIC_BYTE + case 1: +- __sync_or_and_fetch_1(addr, val); ++ __sync_or_and_fetch_1((uint8_t *) addr, val); + return; + #endif + #ifdef UATOMIC_HAS_ATOMIC_SHORT + case 2: +- __sync_or_and_fetch_2(addr, val); ++ __sync_or_and_fetch_2((uint16_t *) addr, val); + return; + #endif + case 4: +- __sync_or_and_fetch_4(addr, val); ++ __sync_or_and_fetch_4((uint32_t *) addr, val); + return; + #if (CAA_BITS_PER_LONG == 64) + case 8: +- __sync_or_and_fetch_8(addr, val); ++ __sync_or_and_fetch_8((uint64_t *) addr, val); + return; + #endif + } +@@ -180,17 +180,17 @@ + switch (len) { + #ifdef UATOMIC_HAS_ATOMIC_BYTE + case 1: +- return __sync_add_and_fetch_1(addr, val); ++ return __sync_add_and_fetch_1((uint8_t *) addr, val); + #endif + #ifdef UATOMIC_HAS_ATOMIC_SHORT + case 2: +- return __sync_add_and_fetch_2(addr, val); ++ return __sync_add_and_fetch_2((uint16_t *) addr, val); + #endif + case 4: +- return __sync_add_and_fetch_4(addr, val); ++ return __sync_add_and_fetch_4((uint32_t *) addr, val); + #if (CAA_BITS_PER_LONG == 64) + case 8: +- return __sync_add_and_fetch_8(addr, val); ++ return __sync_add_and_fetch_8((uint64_t *) addr, val); + #endif + } + _uatomic_link_error(); diff --git a/eng/common/cross/arm64/sources.list.bionic b/eng/common/cross/arm64/sources.list.bionic new file mode 100644 index 0000000000..2109557409 --- /dev/null +++ b/eng/common/cross/arm64/sources.list.bionic @@ -0,0 +1,11 @@ +deb http://ports.ubuntu.com/ubuntu-ports/ bionic main restricted universe +deb-src http://ports.ubuntu.com/ubuntu-ports/ bionic main restricted universe + +deb http://ports.ubuntu.com/ubuntu-ports/ bionic-updates main restricted universe +deb-src http://ports.ubuntu.com/ubuntu-ports/ bionic-updates main restricted universe + +deb http://ports.ubuntu.com/ubuntu-ports/ bionic-backports main restricted +deb-src http://ports.ubuntu.com/ubuntu-ports/ bionic-backports main restricted + +deb http://ports.ubuntu.com/ubuntu-ports/ bionic-security main restricted universe multiverse +deb-src http://ports.ubuntu.com/ubuntu-ports/ bionic-security main restricted universe multiverse diff --git a/eng/common/cross/arm64/sources.list.trusty b/eng/common/cross/arm64/sources.list.trusty new file mode 100644 index 0000000000..07d8f88d82 --- /dev/null +++ b/eng/common/cross/arm64/sources.list.trusty @@ -0,0 +1,11 @@ +deb http://ports.ubuntu.com/ubuntu-ports/ trusty main restricted universe +deb-src http://ports.ubuntu.com/ubuntu-ports/ trusty main restricted universe + +deb http://ports.ubuntu.com/ubuntu-ports/ trusty-updates main restricted universe +deb-src http://ports.ubuntu.com/ubuntu-ports/ trusty-updates main restricted universe + +deb http://ports.ubuntu.com/ubuntu-ports/ trusty-backports main restricted +deb-src http://ports.ubuntu.com/ubuntu-ports/ trusty-backports main restricted + +deb http://ports.ubuntu.com/ubuntu-ports/ trusty-security main restricted universe multiverse +deb-src http://ports.ubuntu.com/ubuntu-ports/ trusty-security main restricted universe multiverse \ No newline at end of file diff --git a/eng/common/cross/arm64/sources.list.vivid b/eng/common/cross/arm64/sources.list.vivid new file mode 100644 index 0000000000..0b1215e475 --- /dev/null +++ b/eng/common/cross/arm64/sources.list.vivid @@ -0,0 +1,11 @@ +deb http://ports.ubuntu.com/ubuntu-ports/ vivid main restricted universe +deb-src http://ports.ubuntu.com/ubuntu-ports/ vivid main restricted universe + +deb http://ports.ubuntu.com/ubuntu-ports/ vivid-updates main restricted universe +deb-src http://ports.ubuntu.com/ubuntu-ports/ vivid-updates main restricted universe + +deb http://ports.ubuntu.com/ubuntu-ports/ vivid-backports main restricted +deb-src http://ports.ubuntu.com/ubuntu-ports/ vivid-backports main restricted + +deb http://ports.ubuntu.com/ubuntu-ports/ vivid-security main restricted universe multiverse +deb-src http://ports.ubuntu.com/ubuntu-ports/ vivid-security main restricted universe multiverse \ No newline at end of file diff --git a/eng/common/cross/arm64/sources.list.wily b/eng/common/cross/arm64/sources.list.wily new file mode 100644 index 0000000000..e23d1e02a0 --- /dev/null +++ b/eng/common/cross/arm64/sources.list.wily @@ -0,0 +1,11 @@ +deb http://ports.ubuntu.com/ubuntu-ports/ wily main restricted universe +deb-src http://ports.ubuntu.com/ubuntu-ports/ wily main restricted universe + +deb http://ports.ubuntu.com/ubuntu-ports/ wily-updates main restricted universe +deb-src http://ports.ubuntu.com/ubuntu-ports/ wily-updates main restricted universe + +deb http://ports.ubuntu.com/ubuntu-ports/ wily-backports main restricted +deb-src http://ports.ubuntu.com/ubuntu-ports/ wily-backports main restricted + +deb http://ports.ubuntu.com/ubuntu-ports/ wily-security main restricted universe multiverse +deb-src http://ports.ubuntu.com/ubuntu-ports/ wily-security main restricted universe multiverse \ No newline at end of file diff --git a/eng/common/cross/arm64/sources.list.xenial b/eng/common/cross/arm64/sources.list.xenial new file mode 100644 index 0000000000..eacd86b7df --- /dev/null +++ b/eng/common/cross/arm64/sources.list.xenial @@ -0,0 +1,11 @@ +deb http://ports.ubuntu.com/ubuntu-ports/ xenial main restricted universe +deb-src http://ports.ubuntu.com/ubuntu-ports/ xenial main restricted universe + +deb http://ports.ubuntu.com/ubuntu-ports/ xenial-updates main restricted universe +deb-src http://ports.ubuntu.com/ubuntu-ports/ xenial-updates main restricted universe + +deb http://ports.ubuntu.com/ubuntu-ports/ xenial-backports main restricted +deb-src http://ports.ubuntu.com/ubuntu-ports/ xenial-backports main restricted + +deb http://ports.ubuntu.com/ubuntu-ports/ xenial-security main restricted universe multiverse +deb-src http://ports.ubuntu.com/ubuntu-ports/ xenial-security main restricted universe multiverse \ No newline at end of file diff --git a/eng/common/cross/arm64/sources.list.zesty b/eng/common/cross/arm64/sources.list.zesty new file mode 100644 index 0000000000..ea2c14a787 --- /dev/null +++ b/eng/common/cross/arm64/sources.list.zesty @@ -0,0 +1,11 @@ +deb http://ports.ubuntu.com/ubuntu-ports/ zesty main restricted universe +deb-src http://ports.ubuntu.com/ubuntu-ports/ zesty main restricted universe + +deb http://ports.ubuntu.com/ubuntu-ports/ zesty-updates main restricted universe +deb-src http://ports.ubuntu.com/ubuntu-ports/ zesty-updates main restricted universe + +deb http://ports.ubuntu.com/ubuntu-ports/ zesty-backports main restricted +deb-src http://ports.ubuntu.com/ubuntu-ports/ zesty-backports main restricted + +deb http://ports.ubuntu.com/ubuntu-ports/ zesty-security main restricted universe multiverse +deb-src http://ports.ubuntu.com/ubuntu-ports/ zesty-security main restricted universe multiverse diff --git a/eng/common/cross/armel/sources.list.jessie b/eng/common/cross/armel/sources.list.jessie new file mode 100644 index 0000000000..3d9c3059d8 --- /dev/null +++ b/eng/common/cross/armel/sources.list.jessie @@ -0,0 +1,3 @@ +# Debian (jessie) # Stable +deb http://ftp.debian.org/debian/ jessie main contrib non-free +deb-src http://ftp.debian.org/debian/ jessie main contrib non-free diff --git a/eng/common/cross/armel/tizen-build-rootfs.sh b/eng/common/cross/armel/tizen-build-rootfs.sh new file mode 100755 index 0000000000..87c48e78fb --- /dev/null +++ b/eng/common/cross/armel/tizen-build-rootfs.sh @@ -0,0 +1,44 @@ +#!/usr/bin/env bash +set -e + +__ARM_SOFTFP_CrossDir=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd ) +__TIZEN_CROSSDIR="$__ARM_SOFTFP_CrossDir/tizen" + +if [[ -z "$ROOTFS_DIR" ]]; then + echo "ROOTFS_DIR is not defined." + exit 1; +fi + +# Clean-up (TODO-Cleanup: We may already delete $ROOTFS_DIR at ./cross/build-rootfs.sh.) +# hk0110 +if [ -d "$ROOTFS_DIR" ]; then + umount $ROOTFS_DIR/* + rm -rf $ROOTFS_DIR +fi + +TIZEN_TMP_DIR=$ROOTFS_DIR/tizen_tmp +mkdir -p $TIZEN_TMP_DIR + +# Download files +echo ">>Start downloading files" +VERBOSE=1 $__ARM_SOFTFP_CrossDir/tizen-fetch.sh $TIZEN_TMP_DIR +echo "<>Start constructing Tizen rootfs" +TIZEN_RPM_FILES=`ls $TIZEN_TMP_DIR/*.rpm` +cd $ROOTFS_DIR +for f in $TIZEN_RPM_FILES; do + rpm2cpio $f | cpio -idm --quiet +done +echo "<>Start configuring Tizen rootfs" +rm ./usr/lib/libunwind.so +ln -s libunwind.so.8 ./usr/lib/libunwind.so +ln -sfn asm-arm ./usr/include/asm +patch -p1 < $__TIZEN_CROSSDIR/tizen.patch +echo "</dev/null; then + VERBOSE=0 +fi + +Log() +{ + if [ $VERBOSE -ge $1 ]; then + echo ${@:2} + fi +} + +Inform() +{ + Log 1 -e "\x1B[0;34m$@\x1B[m" +} + +Debug() +{ + Log 2 -e "\x1B[0;32m$@\x1B[m" +} + +Error() +{ + >&2 Log 0 -e "\x1B[0;31m$@\x1B[m" +} + +Fetch() +{ + URL=$1 + FILE=$2 + PROGRESS=$3 + if [ $VERBOSE -ge 1 ] && [ $PROGRESS ]; then + CURL_OPT="--progress-bar" + else + CURL_OPT="--silent" + fi + curl $CURL_OPT $URL > $FILE +} + +hash curl 2> /dev/null || { Error "Require 'curl' Aborting."; exit 1; } +hash xmllint 2> /dev/null || { Error "Require 'xmllint' Aborting."; exit 1; } +hash sha256sum 2> /dev/null || { Error "Require 'sha256sum' Aborting."; exit 1; } + +TMPDIR=$1 +if [ ! -d $TMPDIR ]; then + TMPDIR=./tizen_tmp + Debug "Create temporary directory : $TMPDIR" + mkdir -p $TMPDIR +fi + +TIZEN_URL=http://download.tizen.org/releases/milestone/tizen +BUILD_XML=build.xml +REPOMD_XML=repomd.xml +PRIMARY_XML=primary.xml +TARGET_URL="http://__not_initialized" + +Xpath_get() +{ + XPATH_RESULT='' + XPATH=$1 + XML_FILE=$2 + RESULT=$(xmllint --xpath $XPATH $XML_FILE) + if [[ -z ${RESULT// } ]]; then + Error "Can not find target from $XML_FILE" + Debug "Xpath = $XPATH" + exit 1 + fi + XPATH_RESULT=$RESULT +} + +fetch_tizen_pkgs_init() +{ + TARGET=$1 + PROFILE=$2 + Debug "Initialize TARGET=$TARGET, PROFILE=$PROFILE" + + TMP_PKG_DIR=$TMPDIR/tizen_${PROFILE}_pkgs + if [ -d $TMP_PKG_DIR ]; then rm -rf $TMP_PKG_DIR; fi + mkdir -p $TMP_PKG_DIR + + PKG_URL=$TIZEN_URL/$PROFILE/latest + + BUILD_XML_URL=$PKG_URL/$BUILD_XML + TMP_BUILD=$TMP_PKG_DIR/$BUILD_XML + TMP_REPOMD=$TMP_PKG_DIR/$REPOMD_XML + TMP_PRIMARY=$TMP_PKG_DIR/$PRIMARY_XML + TMP_PRIMARYGZ=${TMP_PRIMARY}.gz + + Fetch $BUILD_XML_URL $TMP_BUILD + + Debug "fetch $BUILD_XML_URL to $TMP_BUILD" + + TARGET_XPATH="//build/buildtargets/buildtarget[@name=\"$TARGET\"]/repo[@type=\"binary\"]/text()" + Xpath_get $TARGET_XPATH $TMP_BUILD + TARGET_PATH=$XPATH_RESULT + TARGET_URL=$PKG_URL/$TARGET_PATH + + REPOMD_URL=$TARGET_URL/repodata/repomd.xml + PRIMARY_XPATH='string(//*[local-name()="data"][@type="primary"]/*[local-name()="location"]/@href)' + + Fetch $REPOMD_URL $TMP_REPOMD + + Debug "fetch $REPOMD_URL to $TMP_REPOMD" + + Xpath_get $PRIMARY_XPATH $TMP_REPOMD + PRIMARY_XML_PATH=$XPATH_RESULT + PRIMARY_URL=$TARGET_URL/$PRIMARY_XML_PATH + + Fetch $PRIMARY_URL $TMP_PRIMARYGZ + + Debug "fetch $PRIMARY_URL to $TMP_PRIMARYGZ" + + gunzip $TMP_PRIMARYGZ + + Debug "unzip $TMP_PRIMARYGZ to $TMP_PRIMARY" +} + +fetch_tizen_pkgs() +{ + ARCH=$1 + PACKAGE_XPATH_TPL='string(//*[local-name()="metadata"]/*[local-name()="package"][*[local-name()="name"][text()="_PKG_"]][*[local-name()="arch"][text()="_ARCH_"]]/*[local-name()="location"]/@href)' + + PACKAGE_CHECKSUM_XPATH_TPL='string(//*[local-name()="metadata"]/*[local-name()="package"][*[local-name()="name"][text()="_PKG_"]][*[local-name()="arch"][text()="_ARCH_"]]/*[local-name()="checksum"]/text())' + + for pkg in ${@:2} + do + Inform "Fetching... $pkg" + XPATH=${PACKAGE_XPATH_TPL/_PKG_/$pkg} + XPATH=${XPATH/_ARCH_/$ARCH} + Xpath_get $XPATH $TMP_PRIMARY + PKG_PATH=$XPATH_RESULT + + XPATH=${PACKAGE_CHECKSUM_XPATH_TPL/_PKG_/$pkg} + XPATH=${XPATH/_ARCH_/$ARCH} + Xpath_get $XPATH $TMP_PRIMARY + CHECKSUM=$XPATH_RESULT + + PKG_URL=$TARGET_URL/$PKG_PATH + PKG_FILE=$(basename $PKG_PATH) + PKG_PATH=$TMPDIR/$PKG_FILE + + Debug "Download $PKG_URL to $PKG_PATH" + Fetch $PKG_URL $PKG_PATH true + + echo "$CHECKSUM $PKG_PATH" | sha256sum -c - > /dev/null + if [ $? -ne 0 ]; then + Error "Fail to fetch $PKG_URL to $PKG_PATH" + Debug "Checksum = $CHECKSUM" + exit 1 + fi + done +} + +Inform "Initialize arm base" +fetch_tizen_pkgs_init standard base +Inform "fetch common packages" +fetch_tizen_pkgs armv7l gcc glibc glibc-devel libicu libicu-devel +fetch_tizen_pkgs noarch linux-glibc-devel +Inform "fetch coreclr packages" +fetch_tizen_pkgs armv7l lldb lldb-devel libgcc libstdc++ libstdc++-devel libunwind libunwind-devel tizen-release lttng-ust-devel lttng-ust userspace-rcu-devel userspace-rcu +Inform "fetch corefx packages" +fetch_tizen_pkgs armv7l libcom_err libcom_err-devel zlib zlib-devel libopenssl libopenssl-devel krb5 krb5-devel libcurl libcurl-devel + +Inform "Initialize standard unified" +fetch_tizen_pkgs_init standard unified +Inform "fetch corefx packages" +fetch_tizen_pkgs armv7l gssdp gssdp-devel + diff --git a/eng/common/cross/armel/tizen/tizen-dotnet.ks b/eng/common/cross/armel/tizen/tizen-dotnet.ks new file mode 100644 index 0000000000..506d455bd4 --- /dev/null +++ b/eng/common/cross/armel/tizen/tizen-dotnet.ks @@ -0,0 +1,50 @@ +lang en_US.UTF-8 +keyboard us +timezone --utc Asia/Seoul + +part / --fstype="ext4" --size=3500 --ondisk=mmcblk0 --label rootfs --fsoptions=defaults,noatime + +rootpw tizen +desktop --autologinuser=root +user --name root --groups audio,video --password 'tizen' + +repo --name=standard --baseurl=http://download.tizen.org/releases/milestone/tizen/unified/latest/repos/standard/packages/ --ssl_verify=no +repo --name=base --baseurl=http://download.tizen.org/releases/milestone/tizen/base/latest/repos/standard/packages/ --ssl_verify=no + +%packages +tar +gzip + +sed +grep +gawk +perl + +binutils +findutils +util-linux +lttng-ust +userspace-rcu +procps-ng +tzdata +ca-certificates + + +### Core FX +libicu +libunwind +iputils +zlib +krb5 +libcurl +libopenssl + +%end + +%post + +### Update /tmp privilege +chmod 777 /tmp +#################################### + +%end diff --git a/eng/common/cross/armel/tizen/tizen.patch b/eng/common/cross/armel/tizen/tizen.patch new file mode 100644 index 0000000000..d223427c97 --- /dev/null +++ b/eng/common/cross/armel/tizen/tizen.patch @@ -0,0 +1,18 @@ +diff -u -r a/usr/lib/libc.so b/usr/lib/libc.so +--- a/usr/lib/libc.so 2016-12-30 23:00:08.284951863 +0900 ++++ b/usr/lib/libc.so 2016-12-30 23:00:32.140951815 +0900 +@@ -2,4 +2,4 @@ + Use the shared library, but some functions are only in + the static library, so try that secondarily. */ + OUTPUT_FORMAT(elf32-littlearm) +-GROUP ( /lib/libc.so.6 /usr/lib/libc_nonshared.a AS_NEEDED ( /lib/ld-linux.so.3 ) ) ++GROUP ( libc.so.6 libc_nonshared.a AS_NEEDED ( ld-linux.so.3 ) ) +diff -u -r a/usr/lib/libpthread.so b/usr/lib/libpthread.so +--- a/usr/lib/libpthread.so 2016-12-30 23:00:19.408951841 +0900 ++++ b/usr/lib/libpthread.so 2016-12-30 23:00:39.068951801 +0900 +@@ -2,4 +2,4 @@ + Use the shared library, but some functions are only in + the static library, so try that secondarily. */ + OUTPUT_FORMAT(elf32-littlearm) +-GROUP ( /lib/libpthread.so.0 /usr/lib/libpthread_nonshared.a ) ++GROUP ( libpthread.so.0 libpthread_nonshared.a ) diff --git a/eng/common/cross/build-android-rootfs.sh b/eng/common/cross/build-android-rootfs.sh new file mode 100755 index 0000000000..adceda877a --- /dev/null +++ b/eng/common/cross/build-android-rootfs.sh @@ -0,0 +1,137 @@ +#!/usr/bin/env bash +set -e +__NDK_Version=r14 + +usage() +{ + echo "Creates a toolchain and sysroot used for cross-compiling for Android." + echo. + echo "Usage: $0 [BuildArch] [ApiLevel]" + echo. + echo "BuildArch is the target architecture of Android. Currently only arm64 is supported." + echo "ApiLevel is the target Android API level. API levels usually match to Android releases. See https://source.android.com/source/build-numbers.html" + echo. + echo "By default, the toolchain and sysroot will be generated in cross/android-rootfs/toolchain/[BuildArch]. You can change this behavior" + echo "by setting the TOOLCHAIN_DIR environment variable" + echo. + echo "By default, the NDK will be downloaded into the cross/android-rootfs/android-ndk-$__NDK_Version directory. If you already have an NDK installation," + echo "you can set the NDK_DIR environment variable to have this script use that installation of the NDK." + echo "By default, this script will generate a file, android_platform, in the root of the ROOTFS_DIR directory that contains the RID for the supported and tested Android build: android.21-arm64. This file is to replace '/etc/os-release', which is not available for Android." + exit 1 +} + +__ApiLevel=21 # The minimum platform for arm64 is API level 21 +__BuildArch=arm64 +__AndroidArch=aarch64 +__AndroidToolchain=aarch64-linux-android + +for i in "$@" + do + lowerI="$(echo $i | awk '{print tolower($0)}')" + case $lowerI in + -?|-h|--help) + usage + exit 1 + ;; + arm64) + __BuildArch=arm64 + __AndroidArch=aarch64 + __AndroidToolchain=aarch64-linux-android + ;; + arm) + __BuildArch=arm + __AndroidArch=arm + __AndroidToolchain=arm-linux-androideabi + ;; + *[0-9]) + __ApiLevel=$i + ;; + *) + __UnprocessedBuildArgs="$__UnprocessedBuildArgs $i" + ;; + esac +done + +# Obtain the location of the bash script to figure out where the root of the repo is. +__CrossDir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" + +__Android_Cross_Dir="$__CrossDir/android-rootfs" +__NDK_Dir="$__Android_Cross_Dir/android-ndk-$__NDK_Version" +__libunwind_Dir="$__Android_Cross_Dir/libunwind" +__lldb_Dir="$__Android_Cross_Dir/lldb" +__ToolchainDir="$__Android_Cross_Dir/toolchain/$__BuildArch" + +if [[ -n "$TOOLCHAIN_DIR" ]]; then + __ToolchainDir=$TOOLCHAIN_DIR +fi + +if [[ -n "$NDK_DIR" ]]; then + __NDK_Dir=$NDK_DIR +fi + +echo "Target API level: $__ApiLevel" +echo "Target architecture: $__BuildArch" +echo "NDK location: $__NDK_Dir" +echo "Target Toolchain location: $__ToolchainDir" + +# Download the NDK if required +if [ ! -d $__NDK_Dir ]; then + echo Downloading the NDK into $__NDK_Dir + mkdir -p $__NDK_Dir + wget -nv -nc --show-progress https://dl.google.com/android/repository/android-ndk-$__NDK_Version-linux-x86_64.zip -O $__Android_Cross_Dir/android-ndk-$__NDK_Version-linux-x86_64.zip + unzip -q $__Android_Cross_Dir/android-ndk-$__NDK_Version-linux-x86_64.zip -d $__Android_Cross_Dir +fi + +if [ ! -d $__lldb_Dir ]; then + mkdir -p $__lldb_Dir + echo Downloading LLDB into $__lldb_Dir + wget -nv -nc --show-progress https://dl.google.com/android/repository/lldb-2.3.3614996-linux-x86_64.zip -O $__Android_Cross_Dir/lldb-2.3.3614996-linux-x86_64.zip + unzip -q $__Android_Cross_Dir/lldb-2.3.3614996-linux-x86_64.zip -d $__lldb_Dir +fi + +# Create the RootFS for both arm64 as well as aarch +rm -rf $__Android_Cross_Dir/toolchain + +echo Generating the $__BuildArch toolchain +$__NDK_Dir/build/tools/make_standalone_toolchain.py --arch $__BuildArch --api $__ApiLevel --install-dir $__ToolchainDir + +# Install the required packages into the toolchain +# TODO: Add logic to get latest pkg version instead of specific version number +rm -rf $__Android_Cross_Dir/deb/ +rm -rf $__Android_Cross_Dir/tmp + +mkdir -p $__Android_Cross_Dir/deb/ +mkdir -p $__Android_Cross_Dir/tmp/$arch/ +wget -nv -nc http://termux.net/dists/stable/main/binary-$__AndroidArch/libicu_60.2_$__AndroidArch.deb -O $__Android_Cross_Dir/deb/libicu_60.2_$__AndroidArch.deb +wget -nv -nc http://termux.net/dists/stable/main/binary-$__AndroidArch/libicu-dev_60.2_$__AndroidArch.deb -O $__Android_Cross_Dir/deb/libicu-dev_60.2_$__AndroidArch.deb + +wget -nv -nc http://termux.net/dists/stable/main/binary-$__AndroidArch/libandroid-glob-dev_0.4_$__AndroidArch.deb -O $__Android_Cross_Dir/deb/libandroid-glob-dev_0.4_$__AndroidArch.deb +wget -nv -nc http://termux.net/dists/stable/main/binary-$__AndroidArch/libandroid-glob_0.4_$__AndroidArch.deb -O $__Android_Cross_Dir/deb/libandroid-glob_0.4_$__AndroidArch.deb +wget -nv -nc http://termux.net/dists/stable/main/binary-$__AndroidArch/libandroid-support-dev_22_$__AndroidArch.deb -O $__Android_Cross_Dir/deb/libandroid-support-dev_22_$__AndroidArch.deb +wget -nv -nc http://termux.net/dists/stable/main/binary-$__AndroidArch/libandroid-support_22_$__AndroidArch.deb -O $__Android_Cross_Dir/deb/libandroid-support_22_$__AndroidArch.deb +wget -nv -nc http://termux.net/dists/stable/main/binary-$__AndroidArch/liblzma-dev_5.2.3_$__AndroidArch.deb -O $__Android_Cross_Dir/deb/liblzma-dev_5.2.3_$__AndroidArch.deb +wget -nv -nc http://termux.net/dists/stable/main/binary-$__AndroidArch/liblzma_5.2.3_$__AndroidArch.deb -O $__Android_Cross_Dir/deb/liblzma_5.2.3_$__AndroidArch.deb +wget -nv -nc http://termux.net/dists/stable/main/binary-$__AndroidArch/libunwind-dev_1.2.20170304_$__AndroidArch.deb -O $__Android_Cross_Dir/deb/libunwind-dev_1.2.20170304_$__AndroidArch.deb +wget -nv -nc http://termux.net/dists/stable/main/binary-$__AndroidArch/libunwind_1.2.20170304_$__AndroidArch.deb -O $__Android_Cross_Dir/deb/libunwind_1.2.20170304_$__AndroidArch.deb + +echo Unpacking Termux packages +dpkg -x $__Android_Cross_Dir/deb/libicu_60.2_$__AndroidArch.deb $__Android_Cross_Dir/tmp/$__AndroidArch/ +dpkg -x $__Android_Cross_Dir/deb/libicu-dev_60.2_$__AndroidArch.deb $__Android_Cross_Dir/tmp/$__AndroidArch/ +dpkg -x $__Android_Cross_Dir/deb/libandroid-glob-dev_0.4_$__AndroidArch.deb $__Android_Cross_Dir/tmp/$__AndroidArch/ +dpkg -x $__Android_Cross_Dir/deb/libandroid-glob_0.4_$__AndroidArch.deb $__Android_Cross_Dir/tmp/$__AndroidArch/ +dpkg -x $__Android_Cross_Dir/deb/libandroid-support-dev_22_$__AndroidArch.deb $__Android_Cross_Dir/tmp/$__AndroidArch/ +dpkg -x $__Android_Cross_Dir/deb/libandroid-support_22_$__AndroidArch.deb $__Android_Cross_Dir/tmp/$__AndroidArch/ +dpkg -x $__Android_Cross_Dir/deb/liblzma-dev_5.2.3_$__AndroidArch.deb $__Android_Cross_Dir/tmp/$__AndroidArch/ +dpkg -x $__Android_Cross_Dir/deb/liblzma_5.2.3_$__AndroidArch.deb $__Android_Cross_Dir/tmp/$__AndroidArch/ +dpkg -x $__Android_Cross_Dir/deb/libunwind-dev_1.2.20170304_$__AndroidArch.deb $__Android_Cross_Dir/tmp/$__AndroidArch/ +dpkg -x $__Android_Cross_Dir/deb/libunwind_1.2.20170304_$__AndroidArch.deb $__Android_Cross_Dir/tmp/$__AndroidArch/ + +cp -R $__Android_Cross_Dir/tmp/$__AndroidArch/data/data/com.termux/files/usr/* $__ToolchainDir/sysroot/usr/ + +# Generate platform file for build.sh script to assign to __DistroRid +echo "Generating platform file..." + +echo "RID=android.21-arm64" > $__ToolchainDir/sysroot/android_platform +echo Now run: +echo CONFIG_DIR=\`realpath cross/android/$__BuildArch\` ROOTFS_DIR=\`realpath $__ToolchainDir/sysroot\` ./build.sh cross $__BuildArch skipgenerateversion skipnuget cmakeargs -DENABLE_LLDBPLUGIN=0 + diff --git a/eng/common/cross/build-rootfs.sh b/eng/common/cross/build-rootfs.sh new file mode 100755 index 0000000000..805948ca83 --- /dev/null +++ b/eng/common/cross/build-rootfs.sh @@ -0,0 +1,210 @@ +#!/usr/bin/env bash + +usage() +{ + echo "Usage: $0 [BuildArch] [LinuxCodeName] [lldbx.y] [--skipunmount]" + echo "BuildArch can be: arm(default), armel, arm64, x86" + echo "LinuxCodeName - optional, Code name for Linux, can be: trusty(default), vivid, wily, xenial, zesty, bionic, alpine. If BuildArch is armel, LinuxCodeName is jessie(default) or tizen." + echo "lldbx.y - optional, LLDB version, can be: lldb3.6(default), lldb3.8, lldb3.9, lldb4.0, no-lldb. Ignored for alpine" + echo "--skipunmount - optional, will skip the unmount of rootfs folder." + exit 1 +} + +__LinuxCodeName=trusty +__CrossDir=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd ) +__InitialDir=$PWD +__BuildArch=arm +__UbuntuArch=armhf +__UbuntuRepo="http://ports.ubuntu.com/" +__LLDB_Package="lldb-3.6-dev" +__SkipUnmount=0 + +# base development support +__UbuntuPackages="build-essential" + +__AlpinePackages="alpine-base" +__AlpinePackages+=" build-base" +__AlpinePackages+=" linux-headers" +__AlpinePackages+=" lldb-dev" +__AlpinePackages+=" llvm-dev" + +# symlinks fixer +__UbuntuPackages+=" symlinks" + +# CoreCLR and CoreFX dependencies +__UbuntuPackages+=" libicu-dev" +__UbuntuPackages+=" liblttng-ust-dev" +__UbuntuPackages+=" libunwind8-dev" + +__AlpinePackages+=" gettext-dev" +__AlpinePackages+=" icu-dev" +__AlpinePackages+=" libunwind-dev" +__AlpinePackages+=" lttng-ust-dev" + +# CoreFX dependencies +__UbuntuPackages+=" libcurl4-openssl-dev" +__UbuntuPackages+=" libkrb5-dev" +__UbuntuPackages+=" libssl-dev" +__UbuntuPackages+=" zlib1g-dev" + +__AlpinePackages+=" curl-dev" +__AlpinePackages+=" krb5-dev" +__AlpinePackages+=" openssl-dev" +__AlpinePackages+=" zlib-dev" + +__UnprocessedBuildArgs= +for i in "$@" ; do + lowerI="$(echo $i | awk '{print tolower($0)}')" + case $lowerI in + -?|-h|--help) + usage + exit 1 + ;; + arm) + __BuildArch=arm + __UbuntuArch=armhf + __AlpineArch=armhf + __QEMUArch=arm + ;; + arm64) + __BuildArch=arm64 + __UbuntuArch=arm64 + __AlpineArch=aarch64 + __QEMUArch=aarch64 + ;; + armel) + __BuildArch=armel + __UbuntuArch=armel + __UbuntuRepo="http://ftp.debian.org/debian/" + __LinuxCodeName=jessie + ;; + x86) + __BuildArch=x86 + __UbuntuArch=i386 + __UbuntuRepo="http://archive.ubuntu.com/ubuntu/" + ;; + lldb3.6) + __LLDB_Package="lldb-3.6-dev" + ;; + lldb3.8) + __LLDB_Package="lldb-3.8-dev" + ;; + lldb3.9) + __LLDB_Package="liblldb-3.9-dev" + ;; + lldb4.0) + __LLDB_Package="liblldb-4.0-dev" + ;; + no-lldb) + unset __LLDB_Package + ;; + vivid) + if [ "$__LinuxCodeName" != "jessie" ]; then + __LinuxCodeName=vivid + fi + ;; + wily) + if [ "$__LinuxCodeName" != "jessie" ]; then + __LinuxCodeName=wily + fi + ;; + xenial) + if [ "$__LinuxCodeName" != "jessie" ]; then + __LinuxCodeName=xenial + fi + ;; + zesty) + if [ "$__LinuxCodeName" != "jessie" ]; then + __LinuxCodeName=zesty + fi + ;; + bionic) + if [ "$__LinuxCodeName" != "jessie" ]; then + __LinuxCodeName=bionic + fi + ;; + jessie) + __LinuxCodeName=jessie + __UbuntuRepo="http://ftp.debian.org/debian/" + ;; + tizen) + if [ "$__BuildArch" != "armel" ]; then + echo "Tizen is available only for armel." + usage; + exit 1; + fi + __LinuxCodeName= + __UbuntuRepo= + __Tizen=tizen + ;; + alpine) + __LinuxCodeName=alpine + __UbuntuRepo= + ;; + --skipunmount) + __SkipUnmount=1 + ;; + *) + __UnprocessedBuildArgs="$__UnprocessedBuildArgs $i" + ;; + esac +done + +if [ "$__BuildArch" == "armel" ]; then + __LLDB_Package="lldb-3.5-dev" +fi +__UbuntuPackages+=" ${__LLDB_Package:-}" + +__RootfsDir="$__CrossDir/rootfs/$__BuildArch" + +if [[ -n "$ROOTFS_DIR" ]]; then + __RootfsDir=$ROOTFS_DIR +fi + +if [ -d "$__RootfsDir" ]; then + if [ $__SkipUnmount == 0 ]; then + umount $__RootfsDir/* + fi + rm -rf $__RootfsDir +fi + +if [[ "$__LinuxCodeName" == "alpine" ]]; then + __ApkToolsVersion=2.9.1 + __AlpineVersion=3.7 + __ApkToolsDir=$(mktemp -d) + wget https://github.com/alpinelinux/apk-tools/releases/download/v$__ApkToolsVersion/apk-tools-$__ApkToolsVersion-x86_64-linux.tar.gz -P $__ApkToolsDir + tar -xf $__ApkToolsDir/apk-tools-$__ApkToolsVersion-x86_64-linux.tar.gz -C $__ApkToolsDir + mkdir -p $__RootfsDir/usr/bin + cp -v /usr/bin/qemu-$__QEMUArch-static $__RootfsDir/usr/bin + $__ApkToolsDir/apk-tools-$__ApkToolsVersion/apk \ + -X http://dl-cdn.alpinelinux.org/alpine/v$__AlpineVersion/main \ + -X http://dl-cdn.alpinelinux.org/alpine/v$__AlpineVersion/community \ + -X http://dl-cdn.alpinelinux.org/alpine/edge/testing \ + -U --allow-untrusted --root $__RootfsDir --arch $__AlpineArch --initdb \ + add $__AlpinePackages + rm -r $__ApkToolsDir +elif [[ -n $__LinuxCodeName ]]; then + qemu-debootstrap --arch $__UbuntuArch $__LinuxCodeName $__RootfsDir $__UbuntuRepo + cp $__CrossDir/$__BuildArch/sources.list.$__LinuxCodeName $__RootfsDir/etc/apt/sources.list + chroot $__RootfsDir apt-get update + chroot $__RootfsDir apt-get -f -y install + chroot $__RootfsDir apt-get -y install $__UbuntuPackages + chroot $__RootfsDir symlinks -cr /usr + + if [ $__SkipUnmount == 0 ]; then + umount $__RootfsDir/* + fi + + if [[ "$__BuildArch" == "arm" && "$__LinuxCodeName" == "trusty" ]]; then + pushd $__RootfsDir + patch -p1 < $__CrossDir/$__BuildArch/trusty.patch + patch -p1 < $__CrossDir/$__BuildArch/trusty-lttng-2.4.patch + popd + fi +elif [ "$__Tizen" == "tizen" ]; then + ROOTFS_DIR=$__RootfsDir $__CrossDir/$__BuildArch/tizen-build-rootfs.sh +else + echo "Unsupported target platform." + usage; + exit 1 +fi diff --git a/eng/common/cross/toolchain.cmake b/eng/common/cross/toolchain.cmake new file mode 100644 index 0000000000..071d411241 --- /dev/null +++ b/eng/common/cross/toolchain.cmake @@ -0,0 +1,138 @@ +set(CROSS_ROOTFS $ENV{ROOTFS_DIR}) + +set(TARGET_ARCH_NAME $ENV{TARGET_BUILD_ARCH}) +set(CMAKE_SYSTEM_NAME Linux) +set(CMAKE_SYSTEM_VERSION 1) + +if(TARGET_ARCH_NAME STREQUAL "armel") + set(CMAKE_SYSTEM_PROCESSOR armv7l) + set(TOOLCHAIN "arm-linux-gnueabi") + if("$ENV{__DistroRid}" MATCHES "tizen.*") + set(TIZEN_TOOLCHAIN "armv7l-tizen-linux-gnueabi/6.2.1") + endif() +elseif(TARGET_ARCH_NAME STREQUAL "arm") + set(CMAKE_SYSTEM_PROCESSOR armv7l) + if(EXISTS ${CROSS_ROOTFS}/usr/lib/gcc/armv6-alpine-linux-musleabihf) + set(TOOLCHAIN "armv6-alpine-linux-musleabihf") + else() + set(TOOLCHAIN "arm-linux-gnueabihf") + endif() +elseif(TARGET_ARCH_NAME STREQUAL "arm64") + set(CMAKE_SYSTEM_PROCESSOR aarch64) + if(EXISTS ${CROSS_ROOTFS}/usr/lib/gcc/aarch64-alpine-linux-musl) + set(TOOLCHAIN "aarch64-alpine-linux-musl") + else() + set(TOOLCHAIN "aarch64-linux-gnu") + endif() +elseif(TARGET_ARCH_NAME STREQUAL "x86") + set(CMAKE_SYSTEM_PROCESSOR i686) + set(TOOLCHAIN "i686-linux-gnu") +else() + message(FATAL_ERROR "Arch is ${TARGET_ARCH_NAME}. Only armel, arm, arm64 and x86 are supported!") +endif() + +# Specify include paths +if(TARGET_ARCH_NAME STREQUAL "armel") + if(DEFINED TIZEN_TOOLCHAIN) + include_directories(SYSTEM ${CROSS_ROOTFS}/usr/lib/gcc/${TIZEN_TOOLCHAIN}/include/c++/) + include_directories(SYSTEM ${CROSS_ROOTFS}/usr/lib/gcc/${TIZEN_TOOLCHAIN}/include/c++/armv7l-tizen-linux-gnueabi) + endif() +endif() + +# add_compile_param - adds only new options without duplicates. +# arg0 - list with result options, arg1 - list with new options. +# arg2 - optional argument, quick summary string for optional using CACHE FORCE mode. +macro(add_compile_param) + if(NOT ${ARGC} MATCHES "^(2|3)$") + message(FATAL_ERROR "Wrong using add_compile_param! Two or three parameters must be given! See add_compile_param description.") + endif() + foreach(OPTION ${ARGV1}) + if(NOT ${ARGV0} MATCHES "${OPTION}($| )") + set(${ARGV0} "${${ARGV0}} ${OPTION}") + if(${ARGC} EQUAL "3") # CACHE FORCE mode + set(${ARGV0} "${${ARGV0}}" CACHE STRING "${ARGV2}" FORCE) + endif() + endif() + endforeach() +endmacro() + +# Specify link flags +add_compile_param(CROSS_LINK_FLAGS "--sysroot=${CROSS_ROOTFS}") +add_compile_param(CROSS_LINK_FLAGS "--gcc-toolchain=${CROSS_ROOTFS}/usr") +add_compile_param(CROSS_LINK_FLAGS "--target=${TOOLCHAIN}") +add_compile_param(CROSS_LINK_FLAGS "-fuse-ld=gold") + +if(TARGET_ARCH_NAME STREQUAL "armel") + if(DEFINED TIZEN_TOOLCHAIN) # For Tizen only + add_compile_param(CROSS_LINK_FLAGS "-B${CROSS_ROOTFS}/usr/lib/gcc/${TIZEN_TOOLCHAIN}") + add_compile_param(CROSS_LINK_FLAGS "-L${CROSS_ROOTFS}/lib") + add_compile_param(CROSS_LINK_FLAGS "-L${CROSS_ROOTFS}/usr/lib") + add_compile_param(CROSS_LINK_FLAGS "-L${CROSS_ROOTFS}/usr/lib/gcc/${TIZEN_TOOLCHAIN}") + endif() +elseif(TARGET_ARCH_NAME STREQUAL "x86") + add_compile_param(CROSS_LINK_FLAGS "-m32") +endif() + +add_compile_param(CMAKE_EXE_LINKER_FLAGS "${CROSS_LINK_FLAGS}" "TOOLCHAIN_EXE_LINKER_FLAGS") +add_compile_param(CMAKE_SHARED_LINKER_FLAGS "${CROSS_LINK_FLAGS}" "TOOLCHAIN_EXE_LINKER_FLAGS") +add_compile_param(CMAKE_MODULE_LINKER_FLAGS "${CROSS_LINK_FLAGS}" "TOOLCHAIN_EXE_LINKER_FLAGS") + +# Specify compile options +add_compile_options("--sysroot=${CROSS_ROOTFS}") +add_compile_options("--target=${TOOLCHAIN}") +add_compile_options("--gcc-toolchain=${CROSS_ROOTFS}/usr") + +if(TARGET_ARCH_NAME MATCHES "^(arm|armel|arm64)$") + set(CMAKE_C_COMPILER_TARGET ${TOOLCHAIN}) + set(CMAKE_CXX_COMPILER_TARGET ${TOOLCHAIN}) + set(CMAKE_ASM_COMPILER_TARGET ${TOOLCHAIN}) +endif() + +if(TARGET_ARCH_NAME MATCHES "^(arm|armel)$") + add_compile_options(-mthumb) + add_compile_options(-mfpu=vfpv3) + if(TARGET_ARCH_NAME STREQUAL "armel") + add_compile_options(-mfloat-abi=softfp) + if(DEFINED TIZEN_TOOLCHAIN) + add_compile_options(-Wno-deprecated-declarations) # compile-time option + add_compile_options(-D__extern_always_inline=inline) # compile-time option + endif() + endif() +elseif(TARGET_ARCH_NAME STREQUAL "x86") + add_compile_options(-m32) + add_compile_options(-Wno-error=unused-command-line-argument) +endif() + +# Set LLDB include and library paths +if(TARGET_ARCH_NAME MATCHES "^(arm|armel|x86)$") + if(TARGET_ARCH_NAME STREQUAL "x86") + set(LLVM_CROSS_DIR "$ENV{LLVM_CROSS_HOME}") + else() # arm/armel case + set(LLVM_CROSS_DIR "$ENV{LLVM_ARM_HOME}") + endif() + if(LLVM_CROSS_DIR) + set(WITH_LLDB_LIBS "${LLVM_CROSS_DIR}/lib/" CACHE STRING "") + set(WITH_LLDB_INCLUDES "${LLVM_CROSS_DIR}/include" CACHE STRING "") + set(LLDB_H "${WITH_LLDB_INCLUDES}" CACHE STRING "") + set(LLDB "${LLVM_CROSS_DIR}/lib/liblldb.so" CACHE STRING "") + else() + if(TARGET_ARCH_NAME STREQUAL "x86") + set(WITH_LLDB_LIBS "${CROSS_ROOTFS}/usr/lib/i386-linux-gnu" CACHE STRING "") + set(CHECK_LLVM_DIR "${CROSS_ROOTFS}/usr/lib/llvm-3.8/include") + if(EXISTS "${CHECK_LLVM_DIR}" AND IS_DIRECTORY "${CHECK_LLVM_DIR}") + set(WITH_LLDB_INCLUDES "${CHECK_LLVM_DIR}") + else() + set(WITH_LLDB_INCLUDES "${CROSS_ROOTFS}/usr/lib/llvm-3.6/include") + endif() + else() # arm/armel case + set(WITH_LLDB_LIBS "${CROSS_ROOTFS}/usr/lib/${TOOLCHAIN}" CACHE STRING "") + set(WITH_LLDB_INCLUDES "${CROSS_ROOTFS}/usr/lib/llvm-3.6/include" CACHE STRING "") + endif() + endif() +endif() + +set(CMAKE_FIND_ROOT_PATH "${CROSS_ROOTFS}") +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) +set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) diff --git a/eng/common/cross/x86/sources.list.bionic b/eng/common/cross/x86/sources.list.bionic new file mode 100644 index 0000000000..a71ccadcff --- /dev/null +++ b/eng/common/cross/x86/sources.list.bionic @@ -0,0 +1,11 @@ +deb http://archive.ubuntu.com/ubuntu/ bionic main restricted universe +deb-src http://archive.ubuntu.com/ubuntu/ bionic main restricted universe + +deb http://archive.ubuntu.com/ubuntu/ bionic-updates main restricted universe +deb-src http://archive.ubuntu.com/ubuntu/ bionic-updates main restricted universe + +deb http://archive.ubuntu.com/ubuntu/ bionic-backports main restricted +deb-src http://archive.ubuntu.com/ubuntu/ bionic-backports main restricted + +deb http://archive.ubuntu.com/ubuntu/ bionic-security main restricted universe multiverse +deb-src http://archive.ubuntu.com/ubuntu/ bionic-security main restricted universe multiverse diff --git a/eng/common/cross/x86/sources.list.trusty b/eng/common/cross/x86/sources.list.trusty new file mode 100644 index 0000000000..9b3085436e --- /dev/null +++ b/eng/common/cross/x86/sources.list.trusty @@ -0,0 +1,11 @@ +deb http://archive.ubuntu.com/ubuntu/ trusty main restricted universe +deb-src http://archive.ubuntu.com/ubuntu/ trusty main restricted universe + +deb http://archive.ubuntu.com/ubuntu/ trusty-updates main restricted universe +deb-src http://archive.ubuntu.com/ubuntu/ trusty-updates main restricted universe + +deb http://archive.ubuntu.com/ubuntu/ trusty-backports main restricted +deb-src http://archive.ubuntu.com/ubuntu/ trusty-backports main restricted + +deb http://archive.ubuntu.com/ubuntu/ trusty-security main restricted universe multiverse +deb-src http://archive.ubuntu.com/ubuntu/ trusty-security main restricted universe multiverse diff --git a/eng/common/cross/x86/sources.list.vivid b/eng/common/cross/x86/sources.list.vivid new file mode 100644 index 0000000000..26d37b20fc --- /dev/null +++ b/eng/common/cross/x86/sources.list.vivid @@ -0,0 +1,11 @@ +deb http://archive.ubuntu.com/ubuntu/ vivid main restricted universe +deb-src http://archive.ubuntu.com/ubuntu/ vivid main restricted universe + +deb http://archive.ubuntu.com/ubuntu/ vivid-updates main restricted universe +deb-src http://archive.ubuntu.com/ubuntu/ vivid-updates main restricted universe + +deb http://archive.ubuntu.com/ubuntu/ vivid-backports main restricted +deb-src http://archive.ubuntu.com/ubuntu/ vivid-backports main restricted + +deb http://archive.ubuntu.com/ubuntu/ vivid-security main restricted universe multiverse +deb-src http://archive.ubuntu.com/ubuntu/ vivid-security main restricted universe multiverse diff --git a/eng/common/cross/x86/sources.list.wily b/eng/common/cross/x86/sources.list.wily new file mode 100644 index 0000000000..c4b0b442ab --- /dev/null +++ b/eng/common/cross/x86/sources.list.wily @@ -0,0 +1,11 @@ +deb http://archive.ubuntu.com/ubuntu/ wily main restricted universe +deb-src http://archive.ubuntu.com/ubuntu/ wily main restricted universe + +deb http://archive.ubuntu.com/ubuntu/ wily-updates main restricted universe +deb-src http://archive.ubuntu.com/ubuntu/ wily-updates main restricted universe + +deb http://archive.ubuntu.com/ubuntu/ wily-backports main restricted +deb-src http://archive.ubuntu.com/ubuntu/ wily-backports main restricted + +deb http://archive.ubuntu.com/ubuntu/ wily-security main restricted universe multiverse +deb-src http://archive.ubuntu.com/ubuntu/ wily-security main restricted universe multiverse diff --git a/eng/common/cross/x86/sources.list.xenial b/eng/common/cross/x86/sources.list.xenial new file mode 100644 index 0000000000..ad9c5a0144 --- /dev/null +++ b/eng/common/cross/x86/sources.list.xenial @@ -0,0 +1,11 @@ +deb http://archive.ubuntu.com/ubuntu/ xenial main restricted universe +deb-src http://archive.ubuntu.com/ubuntu/ xenial main restricted universe + +deb http://archive.ubuntu.com/ubuntu/ xenial-updates main restricted universe +deb-src http://archive.ubuntu.com/ubuntu/ xenial-updates main restricted universe + +deb http://archive.ubuntu.com/ubuntu/ xenial-backports main restricted +deb-src http://archive.ubuntu.com/ubuntu/ xenial-backports main restricted + +deb http://archive.ubuntu.com/ubuntu/ xenial-security main restricted universe multiverse +deb-src http://archive.ubuntu.com/ubuntu/ xenial-security main restricted universe multiverse diff --git a/eng/common/darc-init.ps1 b/eng/common/darc-init.ps1 new file mode 100644 index 0000000000..96cad844ba --- /dev/null +++ b/eng/common/darc-init.ps1 @@ -0,0 +1,32 @@ +param ( + $darcVersion = $null +) + +$verbosity = "m" +. $PSScriptRoot\tools.ps1 + +function InstallDarcCli ($darcVersion) { + $darcCliPackageName = "microsoft.dotnet.darc" + + $dotnetRoot = InitializeDotNetCli -install:$true + $dotnet = "$dotnetRoot\dotnet.exe" + $toolList = Invoke-Expression "& `"$dotnet`" tool list -g" + + if ($toolList -like "*$darcCliPackageName*") { + Invoke-Expression "& `"$dotnet`" tool uninstall $darcCliPackageName -g" + } + + # Until we can anonymously query the BAR API for the latest arcade-services + # build applied to the PROD channel, this is hardcoded. + if (-not $darcVersion) { + $darcVersion = '1.1.0-beta.19057.9' + } + + $arcadeServicesSource = 'https://dotnetfeed.blob.core.windows.net/dotnet-arcade/index.json' + + Write-Host "Installing Darc CLI version $darcVersion..." + Write-Host "You may need to restart your command window if this is the first dotnet tool you have installed." + Invoke-Expression "& `"$dotnet`" tool install $darcCliPackageName --version $darcVersion --add-source '$arcadeServicesSource' -v $verbosity -g" +} + +InstallDarcCli $darcVersion diff --git a/eng/common/darc-init.sh b/eng/common/darc-init.sh new file mode 100755 index 0000000000..bad07c3ae6 --- /dev/null +++ b/eng/common/darc-init.sh @@ -0,0 +1,38 @@ +#!/usr/bin/env bash + +source="${BASH_SOURCE[0]}" + +# resolve $source until the file is no longer a symlink +while [[ -h "$source" ]]; do + scriptroot="$( cd -P "$( dirname "$source" )" && pwd )" + source="$(readlink "$source")" + # if $source was a relative symlink, we need to resolve it relative to the path where the + # symlink file was located + [[ $source != /* ]] && source="$scriptroot/$source" +done +scriptroot="$( cd -P "$( dirname "$source" )" && pwd )" +verbosity=m + +. "$scriptroot/tools.sh" + +function InstallDarcCli { + local darc_cli_package_name="microsoft.dotnet.darc" + + InitializeDotNetCli + local dotnet_root=$_InitializeDotNetCli + + local uninstall_command=`$dotnet_root/dotnet tool uninstall $darc_cli_package_name -g` + local tool_list=$($dotnet_root/dotnet tool list -g) + if [[ $tool_list = *$darc_cli_package_name* ]]; then + echo $($dotnet_root/dotnet tool uninstall $darc_cli_package_name -g) + fi + + ReadGlobalVersion "Microsoft.DotNet.Arcade.Sdk" + local toolset_version=$_ReadGlobalVersion + + echo "Installing Darc CLI version $toolset_version..." + echo "You may need to restart your command shell if this is the first dotnet tool you have installed." + echo $($dotnet_root/dotnet tool install $darc_cli_package_name --version $toolset_version -v $verbosity -g) +} + +InstallDarcCli diff --git a/eng/common/helixpublish.proj b/eng/common/helixpublish.proj new file mode 100644 index 0000000000..d7f185856e --- /dev/null +++ b/eng/common/helixpublish.proj @@ -0,0 +1,26 @@ + + + + msbuild + + + + + %(Identity) + + + + + + $(WorkItemDirectory) + $(WorkItemCommand) + $(WorkItemTimeout) + + + + + + + + + diff --git a/eng/common/init-tools-native.cmd b/eng/common/init-tools-native.cmd new file mode 100644 index 0000000000..438cd548c4 --- /dev/null +++ b/eng/common/init-tools-native.cmd @@ -0,0 +1,3 @@ +@echo off +powershell -NoProfile -NoLogo -ExecutionPolicy ByPass -command "& """%~dp0init-tools-native.ps1""" %*" +exit /b %ErrorLevel% \ No newline at end of file diff --git a/eng/common/init-tools-native.ps1 b/eng/common/init-tools-native.ps1 new file mode 100644 index 0000000000..e25c60fed4 --- /dev/null +++ b/eng/common/init-tools-native.ps1 @@ -0,0 +1,128 @@ +<# +.SYNOPSIS +Entry point script for installing native tools + +.DESCRIPTION +Reads $RepoRoot\global.json file to determine native assets to install +and executes installers for those tools + +.PARAMETER BaseUri +Base file directory or Url from which to acquire tool archives + +.PARAMETER InstallDirectory +Directory to install native toolset. This is a command-line override for the default +Install directory precedence order: +- InstallDirectory command-line override +- NETCOREENG_INSTALL_DIRECTORY environment variable +- (default) %USERPROFILE%/.netcoreeng/native + +.PARAMETER Clean +Switch specifying to not install anything, but cleanup native asset folders + +.PARAMETER Force +Clean and then install tools + +.PARAMETER DownloadRetries +Total number of retry attempts + +.PARAMETER RetryWaitTimeInSeconds +Wait time between retry attempts in seconds + +.PARAMETER GlobalJsonFile +File path to global.json file + +.NOTES +#> +[CmdletBinding(PositionalBinding=$false)] +Param ( + [string] $BaseUri = "https://netcorenativeassets.blob.core.windows.net/resource-packages/external", + [string] $InstallDirectory, + [switch] $Clean = $False, + [switch] $Force = $False, + [int] $DownloadRetries = 5, + [int] $RetryWaitTimeInSeconds = 30, + [string] $GlobalJsonFile = "$PSScriptRoot\..\..\global.json" +) + +Set-StrictMode -version 2.0 +$ErrorActionPreference="Stop" + +Import-Module -Name (Join-Path $PSScriptRoot "native\CommonLibrary.psm1") + +try { + # Define verbose switch if undefined + $Verbose = $VerbosePreference -Eq "Continue" + + $EngCommonBaseDir = Join-Path $PSScriptRoot "native\" + $NativeBaseDir = $InstallDirectory + if (!$NativeBaseDir) { + $NativeBaseDir = CommonLibrary\Get-NativeInstallDirectory + } + $Env:CommonLibrary_NativeInstallDir = $NativeBaseDir + $InstallBin = Join-Path $NativeBaseDir "bin" + $InstallerPath = Join-Path $EngCommonBaseDir "install-tool.ps1" + + # Process tools list + Write-Host "Processing $GlobalJsonFile" + If (-Not (Test-Path $GlobalJsonFile)) { + Write-Host "Unable to find '$GlobalJsonFile'" + exit 0 + } + $NativeTools = Get-Content($GlobalJsonFile) -Raw | + ConvertFrom-Json | + Select-Object -Expand "native-tools" -ErrorAction SilentlyContinue + if ($NativeTools) { + $NativeTools.PSObject.Properties | ForEach-Object { + $ToolName = $_.Name + $ToolVersion = $_.Value + $LocalInstallerCommand = $InstallerPath + $LocalInstallerCommand += " -ToolName $ToolName" + $LocalInstallerCommand += " -InstallPath $InstallBin" + $LocalInstallerCommand += " -BaseUri $BaseUri" + $LocalInstallerCommand += " -CommonLibraryDirectory $EngCommonBaseDir" + $LocalInstallerCommand += " -Version $ToolVersion" + + if ($Verbose) { + $LocalInstallerCommand += " -Verbose" + } + if (Get-Variable 'Force' -ErrorAction 'SilentlyContinue') { + if($Force) { + $LocalInstallerCommand += " -Force" + } + } + if ($Clean) { + $LocalInstallerCommand += " -Clean" + } + + Write-Verbose "Installing $ToolName version $ToolVersion" + Write-Verbose "Executing '$LocalInstallerCommand'" + Invoke-Expression "$LocalInstallerCommand" + if ($LASTEXITCODE -Ne "0") { + Write-Error "Execution failed" + exit 1 + } + } + } + else { + Write-Host "No native tools defined in global.json" + exit 0 + } + + if ($Clean) { + exit 0 + } + if (Test-Path $InstallBin) { + Write-Host "Native tools are available from" (Convert-Path -Path $InstallBin) + Write-Host "##vso[task.prependpath]$(Convert-Path -Path $InstallBin)" + } + else { + Write-Error "Native tools install directory does not exist, installation failed" + exit 1 + } + exit 0 +} +catch { + Write-Host $_ + Write-Host $_.Exception + exit 1 +} diff --git a/eng/common/init-tools-native.sh b/eng/common/init-tools-native.sh new file mode 100755 index 0000000000..54b70f678b --- /dev/null +++ b/eng/common/init-tools-native.sh @@ -0,0 +1,145 @@ +#!/usr/bin/env bash + +source="${BASH_SOURCE[0]}" +scriptroot="$( cd -P "$( dirname "$source" )" && pwd )" + +base_uri='https://netcorenativeassets.blob.core.windows.net/resource-packages/external' +install_directory='' +clean=false +force=false +download_retries=5 +retry_wait_time_seconds=30 +global_json_file="${scriptroot}/../../global.json" +declare -A native_assets + +. $scriptroot/native/common-library.sh + +while (($# > 0)); do + lowerI="$(echo $1 | awk '{print tolower($0)}')" + case $lowerI in + --baseuri) + base_uri=$2 + shift 2 + ;; + --installdirectory) + install_directory=$2 + shift 2 + ;; + --clean) + clean=true + shift 1 + ;; + --force) + force=true + shift 1 + ;; + --downloadretries) + download_retries=$2 + shift 2 + ;; + --retrywaittimeseconds) + retry_wait_time_seconds=$2 + shift 2 + ;; + --help) + echo "Common settings:" + echo " --installdirectory Directory to install native toolset." + echo " This is a command-line override for the default" + echo " Install directory precedence order:" + echo " - InstallDirectory command-line override" + echo " - NETCOREENG_INSTALL_DIRECTORY environment variable" + echo " - (default) %USERPROFILE%/.netcoreeng/native" + echo "" + echo " --clean Switch specifying not to install anything, but cleanup native asset folders" + echo " --force Clean and then install tools" + echo " --help Print help and exit" + echo "" + echo "Advanced settings:" + echo " --baseuri Base URI for where to download native tools from" + echo " --downloadretries Number of times a download should be attempted" + echo " --retrywaittimeseconds Wait time between download attempts" + echo "" + exit 0 + ;; + esac +done + +function ReadGlobalJsonNativeTools { + # Get the native-tools section from the global.json. + local native_tools_section=$(cat $global_json_file | awk '/"native-tools"/,/}/') + # Only extract the contents of the object. + local native_tools_list=$(echo $native_tools_section | awk -F"[{}]" '{print $2}') + native_tools_list=${native_tools_list//[\" ]/} + native_tools_list=${native_tools_list//,/$'\n'} + + local old_IFS=$IFS + while read -r line; do + # Lines are of the form: 'tool:version' + IFS=: + while read -r key value; do + native_assets[$key]=$value + done <<< "$line" + done <<< "$native_tools_list" + IFS=$old_IFS + + return 0; +} + +native_base_dir=$install_directory +if [[ -z $install_directory ]]; then + native_base_dir=$(GetNativeInstallDirectory) +fi + +install_bin="${native_base_dir}/bin" + +ReadGlobalJsonNativeTools + +if [[ ${#native_assets[@]} -eq 0 ]]; then + echo "No native tools defined in global.json" + exit 0; +else + native_installer_dir="$scriptroot/native" + for tool in "${!native_assets[@]}" + do + tool_version=${native_assets[$tool]} + installer_name="install-$tool.sh" + installer_command="$native_installer_dir/$installer_name" + installer_command+=" --baseuri $base_uri" + installer_command+=" --installpath $install_bin" + installer_command+=" --version $tool_version" + + if [[ $force = true ]]; then + installer_command+=" --force" + fi + + if [[ $clean = true ]]; then + installer_command+=" --clean" + fi + + echo "Installing $tool version $tool_version" + echo "Executing '$installer_command'" + $installer_command + + if [[ $? != 0 ]]; then + echo "Execution Failed" >&2 + exit 1 + fi + done +fi + +if [[ ! -z $clean ]]; then + exit 0 +fi + +if [[ -d $install_bin ]]; then + echo "Native tools are available from $install_bin" + if [[ !-z BUILD_BUILDNUMBER ]]; then + echo "##vso[task.prependpath]$install_bin" + fi +else + echo "Native tools install directory does not exist, installation failed" >&2 + exit 1 +fi + +exit 0 + diff --git a/eng/common/msbuild.ps1 b/eng/common/msbuild.ps1 new file mode 100644 index 0000000000..b37fd3d5e9 --- /dev/null +++ b/eng/common/msbuild.ps1 @@ -0,0 +1,27 @@ +[CmdletBinding(PositionalBinding=$false)] +Param( + [string] $verbosity = "minimal", + [bool] $warnAsError = $true, + [bool] $nodeReuse = $true, + [switch] $ci, + [switch] $prepareMachine, + [Parameter(ValueFromRemainingArguments=$true)][String[]]$extraArgs +) + +. $PSScriptRoot\tools.ps1 + +try { + if ($ci) { + $nodeReuse = $false + } + + MSBuild @extraArgs +} +catch { + Write-Host $_ + Write-Host $_.Exception + Write-Host $_.ScriptStackTrace + ExitWithExitCode 1 +} + +ExitWithExitCode 0 \ No newline at end of file diff --git a/eng/common/msbuild.sh b/eng/common/msbuild.sh new file mode 100755 index 0000000000..8160cd5a59 --- /dev/null +++ b/eng/common/msbuild.sh @@ -0,0 +1,58 @@ +#!/usr/bin/env bash + +source="${BASH_SOURCE[0]}" + +# resolve $source until the file is no longer a symlink +while [[ -h "$source" ]]; do + scriptroot="$( cd -P "$( dirname "$source" )" && pwd )" + source="$(readlink "$source")" + # if $source was a relative symlink, we need to resolve it relative to the path where the + # symlink file was located + [[ $source != /* ]] && source="$scriptroot/$source" +done +scriptroot="$( cd -P "$( dirname "$source" )" && pwd )" + +verbosity='minimal' +warn_as_error=true +node_reuse=true +prepare_machine=false +extra_args='' + +while (($# > 0)); do + lowerI="$(echo $1 | awk '{print tolower($0)}')" + case $lowerI in + --verbosity) + verbosity=$2 + shift 2 + ;; + --warnaserror) + warn_as_error=$2 + shift 2 + ;; + --nodereuse) + node_reuse=$2 + shift 2 + ;; + --ci) + ci=true + shift 1 + ;; + --preparemachine) + prepare_machine=true + shift 1 + ;; + *) + extra_args="$extra_args $1" + shift 1 + ;; + esac +done + +. "$scriptroot/tools.sh" + +if [[ "$ci" == true ]]; then + node_reuse=false +fi + +MSBuild $extra_args +ExitWithExitCode 0 diff --git a/eng/common/native/CommonLibrary.psm1 b/eng/common/native/CommonLibrary.psm1 new file mode 100644 index 0000000000..f286ae0cde --- /dev/null +++ b/eng/common/native/CommonLibrary.psm1 @@ -0,0 +1,358 @@ +<# +.SYNOPSIS +Helper module to install an archive to a directory + +.DESCRIPTION +Helper module to download and extract an archive to a specified directory + +.PARAMETER Uri +Uri of artifact to download + +.PARAMETER InstallDirectory +Directory to extract artifact contents to + +.PARAMETER Force +Force download / extraction if file or contents already exist. Default = False + +.PARAMETER DownloadRetries +Total number of retry attempts. Default = 5 + +.PARAMETER RetryWaitTimeInSeconds +Wait time between retry attempts in seconds. Default = 30 + +.NOTES +Returns False if download or extraction fail, True otherwise +#> +function DownloadAndExtract { + [CmdletBinding(PositionalBinding=$false)] + Param ( + [Parameter(Mandatory=$True)] + [string] $Uri, + [Parameter(Mandatory=$True)] + [string] $InstallDirectory, + [switch] $Force = $False, + [int] $DownloadRetries = 5, + [int] $RetryWaitTimeInSeconds = 30 + ) + # Define verbose switch if undefined + $Verbose = $VerbosePreference -Eq "Continue" + + $TempToolPath = CommonLibrary\Get-TempPathFilename -Path $Uri + + # Download native tool + $DownloadStatus = CommonLibrary\Get-File -Uri $Uri ` + -Path $TempToolPath ` + -DownloadRetries $DownloadRetries ` + -RetryWaitTimeInSeconds $RetryWaitTimeInSeconds ` + -Force:$Force ` + -Verbose:$Verbose + + if ($DownloadStatus -Eq $False) { + Write-Error "Download failed" + return $False + } + + # Extract native tool + $UnzipStatus = CommonLibrary\Expand-Zip -ZipPath $TempToolPath ` + -OutputDirectory $InstallDirectory ` + -Force:$Force ` + -Verbose:$Verbose + + if ($UnzipStatus -Eq $False) { + Write-Error "Unzip failed" + return $False + } + return $True +} + +<# +.SYNOPSIS +Download a file, retry on failure + +.DESCRIPTION +Download specified file and retry if attempt fails + +.PARAMETER Uri +Uri of file to download. If Uri is a local path, the file will be copied instead of downloaded + +.PARAMETER Path +Path to download or copy uri file to + +.PARAMETER Force +Overwrite existing file if present. Default = False + +.PARAMETER DownloadRetries +Total number of retry attempts. Default = 5 + +.PARAMETER RetryWaitTimeInSeconds +Wait time between retry attempts in seconds Default = 30 + +#> +function Get-File { + [CmdletBinding(PositionalBinding=$false)] + Param ( + [Parameter(Mandatory=$True)] + [string] $Uri, + [Parameter(Mandatory=$True)] + [string] $Path, + [int] $DownloadRetries = 5, + [int] $RetryWaitTimeInSeconds = 30, + [switch] $Force = $False + ) + $Attempt = 0 + + if ($Force) { + if (Test-Path $Path) { + Remove-Item $Path -Force + } + } + if (Test-Path $Path) { + Write-Host "File '$Path' already exists, skipping download" + return $True + } + + $DownloadDirectory = Split-Path -ErrorAction Ignore -Path "$Path" -Parent + if (-Not (Test-Path $DownloadDirectory)) { + New-Item -path $DownloadDirectory -force -itemType "Directory" | Out-Null + } + + if (Test-Path -IsValid -Path $Uri) { + Write-Verbose "'$Uri' is a file path, copying file to '$Path'" + Copy-Item -Path $Uri -Destination $Path + return $? + } + else { + Write-Verbose "Downloading $Uri" + while($Attempt -Lt $DownloadRetries) + { + try { + Invoke-WebRequest -UseBasicParsing -Uri $Uri -OutFile $Path + Write-Verbose "Downloaded to '$Path'" + return $True + } + catch { + $Attempt++ + if ($Attempt -Lt $DownloadRetries) { + $AttemptsLeft = $DownloadRetries - $Attempt + Write-Warning "Download failed, $AttemptsLeft attempts remaining, will retry in $RetryWaitTimeInSeconds seconds" + Start-Sleep -Seconds $RetryWaitTimeInSeconds + } + else { + Write-Error $_ + Write-Error $_.Exception + } + } + } + } + + return $False +} + +<# +.SYNOPSIS +Generate a shim for a native tool + +.DESCRIPTION +Creates a wrapper script (shim) that passes arguments forward to native tool assembly + +.PARAMETER ShimName +The name of the shim + +.PARAMETER ShimDirectory +The directory where shims are stored + +.PARAMETER ToolFilePath +Path to file that shim forwards to + +.PARAMETER Force +Replace shim if already present. Default = False + +.NOTES +Returns $True if generating shim succeeds, $False otherwise +#> +function New-ScriptShim { + [CmdletBinding(PositionalBinding=$false)] + Param ( + [Parameter(Mandatory=$True)] + [string] $ShimName, + [Parameter(Mandatory=$True)] + [string] $ShimDirectory, + [Parameter(Mandatory=$True)] + [string] $ToolFilePath, + [Parameter(Mandatory=$True)] + [string] $BaseUri, + [switch] $Force + ) + try { + Write-Verbose "Generating '$ShimName' shim" + + if (-Not (Test-Path $ToolFilePath)){ + Write-Error "Specified tool file path '$ToolFilePath' does not exist" + return $False + } + + # WinShimmer is a small .NET Framework program that creates .exe shims to bootstrapped programs + # Many of the checks for installed programs expect a .exe extension for Windows tools, rather + # than a .bat or .cmd file. + # Source: https://github.com/dotnet/arcade/tree/master/src/WinShimmer + if (-Not (Test-Path "$ShimDirectory\WinShimmer\winshimmer.exe")) { + $InstallStatus = DownloadAndExtract -Uri "$BaseUri/windows/winshimmer/WinShimmer.zip" ` + -InstallDirectory $ShimDirectory\WinShimmer ` + -Force:$Force ` + -DownloadRetries 2 ` + -RetryWaitTimeInSeconds 5 ` + -Verbose:$Verbose + } + + if ((Test-Path (Join-Path $ShimDirectory "$ShimName.exe"))) { + Write-Host "$ShimName.exe already exists; replacing..." + Remove-Item (Join-Path $ShimDirectory "$ShimName.exe") + } + + Invoke-Expression "$ShimDirectory\WinShimmer\winshimmer.exe $ShimName $ToolFilePath $ShimDirectory" + return $True + } + catch { + Write-Host $_ + Write-Host $_.Exception + return $False + } +} + +<# +.SYNOPSIS +Returns the machine architecture of the host machine + +.NOTES +Returns 'x64' on 64 bit machines + Returns 'x86' on 32 bit machines +#> +function Get-MachineArchitecture { + $ProcessorArchitecture = $Env:PROCESSOR_ARCHITECTURE + $ProcessorArchitectureW6432 = $Env:PROCESSOR_ARCHITEW6432 + if($ProcessorArchitecture -Eq "X86") + { + if(($ProcessorArchitectureW6432 -Eq "") -Or + ($ProcessorArchitectureW6432 -Eq "X86")) { + return "x86" + } + $ProcessorArchitecture = $ProcessorArchitectureW6432 + } + if (($ProcessorArchitecture -Eq "AMD64") -Or + ($ProcessorArchitecture -Eq "IA64") -Or + ($ProcessorArchitecture -Eq "ARM64")) { + return "x64" + } + return "x86" +} + +<# +.SYNOPSIS +Get the name of a temporary folder under the native install directory +#> +function Get-TempDirectory { + return Join-Path (Get-NativeInstallDirectory) "temp/" +} + +function Get-TempPathFilename { + [CmdletBinding(PositionalBinding=$false)] + Param ( + [Parameter(Mandatory=$True)] + [string] $Path + ) + $TempDir = CommonLibrary\Get-TempDirectory + $TempFilename = Split-Path $Path -leaf + $TempPath = Join-Path $TempDir $TempFilename + return $TempPath +} + +<# +.SYNOPSIS +Returns the base directory to use for native tool installation + +.NOTES +Returns the value of the NETCOREENG_INSTALL_DIRECTORY if that environment variable +is set, or otherwise returns an install directory under the %USERPROFILE% +#> +function Get-NativeInstallDirectory { + $InstallDir = $Env:NETCOREENG_INSTALL_DIRECTORY + if (!$InstallDir) { + $InstallDir = Join-Path $Env:USERPROFILE ".netcoreeng/native/" + } + return $InstallDir +} + +<# +.SYNOPSIS +Unzip an archive + +.DESCRIPTION +Powershell module to unzip an archive to a specified directory + +.PARAMETER ZipPath (Required) +Path to archive to unzip + +.PARAMETER OutputDirectory (Required) +Output directory for archive contents + +.PARAMETER Force +Overwrite output directory contents if they already exist + +.NOTES +- Returns True and does not perform an extraction if output directory already exists but Overwrite is not True. +- Returns True if unzip operation is successful +- Returns False if Overwrite is True and it is unable to remove contents of OutputDirectory +- Returns False if unable to extract zip archive +#> +function Expand-Zip { + [CmdletBinding(PositionalBinding=$false)] + Param ( + [Parameter(Mandatory=$True)] + [string] $ZipPath, + [Parameter(Mandatory=$True)] + [string] $OutputDirectory, + [switch] $Force + ) + + Write-Verbose "Extracting '$ZipPath' to '$OutputDirectory'" + try { + if ((Test-Path $OutputDirectory) -And (-Not $Force)) { + Write-Host "Directory '$OutputDirectory' already exists, skipping extract" + return $True + } + if (Test-Path $OutputDirectory) { + Write-Verbose "'Force' is 'True', but '$OutputDirectory' exists, removing directory" + Remove-Item $OutputDirectory -Force -Recurse + if ($? -Eq $False) { + Write-Error "Unable to remove '$OutputDirectory'" + return $False + } + } + if (-Not (Test-Path $OutputDirectory)) { + New-Item -path $OutputDirectory -Force -itemType "Directory" | Out-Null + } + + Add-Type -assembly "system.io.compression.filesystem" + [io.compression.zipfile]::ExtractToDirectory("$ZipPath", "$OutputDirectory") + if ($? -Eq $False) { + Write-Error "Unable to extract '$ZipPath'" + return $False + } + } + catch { + Write-Host $_ + Write-Host $_.Exception + + return $False + } + return $True +} + +export-modulemember -function DownloadAndExtract +export-modulemember -function Expand-Zip +export-modulemember -function Get-File +export-modulemember -function Get-MachineArchitecture +export-modulemember -function Get-NativeInstallDirectory +export-modulemember -function Get-TempDirectory +export-modulemember -function Get-TempPathFilename +export-modulemember -function New-ScriptShim diff --git a/eng/common/native/common-library.sh b/eng/common/native/common-library.sh new file mode 100755 index 0000000000..271bddfac5 --- /dev/null +++ b/eng/common/native/common-library.sh @@ -0,0 +1,168 @@ +#!/usr/bin/env bash + +function GetNativeInstallDirectory { + local install_dir + + if [[ -z $NETCOREENG_INSTALL_DIRECTORY ]]; then + install_dir=$HOME/.netcoreeng/native/ + else + install_dir=$NETCOREENG_INSTALL_DIRECTORY + fi + + echo $install_dir + return 0 +} + +function GetTempDirectory { + + echo $(GetNativeInstallDirectory)temp/ + return 0 +} + +function ExpandZip { + local zip_path=$1 + local output_directory=$2 + local force=${3:-false} + + echo "Extracting $zip_path to $output_directory" + if [[ -d $output_directory ]] && [[ $force = false ]]; then + echo "Directory '$output_directory' already exists, skipping extract" + return 0 + fi + + if [[ -d $output_directory ]]; then + echo "'Force flag enabled, but '$output_directory' exists. Removing directory" + rm -rf $output_directory + if [[ $? != 0 ]]; then + echo Unable to remove '$output_directory'>&2 + return 1 + fi + fi + + echo "Creating directory: '$output_directory'" + mkdir -p $output_directory + + echo "Extracting archive" + tar -xf $zip_path -C $output_directory + if [[ $? != 0 ]]; then + echo "Unable to extract '$zip_path'" >&2 + return 1 + fi + + return 0 +} + +function GetCurrentOS { + local unameOut="$(uname -s)" + case $unameOut in + Linux*) echo "Linux";; + Darwin*) echo "MacOS";; + esac + return 0 +} + +function GetFile { + local uri=$1 + local path=$2 + local force=${3:-false} + local download_retries=${4:-5} + local retry_wait_time_seconds=${5:-30} + + if [[ -f $path ]]; then + if [[ $force = false ]]; then + echo "File '$path' already exists. Skipping download" + return 0 + else + rm -rf $path + fi + fi + + if [[ -f $uri ]]; then + echo "'$uri' is a file path, copying file to '$path'" + cp $uri $path + return $? + fi + + echo "Downloading $uri" + # Use curl if available, otherwise use wget + if command -v curl > /dev/null; then + curl "$uri" -sSL --retry $download_retries --retry-delay $retry_wait_time_seconds --create-dirs -o "$path" --fail + else + wget -q -O "$path" "$uri" --tries="$download_retries" + fi + + return $? +} + +function GetTempPathFileName { + local path=$1 + + local temp_dir=$(GetTempDirectory) + local temp_file_name=$(basename $path) + echo $temp_dir$temp_file_name + return 0 +} + +function DownloadAndExtract { + local uri=$1 + local installDir=$2 + local force=${3:-false} + local download_retries=${4:-5} + local retry_wait_time_seconds=${5:-30} + + local temp_tool_path=$(GetTempPathFileName $uri) + + echo "downloading to: $temp_tool_path" + + # Download file + GetFile "$uri" "$temp_tool_path" $force $download_retries $retry_wait_time_seconds + if [[ $? != 0 ]]; then + echo "Failed to download '$uri' to '$temp_tool_path'." >&2 + return 1 + fi + + # Extract File + echo "extracting from $temp_tool_path to $installDir" + ExpandZip "$temp_tool_path" "$installDir" $force $download_retries $retry_wait_time_seconds + if [[ $? != 0 ]]; then + echo "Failed to extract '$temp_tool_path' to '$installDir'." >&2 + return 1 + fi + + return 0 +} + +function NewScriptShim { + local shimpath=$1 + local tool_file_path=$2 + local force=${3:-false} + + echo "Generating '$shimpath' shim" + if [[ -f $shimpath ]]; then + if [[ $force = false ]]; then + echo "File '$shimpath' already exists." >&2 + return 1 + else + rm -rf $shimpath + fi + fi + + if [[ ! -f $tool_file_path ]]; then + echo "Specified tool file path:'$tool_file_path' does not exist" >&2 + return 1 + fi + + local shim_contents=$'#!/usr/bin/env bash\n' + shim_contents+="SHIMARGS="$'$1\n' + shim_contents+="$tool_file_path"$' $SHIMARGS\n' + + # Write shim file + echo "$shim_contents" > $shimpath + + chmod +x $shimpath + + echo "Finished generating shim '$shimpath'" + + return $? +} + diff --git a/eng/common/native/install-cmake.sh b/eng/common/native/install-cmake.sh new file mode 100755 index 0000000000..293af6017d --- /dev/null +++ b/eng/common/native/install-cmake.sh @@ -0,0 +1,117 @@ +#!/usr/bin/env bash + +source="${BASH_SOURCE[0]}" +scriptroot="$( cd -P "$( dirname "$source" )" && pwd )" + +. $scriptroot/common-library.sh + +base_uri= +install_path= +version= +clean=false +force=false +download_retries=5 +retry_wait_time_seconds=30 + +while (($# > 0)); do + lowerI="$(echo $1 | awk '{print tolower($0)}')" + case $lowerI in + --baseuri) + base_uri=$2 + shift 2 + ;; + --installpath) + install_path=$2 + shift 2 + ;; + --version) + version=$2 + shift 2 + ;; + --clean) + clean=true + shift 1 + ;; + --force) + force=true + shift 1 + ;; + --downloadretries) + download_retries=$2 + shift 2 + ;; + --retrywaittimeseconds) + retry_wait_time_seconds=$2 + shift 2 + ;; + --help) + echo "Common settings:" + echo " --baseuri Base file directory or Url wrom which to acquire tool archives" + echo " --installpath Base directory to install native tool to" + echo " --clean Don't install the tool, just clean up the current install of the tool" + echo " --force Force install of tools even if they previously exist" + echo " --help Print help and exit" + echo "" + echo "Advanced settings:" + echo " --downloadretries Total number of retry attempts" + echo " --retrywaittimeseconds Wait time between retry attempts in seconds" + echo "" + exit 0 + ;; + esac +done + +tool_name="cmake" +tool_os=$(GetCurrentOS) +tool_folder=$(echo $tool_os | awk '{print tolower($0)}') +tool_arch="x86_64" +tool_name_moniker="$tool_name-$version-$tool_os-$tool_arch" +tool_install_directory="$install_path/$tool_name/$version" +tool_file_path="$tool_install_directory/$tool_name_moniker/bin/$tool_name" +shim_path="$install_path/$tool_name.sh" +uri="${base_uri}/$tool_folder/cmake/$tool_name_moniker.tar.gz" + +# Clean up tool and installers +if [[ $clean = true ]]; then + echo "Cleaning $tool_install_directory" + if [[ -d $tool_install_directory ]]; then + rm -rf $tool_install_directory + fi + + echo "Cleaning $shim_path" + if [[ -f $shim_path ]]; then + rm -rf $shim_path + fi + + tool_temp_path=$(GetTempPathFileName $uri) + echo "Cleaning $tool_temp_path" + if [[ -f $tool_temp_path ]]; then + rm -rf $tool_temp_path + fi + + exit 0 +fi + +# Install tool +if [[ -f $tool_file_path ]] && [[ $force = false ]]; then + echo "$tool_name ($version) already exists, skipping install" + exit 0 +fi + +DownloadAndExtract $uri $tool_install_directory $force $download_retries $retry_wait_time_seconds + +if [[ $? != 0 ]]; then + echo "Installation failed" >&2 + exit 1 +fi + +# Generate Shim +# Always rewrite shims so that we are referencing the expected version +NewScriptShim $shim_path $tool_file_path true + +if [[ $? != 0 ]]; then + echo "Shim generation failed" >&2 + exit 1 +fi + +exit 0 \ No newline at end of file diff --git a/eng/common/native/install-tool.ps1 b/eng/common/native/install-tool.ps1 new file mode 100644 index 0000000000..635ab3fd41 --- /dev/null +++ b/eng/common/native/install-tool.ps1 @@ -0,0 +1,130 @@ +<# +.SYNOPSIS +Install native tool + +.DESCRIPTION +Install cmake native tool from Azure blob storage + +.PARAMETER InstallPath +Base directory to install native tool to + +.PARAMETER BaseUri +Base file directory or Url from which to acquire tool archives + +.PARAMETER CommonLibraryDirectory +Path to folder containing common library modules + +.PARAMETER Force +Force install of tools even if they previously exist + +.PARAMETER Clean +Don't install the tool, just clean up the current install of the tool + +.PARAMETER DownloadRetries +Total number of retry attempts + +.PARAMETER RetryWaitTimeInSeconds +Wait time between retry attempts in seconds + +.NOTES +Returns 0 if install succeeds, 1 otherwise +#> +[CmdletBinding(PositionalBinding=$false)] +Param ( + [Parameter(Mandatory=$True)] + [string] $ToolName, + [Parameter(Mandatory=$True)] + [string] $InstallPath, + [Parameter(Mandatory=$True)] + [string] $BaseUri, + [Parameter(Mandatory=$True)] + [string] $Version, + [string] $CommonLibraryDirectory = $PSScriptRoot, + [switch] $Force = $False, + [switch] $Clean = $False, + [int] $DownloadRetries = 5, + [int] $RetryWaitTimeInSeconds = 30 +) + +# Import common library modules +Import-Module -Name (Join-Path $CommonLibraryDirectory "CommonLibrary.psm1") + +try { + # Define verbose switch if undefined + $Verbose = $VerbosePreference -Eq "Continue" + + $Arch = CommonLibrary\Get-MachineArchitecture + $ToolOs = "win64" + if($Arch -Eq "x32") { + $ToolOs = "win32" + } + $ToolNameMoniker = "$ToolName-$Version-$ToolOs-$Arch" + $ToolInstallDirectory = Join-Path $InstallPath "$ToolName\$Version\" + $Uri = "$BaseUri/windows/$ToolName/$ToolNameMoniker.zip" + $ShimPath = Join-Path $InstallPath "$ToolName.exe" + + if ($Clean) { + Write-Host "Cleaning $ToolInstallDirectory" + if (Test-Path $ToolInstallDirectory) { + Remove-Item $ToolInstallDirectory -Force -Recurse + } + Write-Host "Cleaning $ShimPath" + if (Test-Path $ShimPath) { + Remove-Item $ShimPath -Force + } + $ToolTempPath = CommonLibrary\Get-TempPathFilename -Path $Uri + Write-Host "Cleaning $ToolTempPath" + if (Test-Path $ToolTempPath) { + Remove-Item $ToolTempPath -Force + } + exit 0 + } + + # Install tool + if ((Test-Path $ToolInstallDirectory) -And (-Not $Force)) { + Write-Verbose "$ToolName ($Version) already exists, skipping install" + } + else { + $InstallStatus = CommonLibrary\DownloadAndExtract -Uri $Uri ` + -InstallDirectory $ToolInstallDirectory ` + -Force:$Force ` + -DownloadRetries $DownloadRetries ` + -RetryWaitTimeInSeconds $RetryWaitTimeInSeconds ` + -Verbose:$Verbose + + if ($InstallStatus -Eq $False) { + Write-Error "Installation failed" + exit 1 + } + } + + $ToolFilePath = Get-ChildItem $ToolInstallDirectory -Recurse -Filter "$ToolName.exe" | % { $_.FullName } + if (@($ToolFilePath).Length -Gt 1) { + Write-Error "There are multiple copies of $ToolName in $($ToolInstallDirectory): `n$(@($ToolFilePath | out-string))" + exit 1 + } elseif (@($ToolFilePath).Length -Lt 1) { + Write-Error "$ToolName was not found in $ToolFilePath." + exit 1 + } + + # Generate shim + # Always rewrite shims so that we are referencing the expected version + $GenerateShimStatus = CommonLibrary\New-ScriptShim -ShimName $ToolName ` + -ShimDirectory $InstallPath ` + -ToolFilePath "$ToolFilePath" ` + -BaseUri $BaseUri ` + -Force:$Force ` + -Verbose:$Verbose + + if ($GenerateShimStatus -Eq $False) { + Write-Error "Generate shim failed" + return 1 + } + + exit 0 +} +catch { + Write-Host $_ + Write-Host $_.Exception + exit 1 +} diff --git a/eng/common/sdk-task.ps1 b/eng/common/sdk-task.ps1 new file mode 100644 index 0000000000..9ba7530122 --- /dev/null +++ b/eng/common/sdk-task.ps1 @@ -0,0 +1,74 @@ +[CmdletBinding(PositionalBinding=$false)] +Param( + [string] $projects = "", + [string][Alias('v')]$verbosity = "minimal", + [string] $msbuildEngine = $null, + [bool] $warnAsError = $true, + [switch][Alias('bl')]$binaryLog, + [switch][Alias('r')]$restore, + [switch] $ci, + [switch] $prepareMachine, + [switch] $help, + [Parameter(ValueFromRemainingArguments=$true)][String[]]$properties +) + +. $PSScriptRoot\tools.ps1 + +function Print-Usage() { + Write-Host "Common settings:" + Write-Host " -v[erbosity] Msbuild verbosity: q[uiet], m[inimal], n[ormal], d[etailed], and diag[nostic]" + Write-Host " -[bl|binaryLog] Output binary log (short: -bl)" + Write-Host " -help Print help and exit" + Write-Host "" + + Write-Host "Advanced settings:" + Write-Host " -restore Restore dependencies (short: -r)" + Write-Host " -projects Semi-colon delimited list of sln/proj's from the Arcade sdk to build. Globbing is supported (*.sln)" + Write-Host " -ci Set when running on CI server" + Write-Host " -prepareMachine Prepare machine for CI run" + Write-Host " -msbuildEngine Msbuild engine to use to run build ('dotnet', 'vs', or unspecified)." + Write-Host "" + Write-Host "Command line arguments not listed above are passed thru to msbuild." + Write-Host "The above arguments can be shortened as much as to be unambiguous (e.g. -co for configuration, -t for test, etc.)." +} + +function Build { + $toolsetBuildProj = InitializeToolset + + $toolsetBuildProj = Join-Path (Split-Path $toolsetBuildProj -Parent) "SdkTasks\SdkTask.proj" + $bl = if ($binaryLog) { "/bl:" + (Join-Path $LogDir "SdkTask.binlog") } else { "" } + MSBuild $toolsetBuildProj ` + $bl ` + /p:Projects=$projects ` + /p:Restore=$restore ` + /p:RepoRoot=$RepoRoot ` + /p:ContinuousIntegrationBuild=$ci ` + @properties +} + +try { + if ($help -or (($null -ne $properties) -and ($properties.Contains("/help") -or $properties.Contains("/?")))) { + Print-Usage + exit 0 + } + + if ($projects -eq "") { + Write-Error "Missing required parameter '-projects '" + Print-Usage + ExitWithExitCode 1 + } + + if ($ci) { + $binaryLog = $true + } + + Build +} +catch { + Write-Host $_ + Write-Host $_.Exception + Write-Host $_.ScriptStackTrace + ExitWithExitCode 1 +} + +ExitWithExitCode 0 diff --git a/eng/common/templates/job/job.yml b/eng/common/templates/job/job.yml new file mode 100644 index 0000000000..5e293db35d --- /dev/null +++ b/eng/common/templates/job/job.yml @@ -0,0 +1,205 @@ +parameters: +# Job schema parameters - https://docs.microsoft.com/en-us/azure/devops/pipelines/yaml-schema?view=vsts&tabs=schema#job + cancelTimeoutInMinutes: '' + + condition: '' + + continueOnError: false + + container: '' + + dependsOn: '' + + displayName: '' + + steps: [] + + pool: '' + + strategy: '' + + timeoutInMinutes: '' + + variables: [] + + workspace: '' + +# Job base template specific parameters + # Optional: Enable installing Microbuild plugin + # if 'true', these "variables" must be specified in the variables object or as part of the queue matrix + # _TeamName - the name of your team + # _SignType - 'test' or 'real' + enableMicrobuild: false + + # Optional: Include PublishBuildArtifacts task + enablePublishBuildArtifacts: false + + # Optional: Enable publishing to the build asset registry + enablePublishBuildAssets: false + + # Optional: Include PublishTestResults task + enablePublishTestResults: false + + # Optional: enable sending telemetry + # if 'true', these "variables" must be specified in the variables object or as part of the queue matrix + # _HelixBuildConfig - differentiate between Debug, Release, other + # _HelixType - Example: build/product/ + # _HelixSource - Example: official/dotnet/arcade/$(Build.SourceBranch) + enableTelemetry: false + + # Optional: If specified, then automatically derive "_HelixSource" variable for telemetry + helixRepo: '' + + # Optional: Define the type for helix telemetry (must end in '/') + helixType: build/product/ + + # Required: name of the job + name: '' + + # Optional: should run as a public build even in the internal project + # if 'true', the build won't run any of the internal only steps, even if it is running in non-public projects. + runAsPublic: false + +# Internal resources (telemetry, microbuild) can only be accessed from non-public projects, +# and some (Microbuild) should only be applied to non-PR cases for internal builds. + +jobs: +- job: ${{ parameters.name }} + + ${{ if ne(parameters.cancelTimeoutInMinutes, '') }}: + cancelTimeoutInMinutes: ${{ parameters.cancelTimeoutInMinutes }} + + ${{ if ne(parameters.condition, '') }}: + condition: ${{ parameters.condition }} + + ${{ if ne(parameters.container, '') }}: + container: ${{ parameters.container }} + + ${{ if ne(parameters.continueOnError, '') }}: + continueOnError: ${{ parameters.continueOnError }} + + ${{ if ne(parameters.dependsOn, '') }}: + dependsOn: ${{ parameters.dependsOn }} + + ${{ if ne(parameters.displayName, '') }}: + displayName: ${{ parameters.displayName }} + + ${{ if ne(parameters.pool, '') }}: + pool: ${{ parameters.pool }} + + ${{ if ne(parameters.strategy, '') }}: + strategy: ${{ parameters.strategy }} + + ${{ if ne(parameters.timeoutInMinutes, '') }}: + timeoutInMinutes: ${{ parameters.timeoutInMinutes }} + + variables: + - ${{ each variable in parameters.variables }}: + # handle name-value variable syntax + # example: + # - name: [key] + # value: [value] + - ${{ if ne(variable.name, '') }}: + - name: ${{ variable.name }} + value: ${{ variable.value }} + + # handle variable groups + - ${{ if ne(variable.group, '') }}: + - group: ${{ variable.group }} + + # handle key-value variable syntax. + # example: + # - [key]: [value] + - ${{ if and(eq(variable.name, ''), eq(variable.group, '')) }}: + - ${{ each pair in variable }}: + - name: ${{ pair.key }} + value: ${{ pair.value }} + + # Add additional variables + - ${{ if and(ne(parameters.helixRepo, ''), eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notIn(variables['Build.Reason'], 'PullRequest')) }}: + - name: _HelixSource + value: official/${{ parameters.helixRepo }}/$(Build.SourceBranch) + - ${{ if and(ne(parameters.helixRepo, ''), or(ne(parameters.runAsPublic, 'false'), eq(variables['System.TeamProject'], 'public'), in(variables['Build.Reason'], 'PullRequest'))) }}: + - name: _HelixSource + value: pr/${{ parameters.helixRepo }}/$(Build.SourceBranch) + - name: _HelixType + value: ${{ parameters.helixType }} + - name: _HelixBuildConfig + value: $(_BuildConfig) + + ${{ if ne(parameters.workspace, '') }}: + workspace: ${{ parameters.workspace }} + + steps: + - ${{ if eq(parameters.enableTelemetry, 'true') }}: + - template: /eng/common/templates/steps/telemetry-start.yml + parameters: + buildConfig: $(_HelixBuildConfig) + helixSource: $(_HelixSource) + helixType: $(_HelixType) + runAsPublic: ${{ parameters.runAsPublic }} + + - ${{ if eq(parameters.enableMicrobuild, 'true') }}: + - ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: + - task: MicroBuildSigningPlugin@2 + displayName: Install MicroBuild plugin + inputs: + signType: $(_SignType) + zipSources: false + feedSource: https://dnceng.pkgs.visualstudio.com/_packaging/MicroBuildToolset/nuget/v3/index.json + env: + TeamName: $(_TeamName) + continueOnError: ${{ parameters.continueOnError }} + condition: and(succeeded(), in(variables['_SignType'], 'real', 'test'), eq(variables['Agent.Os'], 'Windows_NT')) + + - ${{ each step in parameters.steps }}: + - ${{ step }} + + - ${{ if eq(parameters.enableMicrobuild, 'true') }}: + - ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: + - task: MicroBuildCleanup@1 + displayName: Execute Microbuild cleanup tasks + condition: and(always(), in(variables['_SignType'], 'real', 'test'), eq(variables['Agent.Os'], 'Windows_NT')) + continueOnError: ${{ parameters.continueOnError }} + env: + TeamName: $(_TeamName) + + - ${{ if eq(parameters.enableTelemetry, 'true') }}: + - template: /eng/common/templates/steps/telemetry-end.yml + + - ${{ if eq(parameters.enablePublishBuildArtifacts, 'true') }}: + - task: PublishBuildArtifacts@1 + displayName: Publish Logs to VSTS + inputs: + PathtoPublish: '$(Build.SourcesDirectory)/artifacts/log/$(_BuildConfig)' + PublishLocation: Container + ArtifactName: $(Agent.Os)_$(Agent.JobName) + continueOnError: true + condition: always() + + - ${{ if eq(parameters.enablePublishTestResults, 'true') }}: + - task: PublishTestResults@2 + displayName: Publish Test Results + inputs: + testResultsFormat: 'xUnit' + testResultsFiles: '*.xml' + searchFolder: '$(Build.SourcesDirectory)/artifacts/TestResults/$(_BuildConfig)' + continueOnError: true + condition: always() + + - ${{ if and(eq(parameters.enablePublishBuildAssets, true), eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: + - task: CopyFiles@2 + displayName: Gather Asset Manifests + inputs: + SourceFolder: '$(Build.SourcesDirectory)/artifacts/log/$(_BuildConfig)/AssetManifest' + TargetFolder: '$(Build.StagingDirectory)/AssetManifests' + continueOnError: ${{ parameters.continueOnError }} + condition: and(succeeded(), eq(variables['_DotNetPublishToBlobFeed'], 'true')) + - task: PublishBuildArtifacts@1 + displayName: Push Asset Manifests + inputs: + PathtoPublish: '$(Build.StagingDirectory)/AssetManifests' + PublishLocation: Container + ArtifactName: AssetManifests + continueOnError: ${{ parameters.continueOnError }} + condition: and(succeeded(), eq(variables['_DotNetPublishToBlobFeed'], 'true')) \ No newline at end of file diff --git a/eng/common/templates/job/publish-build-assets.yml b/eng/common/templates/job/publish-build-assets.yml new file mode 100644 index 0000000000..c094658fef --- /dev/null +++ b/eng/common/templates/job/publish-build-assets.yml @@ -0,0 +1,63 @@ +parameters: + configuration: 'Debug' + + # Optional: condition for the job to run + condition: '' + + # Optional: 'true' if future jobs should run even if this job fails + continueOnError: false + + # Optional: dependencies of the job + dependsOn: '' + + # Optional: Include PublishBuildArtifacts task + enablePublishBuildArtifacts: false + + # Optional: A defined YAML pool - https://docs.microsoft.com/en-us/azure/devops/pipelines/yaml-schema?view=vsts&tabs=schema#pool + pool: {} + + # Optional: should run as a public build even in the internal project + # if 'true', the build won't run any of the internal only steps, even if it is running in non-public projects. + runAsPublic: false + +jobs: +- job: Asset_Registry_Publish + + dependsOn: ${{ parameters.dependsOn }} + + displayName: Publish to Build Asset Registry + + pool: ${{ parameters.pool }} + + variables: + - ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: + - name: _BuildConfig + value: ${{ parameters.configuration }} + - group: Publish-Build-Assets + + steps: + - ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: + - task: DownloadBuildArtifacts@0 + displayName: Download artifact + inputs: + artifactName: AssetManifests + downloadPath: '$(Build.StagingDirectory)/Download' + condition: ${{ parameters.condition }} + continueOnError: ${{ parameters.continueOnError }} + - script: eng\common\publishbuildassets.cmd + /p:ManifestsPath='$(Build.StagingDirectory)/Download/AssetManifests' + /p:BuildAssetRegistryToken=$(MaestroAccessToken) + /p:MaestroApiEndpoint=https://maestro-prod.westus2.cloudapp.azure.com + /p:Configuration=$(_BuildConfig) + displayName: Publish Build Assets + condition: ${{ parameters.condition }} + continueOnError: ${{ parameters.continueOnError }} + - ${{ if eq(parameters.enablePublishBuildArtifacts, 'true') }}: + - task: PublishBuildArtifacts@1 + displayName: Publish Logs to VSTS + inputs: + PathtoPublish: '$(Build.SourcesDirectory)/artifacts/log/$(_BuildConfig)' + PublishLocation: Container + ArtifactName: $(Agent.Os)_PublishBuildAssets + continueOnError: true + condition: always() diff --git a/eng/common/templates/jobs/jobs.yml b/eng/common/templates/jobs/jobs.yml new file mode 100644 index 0000000000..c7226b12ed --- /dev/null +++ b/eng/common/templates/jobs/jobs.yml @@ -0,0 +1,77 @@ +parameters: + # Optional: 'true' if failures in job.yml job should not fail the job + continueOnError: false + + # Optional: Enable installing Microbuild plugin + # if 'true', these "variables" must be specified in the variables object or as part of the queue matrix + # _TeamName - the name of your team + # _SignType - 'test' or 'real' + enableMicrobuild: false + + # Optional: Include PublishBuildArtifacts task + enablePublishBuildArtifacts: false + + # Optional: Enable publishing to the build asset registry + enablePublishBuildAssets: false + + # Optional: Include PublishTestResults task + enablePublishTestResults: false + + # Optional: enable sending telemetry + # if 'true', these "variables" must be specified in the variables object or as part of the queue matrix + # _HelixBuildConfig - differentiate between Debug, Release, other + # _HelixType - Example: build/product/ + # _HelixSource - Example: official/dotnet/arcade/$(Build.SourceBranch) + enableTelemetry: false + + # Required: A collection of jobs to run - https://docs.microsoft.com/en-us/azure/devops/pipelines/yaml-schema?view=vsts&tabs=schema#job + jobs: [] + + # Optional: If specified, then automatically derive "_HelixSource" variable for telemetry + helixRepo: '' + + # Optional: Define the type for helix telemetry (must end in '/') + helixType: build/product/ + + # Optional: Override automatically derived dependsOn value for "publish build assets" job + publishBuildAssetsDependsOn: '' + + # Optional: should run as a public build even in the internal project + # if 'true', the build won't run any of the internal only steps, even if it is running in non-public projects. + runAsPublic: false + +# Internal resources (telemetry, microbuild) can only be accessed from non-public projects, +# and some (Microbuild) should only be applied to non-PR cases for internal builds. + +jobs: +- ${{ each job in parameters.jobs }}: + - template: ../job/job.yml + parameters: + # pass along parameters + ${{ each parameter in parameters }}: + ${{ if ne(parameter.key, 'jobs') }}: + ${{ parameter.key }}: ${{ parameter.value }} + + # pass along job properties + ${{ each property in job }}: + ${{ if ne(property.key, 'job') }}: + ${{ property.key }}: ${{ property.value }} + + name: ${{ job.job }} + +- ${{ if and(eq(parameters.enablePublishBuildAssets, true), eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: + - template: ../job/publish-build-assets.yml + parameters: + continueOnError: ${{ parameters.continueOnError }} + dependsOn: + - ${{ if ne(parameters.publishBuildAssetsDependsOn, '') }}: + - ${{ each job in parameters.publishBuildAssetsDependsOn }}: + - ${{ job.job }} + - ${{ if eq(parameters.publishBuildAssetsDependsOn, '') }}: + - ${{ each job in parameters.jobs }}: + - ${{ job.job }} + pool: + vmImage: vs2017-win2016 + runAsPublic: ${{ parameters.runAsPublic }} + enablePublishBuildArtifacts: ${{ parameters.enablePublishBuildArtifacts }} + diff --git a/eng/common/templates/phases/base.yml b/eng/common/templates/phases/base.yml new file mode 100644 index 0000000000..0123cf43b1 --- /dev/null +++ b/eng/common/templates/phases/base.yml @@ -0,0 +1,130 @@ +parameters: + # Optional: Clean sources before building + clean: true + + # Optional: Git fetch depth + fetchDepth: '' + + # Optional: name of the phase (not specifying phase name may cause name collisions) + name: '' + # Optional: display name of the phase + displayName: '' + + # Optional: condition for the job to run + condition: '' + + # Optional: dependencies of the phase + dependsOn: '' + + # Required: A defined YAML queue + queue: {} + + # Required: build steps + steps: [] + + # Optional: variables + variables: {} + + # Optional: should run as a public build even in the internal project + # if 'true', the build won't run any of the internal only steps, even if it is running in non-public projects. + runAsPublic: false + + ## Telemetry variables + + # Optional: enable sending telemetry + # if 'true', these "variables" must be specified in the variables object or as part of the queue matrix + # _HelixBuildConfig - differentiate between Debug, Release, other + # _HelixSource - Example: build/product + # _HelixType - Example: official/dotnet/arcade/$(Build.SourceBranch) + enableTelemetry: false + + # Optional: Enable installing Microbuild plugin + # if 'true', these "variables" must be specified in the variables object or as part of the queue matrix + # _TeamName - the name of your team + # _SignType - 'test' or 'real' + enableMicrobuild: false + +# Internal resources (telemetry, microbuild) can only be accessed from non-public projects, +# and some (Microbuild) should only be applied to non-PR cases for internal builds. + +phases: +- phase: ${{ parameters.name }} + + ${{ if ne(parameters.displayName, '') }}: + displayName: ${{ parameters.displayName }} + + ${{ if ne(parameters.condition, '') }}: + condition: ${{ parameters.condition }} + + ${{ if ne(parameters.dependsOn, '') }}: + dependsOn: ${{ parameters.dependsOn }} + + queue: ${{ parameters.queue }} + + ${{ if ne(parameters.variables, '') }}: + variables: + ${{ insert }}: ${{ parameters.variables }} + + steps: + - checkout: self + clean: ${{ parameters.clean }} + ${{ if ne(parameters.fetchDepth, '') }}: + fetchDepth: ${{ parameters.fetchDepth }} + + - ${{ if eq(parameters.enableTelemetry, 'true') }}: + - template: /eng/common/templates/steps/telemetry-start.yml + parameters: + buildConfig: $(_HelixBuildConfig) + helixSource: $(_HelixSource) + helixType: $(_HelixType) + runAsPublic: ${{ parameters.runAsPublic }} + + - ${{ if eq(parameters.enableMicrobuild, 'true') }}: + # Internal only resource, and Microbuild signing shouldn't be applied to PRs. + - ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: + - task: MicroBuildSigningPlugin@2 + displayName: Install MicroBuild plugin + inputs: + signType: $(_SignType) + zipSources: false + feedSource: https://dnceng.pkgs.visualstudio.com/_packaging/MicroBuildToolset/nuget/v3/index.json + + env: + TeamName: $(_TeamName) + continueOnError: false + condition: and(succeeded(), in(variables['_SignType'], 'real', 'test'), eq(variables['Agent.Os'], 'Windows_NT')) + + # Run provided build steps + - ${{ parameters.steps }} + + - ${{ if eq(parameters.enableMicrobuild, 'true') }}: + # Internal only resources + - ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: + - task: MicroBuildCleanup@1 + displayName: Execute Microbuild cleanup tasks + condition: and(always(), in(variables['_SignType'], 'real', 'test'), eq(variables['Agent.Os'], 'Windows_NT')) + env: + TeamName: $(_TeamName) + + - ${{ if eq(parameters.enableTelemetry, 'true') }}: + - template: /eng/common/templates/steps/telemetry-end.yml + parameters: + helixSource: $(_HelixSource) + helixType: $(_HelixType) + + - ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: + - task: CopyFiles@2 + displayName: Gather Asset Manifests + inputs: + SourceFolder: '$(Build.SourcesDirectory)/artifacts/log/$(_BuildConfig)/AssetManifest' + TargetFolder: '$(Build.StagingDirectory)/AssetManifests' + continueOnError: false + condition: and(succeeded(), eq(variables['_DotNetPublishToBlobFeed'], 'true')) + - task: PublishBuildArtifacts@1 + displayName: Push Asset Manifests + inputs: + PathtoPublish: '$(Build.StagingDirectory)/AssetManifests' + PublishLocation: Container + ArtifactName: AssetManifests + continueOnError: false + condition: and(succeeded(), eq(variables['_DotNetPublishToBlobFeed'], 'true')) diff --git a/eng/common/templates/phases/publish-build-assets.yml b/eng/common/templates/phases/publish-build-assets.yml new file mode 100644 index 0000000000..0df6203b50 --- /dev/null +++ b/eng/common/templates/phases/publish-build-assets.yml @@ -0,0 +1,46 @@ +parameters: + dependsOn: '' + queue: {} + configuration: 'Debug' + condition: succeeded() + continueOnError: false + runAsPublic: false +phases: + - phase: Asset_Registry_Publish + displayName: Publish to Build Asset Registry + dependsOn: ${{ parameters.dependsOn }} + queue: ${{ parameters.queue }} + variables: + _BuildConfig: ${{ parameters.configuration }} + steps: + - ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: + - task: DownloadBuildArtifacts@0 + displayName: Download artifact + inputs: + artifactName: AssetManifests + downloadPath: '$(Build.StagingDirectory)/Download' + condition: ${{ parameters.condition }} + continueOnError: ${{ parameters.continueOnError }} + - task: AzureKeyVault@1 + inputs: + azureSubscription: 'DotNet-Engineering-Services_KeyVault' + KeyVaultName: EngKeyVault + SecretsFilter: 'MaestroAccessToken' + condition: ${{ parameters.condition }} + continueOnError: ${{ parameters.continueOnError }} + - script: eng\common\publishbuildassets.cmd + -configuration $(_BuildConfig) + /p:ManifestsPath='$(Build.StagingDirectory)/Download/AssetManifests' + /p:BuildAssetRegistryToken=$(MaestroAccessToken) + /p:MaestroApiEndpoint=https://maestro-prod.westus2.cloudapp.azure.com + displayName: Publish Build Assets + condition: ${{ parameters.condition }} + continueOnError: ${{ parameters.continueOnError }} + - task: PublishBuildArtifacts@1 + displayName: Publish Logs to VSTS + inputs: + PathtoPublish: '$(Build.SourcesDirectory)/artifacts/log/$(_BuildConfig)' + PublishLocation: Container + ArtifactName: $(Agent.Os)_Asset_Registry_Publish + continueOnError: true + condition: always() diff --git a/eng/common/templates/steps/build-reason.yml b/eng/common/templates/steps/build-reason.yml new file mode 100644 index 0000000000..eba58109b5 --- /dev/null +++ b/eng/common/templates/steps/build-reason.yml @@ -0,0 +1,12 @@ +# build-reason.yml +# Description: runs steps if build.reason condition is valid. conditions is a string of valid build reasons +# to include steps (',' separated). +parameters: + conditions: '' + steps: [] + +steps: + - ${{ if and( not(startsWith(parameters.conditions, 'not')), contains(parameters.conditions, variables['build.reason'])) }}: + - ${{ parameters.steps }} + - ${{ if and( startsWith(parameters.conditions, 'not'), not(contains(parameters.conditions, variables['build.reason']))) }}: + - ${{ parameters.steps }} diff --git a/eng/common/templates/steps/helix-publish.yml b/eng/common/templates/steps/helix-publish.yml new file mode 100644 index 0000000000..470ab65da0 --- /dev/null +++ b/eng/common/templates/steps/helix-publish.yml @@ -0,0 +1,51 @@ +parameters: + HelixSource: 'pr/dotnet-github-anon-kaonashi-bot' + HelixType: ̓'tests/default' + HelixBuild: $(Build.BuildNumber) + HelixTargetQueues: '' + HelixAccessToken: '' + HelixPreCommands: '' + HelixPostCommands: '' + WorkItemDirectory: '' + WorkItemCommand: '' + CorrelationPayloadDirectory: '' + XUnitProjects: '' + XUnitTargetFramework: '' + XUnitRunnerVersion: '' + IncludeDotNetCli: false + DotNetCliPackageType: '' + DotNetCliVersion: '' + EnableXUnitReporter: false + WaitForWorkItemCompletion: true + condition: succeeded() + continueOnError: false + +steps: + - task: DotNetCoreCLI@2 + inputs: + command: custom + projects: eng/common/helixpublish.proj + custom: msbuild + arguments: '/bl:$(Build.SourcesDirectory)/artifacts/log/$(_BuildConfig)/SendToHelix.binlog' + displayName: Send job to Helix + env: + HelixSource: ${{ parameters.HelixSource }} + HelixType: ${{ parameters.HelixType }} + HelixBuild: ${{ parameters.HelixBuild }} + HelixTargetQueues: ${{ parameters.HelixTargetQueues }} + HelixAccessToken: ${{ parameters.HelixAccessToken }} + HelixPreCommands: ${{ parameters.HelixPreCommands }} + HelixPostCommands: ${{ parameters.HelixPostCommands }} + WorkItemDirectory: ${{ parameters.WorkItemDirectory }} + WorkItemCommand: ${{ parameters.WorkItemCommand }} + CorrelationPayloadDirectory: ${{ parameters.CorrelationPayloadDirectory }} + XUnitProjects: ${{ parameters.XUnitProjects }} + XUnitRuntimeTargetFramework: ${{ parameters.XUnitTargetFramework }} + XUnitRunnerVersion: ${{ parameters.XUnitRunnerVersion }} + IncludeDotNetCli: ${{ parameters.IncludeDotNetCli }} + DotNetCliPackageType: ${{ parameters.DotNetCliPackageType }} + DotNetCliVersion: ${{ parameters.DotNetCliVersion }} + EnableXUnitReporter: ${{ parameters.EnableXUnitReporter }} + WaitForWorkItemCompletion: ${{ parameters.WaitForWorkItemCompletion }} + condition: ${{ parameters.condition }} + continueOnError: ${{ parameters.continueOnError }} diff --git a/eng/common/templates/steps/run-on-unix.yml b/eng/common/templates/steps/run-on-unix.yml new file mode 100644 index 0000000000..e1733814f6 --- /dev/null +++ b/eng/common/templates/steps/run-on-unix.yml @@ -0,0 +1,7 @@ +parameters: + agentOs: '' + steps: [] + +steps: +- ${{ if ne(parameters.agentOs, 'Windows_NT') }}: + - ${{ parameters.steps }} diff --git a/eng/common/templates/steps/run-on-windows.yml b/eng/common/templates/steps/run-on-windows.yml new file mode 100644 index 0000000000..73e7e9c275 --- /dev/null +++ b/eng/common/templates/steps/run-on-windows.yml @@ -0,0 +1,7 @@ +parameters: + agentOs: '' + steps: [] + +steps: +- ${{ if eq(parameters.agentOs, 'Windows_NT') }}: + - ${{ parameters.steps }} diff --git a/eng/common/templates/steps/run-script-ifequalelse.yml b/eng/common/templates/steps/run-script-ifequalelse.yml new file mode 100644 index 0000000000..3d1242f558 --- /dev/null +++ b/eng/common/templates/steps/run-script-ifequalelse.yml @@ -0,0 +1,33 @@ +parameters: + # if parameter1 equals parameter 2, run 'ifScript' command, else run 'elsescript' command + parameter1: '' + parameter2: '' + ifScript: '' + elseScript: '' + + # name of script step + name: Script + + # display name of script step + displayName: If-Equal-Else Script + + # environment + env: {} + + # conditional expression for step execution + condition: '' + +steps: +- ${{ if and(ne(parameters.ifScript, ''), eq(parameters.parameter1, parameters.parameter2)) }}: + - script: ${{ parameters.ifScript }} + name: ${{ parameters.name }} + displayName: ${{ parameters.displayName }} + env: ${{ parameters.env }} + condition: ${{ parameters.condition }} + +- ${{ if and(ne(parameters.elseScript, ''), ne(parameters.parameter1, parameters.parameter2)) }}: + - script: ${{ parameters.elseScript }} + name: ${{ parameters.name }} + displayName: ${{ parameters.displayName }} + env: ${{ parameters.env }} + condition: ${{ parameters.condition }} \ No newline at end of file diff --git a/eng/common/templates/steps/send-to-helix.yml b/eng/common/templates/steps/send-to-helix.yml new file mode 100644 index 0000000000..a5835c0f47 --- /dev/null +++ b/eng/common/templates/steps/send-to-helix.yml @@ -0,0 +1,81 @@ +parameters: + HelixSource: 'pr/default' # required -- sources must start with pr/, official/, prodcon/, or agent/ + HelixType: 'tests/default/' # required -- Helix telemetry which identifies what type of data this is; should include "test" for clarity and must end in '/' + HelixBuild: $(Build.BuildNumber) # required -- the build number Helix will use to identify this -- automatically set to the AzDO build number + HelixTargetQueues: '' # required -- semicolon delimited list of Helix queues to test on; see https://helix.dot.net/api/2018-03-14/info/queues for a list of queues + HelixAccessToken: '' # required -- access token to make Helix API requests; should be provided by the appropriate variable group + HelixPreCommands: '' # optional -- commands to run before Helix work item execution + HelixPostCommands: '' # optional -- commands to run after Helix work item execution + WorkItemDirectory: '' # optional -- a payload directory to zip up and send to Helix; requires WorkItemCommand; incompatible with XUnitProjects + WorkItemCommand: '' # optional -- a command to execute on the payload; requires WorkItemDirectory; incompatible with XUnitProjects + WorkItemTimeout: '' # optional -- a timeout in seconds for the work item command; requires WorkItemDirectory; incompatible with XUnitProjects + CorrelationPayloadDirectory: '' # optional -- a directory to zip up and send to Helix as a correlation payload + XUnitProjects: '' # optional -- semicolon delimited list of XUnitProjects to parse and send to Helix; requires XUnitRuntimeTargetFramework, XUnitPublishTargetFramework, XUnitRunnerVersion, and IncludeDotNetCli=true + XUnitPublishTargetFramework: '' # optional -- framework to use to publish your xUnit projects + XUnitRuntimeTargetFramework: '' # optional -- framework to use for the xUnit console runner + XUnitRunnerVersion: '' # optional -- version of the xUnit nuget package you wish to use on Helix; required for XUnitProjects + IncludeDotNetCli: false # optional -- true will download a version of the .NET CLI onto the Helix machine as a correlation payload; requires DotNetCliPackageType and DotNetCliVersion + DotNetCliPackageType: '' # optional -- either 'sdk' or 'runtime'; determines whether the sdk or runtime will be sent to Helix; see https://raw.githubusercontent.com/dotnet/core/master/release-notes/releases.json + DotNetCliVersion: '' # optional -- version of the CLI to send to Helix; based on this: https://raw.githubusercontent.com/dotnet/core/master/release-notes/releases.json + EnableXUnitReporter: false # optional -- true enables XUnit result reporting to Mission Control + WaitForWorkItemCompletion: true # optional -- true will make the task wait until work items have been completed and fail the build if work items fail. False is "fire and forget." + IsExternal: false # [DEPRECATED] -- doesn't do anything, jobs are external if HelixAccessToken is empty and Creator is set + Creator: '' # optional -- if the build is external, use this to specify who is sending the job + condition: succeeded() # optional -- condition for step to execute; defaults to succeeded() + continueOnError: false # optional -- determines whether to continue the build if the step errors; defaults to false + +steps: + - powershell: 'powershell "$env:BUILD_SOURCESDIRECTORY\eng\common\msbuild.ps1 $env:BUILD_SOURCESDIRECTORY\eng\common\helixpublish.proj /bl:$env:BUILD_SOURCESDIRECTORY\artifacts\log\$env:BuildConfig\SendToHelix.binlog"' + displayName: Send job to Helix (Windows) + env: + BuildConfig: $(_BuildConfig) + HelixSource: ${{ parameters.HelixSource }} + HelixType: ${{ parameters.HelixType }} + HelixBuild: ${{ parameters.HelixBuild }} + HelixTargetQueues: ${{ parameters.HelixTargetQueues }} + HelixAccessToken: ${{ parameters.HelixAccessToken }} + HelixPreCommands: ${{ parameters.HelixPreCommands }} + HelixPostCommands: ${{ parameters.HelixPostCommands }} + WorkItemDirectory: ${{ parameters.WorkItemDirectory }} + WorkItemCommand: ${{ parameters.WorkItemCommand }} + WorkItemTimeout: ${{ parameters.WorkItemTimeout }} + CorrelationPayloadDirectory: ${{ parameters.CorrelationPayloadDirectory }} + XUnitProjects: ${{ parameters.XUnitProjects }} + XUnitPublishTargetFramework: ${{ parameters.XUnitPublishTargetFramework }} + XUnitRuntimeTargetFramework: ${{ parameters.XUnitRuntimeTargetFramework }} + XUnitRunnerVersion: ${{ parameters.XUnitRunnerVersion }} + IncludeDotNetCli: ${{ parameters.IncludeDotNetCli }} + DotNetCliPackageType: ${{ parameters.DotNetCliPackageType }} + DotNetCliVersion: ${{ parameters.DotNetCliVersion }} + EnableXUnitReporter: ${{ parameters.EnableXUnitReporter }} + WaitForWorkItemCompletion: ${{ parameters.WaitForWorkItemCompletion }} + Creator: ${{ parameters.Creator }} + condition: and(${{ parameters.condition }}, eq(variables['Agent.Os'], 'Windows_NT')) + continueOnError: ${{ parameters.continueOnError }} + - script: $BUILD_SOURCESDIRECTORY/eng/common/msbuild.sh $BUILD_SOURCESDIRECTORY/eng/common/helixpublish.proj /bl:$BUILD_SOURCESDIRECTORY/artifacts/log/$BuildConfig/SendToHelix.binlog + displayName: Send job to Helix (Unix) + env: + BuildConfig: $(_BuildConfig) + HelixSource: ${{ parameters.HelixSource }} + HelixType: ${{ parameters.HelixType }} + HelixBuild: ${{ parameters.HelixBuild }} + HelixTargetQueues: ${{ parameters.HelixTargetQueues }} + HelixAccessToken: ${{ parameters.HelixAccessToken }} + HelixPreCommands: ${{ parameters.HelixPreCommands }} + HelixPostCommands: ${{ parameters.HelixPostCommands }} + WorkItemDirectory: ${{ parameters.WorkItemDirectory }} + WorkItemCommand: ${{ parameters.WorkItemCommand }} + WorkItemTimeout: ${{ parameters.WorkItemTimeout }} + CorrelationPayloadDirectory: ${{ parameters.CorrelationPayloadDirectory }} + XUnitProjects: ${{ parameters.XUnitProjects }} + XUnitPublishTargetFramework: ${{ parameters.XUnitPublishTargetFramework }} + XUnitRuntimeTargetFramework: ${{ parameters.XUnitRuntimeTargetFramework }} + XUnitRunnerVersion: ${{ parameters.XUnitRunnerVersion }} + IncludeDotNetCli: ${{ parameters.IncludeDotNetCli }} + DotNetCliPackageType: ${{ parameters.DotNetCliPackageType }} + DotNetCliVersion: ${{ parameters.DotNetCliVersion }} + EnableXUnitReporter: ${{ parameters.EnableXUnitReporter }} + WaitForWorkItemCompletion: ${{ parameters.WaitForWorkItemCompletion }} + Creator: ${{ parameters.Creator }} + condition: and(${{ parameters.condition }}, ne(variables['Agent.Os'], 'Windows_NT')) + continueOnError: ${{ parameters.continueOnError }} diff --git a/eng/common/templates/steps/telemetry-end.yml b/eng/common/templates/steps/telemetry-end.yml new file mode 100644 index 0000000000..9b61481e7e --- /dev/null +++ b/eng/common/templates/steps/telemetry-end.yml @@ -0,0 +1,63 @@ +steps: +- bash: | + if [ "$AGENT_JOBSTATUS" = "Succeeded" ] || [ "$AGENT_JOBSTATUS" = "PartiallySucceeded" ]; then + errorCount=0 + else + errorCount=1 + fi + warningCount=0 + + # create a temporary file for curl output + res=`mktemp` + + curlResult=` + curl --verbose --output $res --write-out "%{http_code}"\ + -H 'Content-Type: application/json' \ + -H "X-Helix-Job-Token: $Helix_JobToken" \ + -H 'Content-Length: 0' \ + -X POST -G "https://helix.dot.net/api/2018-03-14/telemetry/job/build/$Helix_WorkItemId/finish" \ + --data-urlencode "errorCount=$errorCount" \ + --data-urlencode "warningCount=$warningCount"` + curlStatus=$? + + if [ $curlStatus -eq 0 ]; then + if [ $curlResult -gt 299 ] || [ $curlResult -lt 200 ]; then + curlStatus=$curlResult + fi + fi + + if [ $curlStatus -ne 0 ]; then + echo "Failed to Send Build Finish information" + vstsLogOutput="vso[task.logissue type=error;sourcepath=templates/steps/telemetry-end.yml;code=1;]Failed to Send Build Finish information: $curlStatus" + echo "##$vstsLogOutput" + exit 1 + fi + displayName: Send Unix Build End Telemetry + env: + # defined via VSTS variables in start-job.sh + Helix_JobToken: $(Helix_JobToken) + Helix_WorkItemId: $(Helix_WorkItemId) + condition: and(always(), ne(variables['Agent.Os'], 'Windows_NT')) +- powershell: | + if (($env:Agent_JobStatus -eq 'Succeeded') -or ($env:Agent_JobStatus -eq 'PartiallySucceeded')) { + $ErrorCount = 0 + } else { + $ErrorCount = 1 + } + $WarningCount = 0 + + try { + Invoke-RestMethod -Uri "https://helix.dot.net/api/2018-03-14/telemetry/job/build/$env:Helix_WorkItemId/finish?errorCount=$ErrorCount&warningCount=$WarningCount" -Method Post -ContentType "application/json" -Body "" ` + -Headers @{ 'X-Helix-Job-Token'=$env:Helix_JobToken } + } + catch { + Write-Error $_ + Write-Error $_.Exception + exit 1 + } + displayName: Send Windows Build End Telemetry + env: + # defined via VSTS variables in start-job.ps1 + Helix_JobToken: $(Helix_JobToken) + Helix_WorkItemId: $(Helix_WorkItemId) + condition: and(always(),eq(variables['Agent.Os'], 'Windows_NT')) diff --git a/eng/common/templates/steps/telemetry-start.yml b/eng/common/templates/steps/telemetry-start.yml new file mode 100644 index 0000000000..79c128c5de --- /dev/null +++ b/eng/common/templates/steps/telemetry-start.yml @@ -0,0 +1,154 @@ +parameters: + helixSource: 'undefined_defaulted_in_telemetry.yml' + helixType: 'undefined_defaulted_in_telemetry.yml' + buildConfig: '' + runAsPublic: false + +steps: +- ${{ if and(eq(parameters.runAsPublic, 'false'), not(eq(variables['System.TeamProject'], 'public'))) }}: + - task: AzureKeyVault@1 + inputs: + azureSubscription: 'HelixProd_KeyVault' + KeyVaultName: HelixProdKV + SecretsFilter: 'HelixApiAccessToken' + condition: always() +- bash: | + # create a temporary file + jobInfo=`mktemp` + + # write job info content to temporary file + cat > $jobInfo <' | Set-Content $proj + MSBuild $proj $bl /t:__WriteToolsetLocation /noconsolelogger /p:__ToolsetLocationOutputFile=$toolsetLocationFile + + $path = Get-Content $toolsetLocationFile -TotalCount 1 + if (!(Test-Path $path)) { + throw "Invalid toolset path: $path" + } + + return $global:_ToolsetBuildProj = $path +} + +function ExitWithExitCode([int] $exitCode) { + if ($ci -and $prepareMachine) { + Stop-Processes + } + exit $exitCode +} + +function Stop-Processes() { + Write-Host "Killing running build processes..." + foreach ($processName in $processesToStopOnExit) { + Get-Process -Name $processName -ErrorAction SilentlyContinue | Stop-Process + } +} + +# +# Executes msbuild (or 'dotnet msbuild') with arguments passed to the function. +# The arguments are automatically quoted. +# Terminates the script if the build fails. +# +function MSBuild() { + if ($ci) { + if (!$binaryLog) { + throw "Binary log must be enabled in CI build." + } + + if ($nodeReuse) { + throw "Node reuse must be disabled in CI build." + } + } + + $buildTool = InitializeBuildTool + + $cmdArgs = "$($buildTool.Command) /m /nologo /clp:Summary /v:$verbosity /nr:$nodeReuse" + + if ($warnAsError) { + $cmdArgs += " /warnaserror /p:TreatWarningsAsErrors=true" + } + + foreach ($arg in $args) { + if ($arg -ne $null -and $arg.Trim() -ne "") { + $cmdArgs += " `"$arg`"" + } + } + + $exitCode = Exec-Process $buildTool.Path $cmdArgs + + if ($exitCode -ne 0) { + Write-Host "Build failed." -ForegroundColor Red + + $buildLog = GetMSBuildBinaryLogCommandLineArgument $args + if ($buildLog -ne $null) { + Write-Host "See log: $buildLog" -ForegroundColor DarkGray + } + + ExitWithExitCode $exitCode + } +} + +function GetMSBuildBinaryLogCommandLineArgument($arguments) { + foreach ($argument in $arguments) { + if ($argument -ne $null) { + $arg = $argument.Trim() + if ($arg.StartsWith("/bl:", "OrdinalIgnoreCase")) { + return $arg.Substring("/bl:".Length) + } + + if ($arg.StartsWith("/binaryLogger:", "OrdinalIgnoreCase")) { + return $arg.Substring("/binaryLogger:".Length) + } + } + } + + return $null +} + +$RepoRoot = Resolve-Path (Join-Path $PSScriptRoot "..\..") +$EngRoot = Resolve-Path (Join-Path $PSScriptRoot "..") +$ArtifactsDir = Join-Path $RepoRoot "artifacts" +$ToolsetDir = Join-Path $ArtifactsDir "toolset" +$ToolsDir = Join-Path $RepoRoot ".tools" +$LogDir = Join-Path (Join-Path $ArtifactsDir "log") $configuration +$TempDir = Join-Path (Join-Path $ArtifactsDir "tmp") $configuration +$GlobalJson = Get-Content -Raw -Path (Join-Path $RepoRoot "global.json") | ConvertFrom-Json + +Create-Directory $ToolsetDir +Create-Directory $TempDir +Create-Directory $LogDir + +if ($ci) { + $env:TEMP = $TempDir + $env:TMP = $TempDir +} diff --git a/eng/common/tools.sh b/eng/common/tools.sh new file mode 100755 index 0000000000..8a253bef51 --- /dev/null +++ b/eng/common/tools.sh @@ -0,0 +1,319 @@ +# Initialize variables if they aren't already defined. + +# CI mode - set to true on CI server for PR validation build or official build. +ci=${ci:-false} + +# Build configuration. Common values include 'Debug' and 'Release', but the repository may use other names. +configuration=${configuration:-'Debug'} + +# Set to true to output binary log from msbuild. Note that emitting binary log slows down the build. +# Binary log must be enabled on CI. +binary_log=${binary_log:-$ci} + +# Turns on machine preparation/clean up code that changes the machine state (e.g. kills build processes). +prepare_machine=${prepare_machine:-false} + +# True to restore toolsets and dependencies. +restore=${restore:-true} + +# Adjusts msbuild verbosity level. +verbosity=${verbosity:-'minimal'} + +# Set to true to reuse msbuild nodes. Recommended to not reuse on CI. +if [[ "$ci" == true ]]; then + node_reuse=${node_reuse:-false} +else + node_reuse=${node_reuse:-true} +fi + +# Configures warning treatment in msbuild. +warn_as_error=${warn_as_error:-true} + +# True to attempt using .NET Core already that meets requirements specified in global.json +# installed on the machine instead of downloading one. +use_installed_dotnet_cli=${use_installed_dotnet_cli:-true} + +# True to use global NuGet cache instead of restoring packages to repository-local directory. +if [[ "$ci" == true ]]; then + use_global_nuget_cache=${use_global_nuget_cache:-false} +else + use_global_nuget_cache=${use_global_nuget_cache:-true} +fi + +# Resolve any symlinks in the given path. +function ResolvePath { + local path=$1 + + while [[ -h $path ]]; do + local dir="$( cd -P "$( dirname "$path" )" && pwd )" + path="$(readlink "$path")" + + # if $path was a relative symlink, we need to resolve it relative to the path where the + # symlink file was located + [[ $path != /* ]] && path="$dir/$path" + done + + # return value + _ResolvePath="$path" +} + +# ReadVersionFromJson [json key] +function ReadGlobalVersion { + local key=$1 + + local line=`grep -m 1 "$key" "$global_json_file"` + local pattern="\"$key\" *: *\"(.*)\"" + + if [[ ! $line =~ $pattern ]]; then + echo "Error: Cannot find \"$key\" in $global_json_file" >&2 + ExitWithExitCode 1 + fi + + # return value + _ReadGlobalVersion=${BASH_REMATCH[1]} +} + +function InitializeDotNetCli { + if [[ -n "${_InitializeDotNetCli:-}" ]]; then + return + fi + + local install=$1 + + # Don't resolve runtime, shared framework, or SDK from other locations to ensure build determinism + export DOTNET_MULTILEVEL_LOOKUP=0 + + # Disable first run since we want to control all package sources + export DOTNET_SKIP_FIRST_TIME_EXPERIENCE=1 + + # Disable telemetry on CI + if [[ $ci == true ]]; then + export DOTNET_CLI_TELEMETRY_OPTOUT=1 + fi + + # LTTNG is the logging infrastructure used by Core CLR. Need this variable set + # so it doesn't output warnings to the console. + export LTTNG_HOME="$HOME" + + # Source Build uses DotNetCoreSdkDir variable + if [[ -n "${DotNetCoreSdkDir:-}" ]]; then + export DOTNET_INSTALL_DIR="$DotNetCoreSdkDir" + fi + + # Find the first path on $PATH that contains the dotnet.exe + if [[ "$use_installed_dotnet_cli" == true && -z "${DOTNET_INSTALL_DIR:-}" ]]; then + local dotnet_path=`command -v dotnet` + if [[ -n "$dotnet_path" ]]; then + ResolvePath "$dotnet_path" + export DOTNET_INSTALL_DIR=`dirname "$_ResolvePath"` + fi + fi + + ReadGlobalVersion "dotnet" + local dotnet_sdk_version=$_ReadGlobalVersion + local dotnet_root="" + + # Use dotnet installation specified in DOTNET_INSTALL_DIR if it contains the required SDK version, + # otherwise install the dotnet CLI and SDK to repo local .dotnet directory to avoid potential permission issues. + if [[ -n "${DOTNET_INSTALL_DIR:-}" && -d "$DOTNET_INSTALL_DIR/sdk/$dotnet_sdk_version" ]]; then + dotnet_root="$DOTNET_INSTALL_DIR" + else + dotnet_root="$repo_root/.dotnet" + export DOTNET_INSTALL_DIR="$dotnet_root" + + if [[ ! -d "$DOTNET_INSTALL_DIR/sdk/$dotnet_sdk_version" ]]; then + if [[ "$install" == true ]]; then + InstallDotNetSdk "$dotnet_root" "$dotnet_sdk_version" + else + echo "Unable to find dotnet with SDK version '$dotnet_sdk_version'" >&2 + ExitWithExitCode 1 + fi + fi + fi + + # Add dotnet to PATH. This prevents any bare invocation of dotnet in custom + # build steps from using anything other than what we've downloaded. + export PATH="$dotnet_root:$PATH" + + if [[ $ci == true ]]; then + # Make Sure that our bootstrapped dotnet cli is avaliable in future steps of the Azure Pipelines build + echo "##vso[task.prependpath]$dotnet_root" + echo "##vso[task.setvariable variable=DOTNET_MULTILEVEL_LOOKUP]0" + echo "##vso[task.setvariable variable=DOTNET_SKIP_FIRST_TIME_EXPERIENCE]1" + fi + + # return value + _InitializeDotNetCli="$dotnet_root" +} + +function InstallDotNetSdk { + local root=$1 + local version=$2 + + GetDotNetInstallScript "$root" + local install_script=$_GetDotNetInstallScript + + bash "$install_script" --version $version --install-dir "$root" || { + local exit_code=$? + echo "Failed to install dotnet SDK (exit code '$exit_code')." >&2 + ExitWithExitCode $exit_code + } +} + +function GetDotNetInstallScript { + local root=$1 + local install_script="$root/dotnet-install.sh" + local install_script_url="https://dot.net/v1/dotnet-install.sh" + + if [[ ! -a "$install_script" ]]; then + mkdir -p "$root" + + echo "Downloading '$install_script_url'" + + # Use curl if available, otherwise use wget + if command -v curl > /dev/null; then + curl "$install_script_url" -sSL --retry 10 --create-dirs -o "$install_script" + else + wget -q -O "$install_script" "$install_script_url" + fi + fi + + # return value + _GetDotNetInstallScript="$install_script" +} + +function InitializeBuildTool { + if [[ -n "${_InitializeBuildTool:-}" ]]; then + return + fi + + InitializeDotNetCli $restore + + # return values + _InitializeBuildTool="$_InitializeDotNetCli/dotnet" + _InitializeBuildToolCommand="msbuild" +} + +function GetNuGetPackageCachePath { + if [[ -z ${NUGET_PACKAGES:-} ]]; then + if [[ "$use_global_nuget_cache" == true ]]; then + export NUGET_PACKAGES="$HOME/.nuget/packages" + else + export NUGET_PACKAGES="$repo_root/.packages" + fi + fi + + # return value + _GetNuGetPackageCachePath=$NUGET_PACKAGES +} + +function InitializeToolset { + if [[ -n "${_InitializeToolset:-}" ]]; then + return + fi + + GetNuGetPackageCachePath + + ReadGlobalVersion "Microsoft.DotNet.Arcade.Sdk" + + local toolset_version=$_ReadGlobalVersion + local toolset_location_file="$toolset_dir/$toolset_version.txt" + + if [[ -a "$toolset_location_file" ]]; then + local path=`cat "$toolset_location_file"` + if [[ -a "$path" ]]; then + # return value + _InitializeToolset="$path" + return + fi + fi + + if [[ "$restore" != true ]]; then + echo "Toolset version $toolsetVersion has not been restored." >&2 + ExitWithExitCode 2 + fi + + local toolset_restore_log="$log_dir/ToolsetRestore.binlog" + local proj="$toolset_dir/restore.proj" + + echo '' > "$proj" + MSBuild "$proj" /t:__WriteToolsetLocation /noconsolelogger /bl:"$toolset_restore_log" /p:__ToolsetLocationOutputFile="$toolset_location_file" + + local toolset_build_proj=`cat "$toolset_location_file"` + + if [[ ! -a "$toolset_build_proj" ]]; then + echo "Invalid toolset path: $toolset_build_proj" >&2 + ExitWithExitCode 3 + fi + + # return value + _InitializeToolset="$toolset_build_proj" +} + +function ExitWithExitCode { + if [[ "$ci" == true && "$prepare_machine" == true ]]; then + StopProcesses + fi + exit $1 +} + +function StopProcesses { + echo "Killing running build processes..." + pkill -9 "dotnet" || true + pkill -9 "vbcscompiler" || true + return 0 +} + +function MSBuild { + if [[ "$ci" == true ]]; then + if [[ "$binary_log" != true ]]; then + echo "Binary log must be enabled in CI build." >&2 + ExitWithExitCode 1 + fi + + if [[ "$node_reuse" == true ]]; then + echo "Node reuse must be disabled in CI build." >&2 + ExitWithExitCode 1 + fi + fi + + InitializeBuildTool + + local warnaserror_switch="" + if [[ $warn_as_error == true ]]; then + warnaserror_switch="/warnaserror" + fi + + "$_InitializeBuildTool" "$_InitializeBuildToolCommand" /m /nologo /clp:Summary /v:$verbosity /nr:$node_reuse $warnaserror_switch /p:TreatWarningsAsErrors=$warn_as_error "$@" || { + local exit_code=$? + echo "Build failed (exit code '$exit_code')." >&2 + ExitWithExitCode $exit_code + } +} + +ResolvePath "${BASH_SOURCE[0]}" +_script_dir=`dirname "$_ResolvePath"` + +eng_root=`cd -P "$_script_dir/.." && pwd` +repo_root=`cd -P "$_script_dir/../.." && pwd` +artifacts_dir="$repo_root/artifacts" +toolset_dir="$artifacts_dir/toolset" +log_dir="$artifacts_dir/log/$configuration" +temp_dir="$artifacts_dir/tmp/$configuration" + +global_json_file="$repo_root/global.json" + +# HOME may not be defined in some scenarios, but it is required by NuGet +if [[ -z $HOME ]]; then + export HOME="$repo_root/artifacts/.home/" + mkdir -p "$HOME" +fi + +mkdir -p "$toolset_dir" +mkdir -p "$temp_dir" +mkdir -p "$log_dir" + +if [[ $ci == true ]]; then + export TEMP="$temp_dir" + export TMP="$temp_dir" +fi diff --git a/fcs/.paket/Paket.Restore.targets b/fcs/.paket/Paket.Restore.targets index e7c1bc0c83..52f41c608a 100644 --- a/fcs/.paket/Paket.Restore.targets +++ b/fcs/.paket/Paket.Restore.targets @@ -11,23 +11,49 @@ $(MSBuildThisFileDirectory)..\ $(PaketRootPath)paket-files\paket.restore.cached $(PaketRootPath)paket.lock + classic + proj + assembly + native /Library/Frameworks/Mono.framework/Commands/mono mono - - $(PaketRootPath)paket.exe - $(PaketToolsPath)paket.exe - "$(PaketExePath)" - $(MonoPath) --runtime=v4.0.30319 "$(PaketExePath)" - + + $(PaketRootPath)paket.bootstrapper.exe + $(PaketToolsPath)paket.bootstrapper.exe + $([System.IO.Path]::GetDirectoryName("$(PaketBootStrapperExePath)"))\ + + + + + $(PaketRootPath)paket.exe + $(PaketToolsPath)paket.exe + $(PaketToolsPath)paket.exe + $(_PaketBootStrapperExeDir)paket.exe + paket.exe + + + $(PaketRootPath)paket + $(PaketToolsPath)paket + $(PaketToolsPath)paket + + + $(PaketRootPath)paket.exe + $(PaketToolsPath)paket.exe + + + $(PaketBootStrapperExeDir)paket.exe + + + paket + + <_PaketExeExtension>$([System.IO.Path]::GetExtension("$(PaketExePath)")) - dotnet "$(PaketExePath)" + dotnet "$(PaketExePath)" + $(MonoPath) --runtime=v4.0.30319 "$(PaketExePath)" + "$(PaketExePath)" - - "$(PaketExePath)" - $(PaketRootPath)paket.bootstrapper.exe - $(PaketToolsPath)paket.bootstrapper.exe "$(PaketBootStrapperExePath)" $(MonoPath) --runtime=v4.0.30319 "$(PaketBootStrapperExePath)" @@ -36,30 +62,40 @@ true true + + + True - + + + + + true - $(NoWarn);NU1603 + $(NoWarn);NU1603;NU1604;NU1605;NU1608 - /usr/bin/shasum $(PaketRestoreCacheFile) | /usr/bin/awk '{ print $1 }' - /usr/bin/shasum $(PaketLockFilePath) | /usr/bin/awk '{ print $1 }' + /usr/bin/shasum "$(PaketRestoreCacheFile)" | /usr/bin/awk '{ print $1 }' + /usr/bin/shasum "$(PaketLockFilePath)" | /usr/bin/awk '{ print $1 }' - + - + + + + $([System.IO.File]::ReadAllText('$(PaketRestoreCacheFile)')) @@ -69,11 +105,26 @@ true + + + true + + - + + + + + + + + $(MSBuildProjectDirectory)\obj\$(MSBuildProjectFile).paket.references.cached @@ -82,7 +133,9 @@ $(MSBuildProjectDirectory)\$(MSBuildProjectName).paket.references $(MSBuildProjectDirectory)\paket.references - $(MSBuildProjectDirectory)\obj\$(MSBuildProjectFile).$(TargetFramework).paket.resolved + + false + true true references-file-or-cache-not-found @@ -101,32 +154,43 @@ - + true - target-framework '$(TargetFramework)' + target-framework '$(TargetFramework)' or '$(TargetFrameworks)' files @(PaketResolvedFilePaths) - + + - + + false + true + + - + - + + $([System.String]::Copy('%(PaketReferencesFileLines.Identity)').Split(',').Length) $([System.String]::Copy('%(PaketReferencesFileLines.Identity)').Split(',')[0]) $([System.String]::Copy('%(PaketReferencesFileLines.Identity)').Split(',')[1]) $([System.String]::Copy('%(PaketReferencesFileLines.Identity)').Split(',')[4]) + $([System.String]::Copy('%(PaketReferencesFileLines.Identity)').Split(',')[5]) %(PaketReferencesFileLinesInfo.PackageVersion) - All + All + runtime + runtime + true + true @@ -158,19 +222,27 @@ false + $(MSBuildVersion) + 15.8.0 <_NuspecFilesNewLocation Include="$(BaseIntermediateOutputPath)$(Configuration)\*.nuspec"/> + + $(MSBuildProjectDirectory)/$(MSBuildProjectFile) true - false - true + false + true + false + true + false + true $(BaseIntermediateOutputPath)$(Configuration) $(BaseIntermediateOutputPath) @@ -183,11 +255,54 @@ - - + - + + - + + $(UserProfile)\.nuget\packages\ + $(HOME)/.nuget/packages/ + $(NuGetPackageRoot)\ + $(NuGetPackageRoot)/ + $(MSBuildThisFileDirectory)..\artifacts + $(ArtifactsDir)\bin + $(ArtifactsDir)\obj + $(ArtifactsBinDir)\fcs + $(ArtifactsObjDir)\fcs + + + + + $(ArtifactsBinDir)\FSharp.Build\Proto\net46 + + + + $(ProtoOutputPath)\Microsoft.FSharp.Targets + $(ProtoOutputPath)\Microsoft.FSharp.NetSdk.props + $(ProtoOutputPath)\Microsoft.FSharp.NetSdk.targets + $(ProtoOutputPath)\Microsoft.FSharp.Overrides.NetSdk.targets + + diff --git a/fcs/Directory.Build.targets b/fcs/Directory.Build.targets new file mode 100644 index 0000000000..bb5b23d29d --- /dev/null +++ b/fcs/Directory.Build.targets @@ -0,0 +1,3 @@ + + + diff --git a/fcs/FSharp.Compiler.Service.MSBuild.v12/FSharp.Compiler.Service.MSBuild.v12.fsproj b/fcs/FSharp.Compiler.Service.MSBuild.v12/FSharp.Compiler.Service.MSBuild.v12.fsproj index deb3f51b69..9d3e20e80c 100644 --- a/fcs/FSharp.Compiler.Service.MSBuild.v12/FSharp.Compiler.Service.MSBuild.v12.fsproj +++ b/fcs/FSharp.Compiler.Service.MSBuild.v12/FSharp.Compiler.Service.MSBuild.v12.fsproj @@ -7,7 +7,6 @@ net45 true - ..\..\$(Configuration.ToLower())\fcs $(DefineConstants);CROSS_PLATFORM_COMPILER $(DefineConstants);ENABLE_MONO_SUPPORT @@ -29,7 +28,7 @@ - + $(FSharpSourcesRoot)\..\fcs\dependencies\MSBuild.v12.0\Microsoft.Build.Framework.dll @@ -51,18 +50,8 @@ $(FSharpSourcesRoot)\..\fcs\dependencies\MSBuild.v12.0\Microsoft.Build.Tasks.v12.0.dll false - - - $(FSharpSourcesRoot)\..\packages\Microsoft.Portable.FSharp.Core.$(FSharpCoreFrozenPortablePackageVersion)\lib\profiles\net40\FSharp.Core.dll - false - - - FSharp.Compiler.Service - {2e4d67b4-522d-4cf7-97e4-ba940f0b18f3} - True - \ No newline at end of file diff --git a/fcs/FSharp.Compiler.Service.ProjectCracker/FSharp.Compiler.Service.ProjectCracker.fsproj b/fcs/FSharp.Compiler.Service.ProjectCracker/FSharp.Compiler.Service.ProjectCracker.fsproj index ff23a6589c..5b8efa504d 100644 --- a/fcs/FSharp.Compiler.Service.ProjectCracker/FSharp.Compiler.Service.ProjectCracker.fsproj +++ b/fcs/FSharp.Compiler.Service.ProjectCracker/FSharp.Compiler.Service.ProjectCracker.fsproj @@ -1,13 +1,9 @@  - - $(MSBuildProjectDirectory)\..\..\src - net45 true - ..\..\$(Configuration.ToLower())\fcs Legacy project file cracker for the F# compiler service. @@ -25,13 +21,13 @@ - - + + - + \ No newline at end of file diff --git a/fcs/FSharp.Compiler.Service.ProjectCrackerTool/FSharp.Compiler.Service.ProjectCrackerTool.fsproj b/fcs/FSharp.Compiler.Service.ProjectCrackerTool/FSharp.Compiler.Service.ProjectCrackerTool.fsproj index f6ff4d1bea..2e5ae3075f 100644 --- a/fcs/FSharp.Compiler.Service.ProjectCrackerTool/FSharp.Compiler.Service.ProjectCrackerTool.fsproj +++ b/fcs/FSharp.Compiler.Service.ProjectCrackerTool/FSharp.Compiler.Service.ProjectCrackerTool.fsproj @@ -14,7 +14,6 @@ $(OtherFlags) --staticlink:FSharp.Core true false - ..\..\$(Configuration.ToLower())\fcs @@ -25,11 +24,7 @@ - - $(FSharpSourcesRoot)\..\packages\Microsoft.Portable.FSharp.Core.$(FSharpCoreFrozenPortablePackageVersion)\lib\profiles\net40\FSharp.Core.dll - false - - + $(FSharpSourcesRoot)\..\fcs\dependencies\MSBuild.v12.0\Microsoft.Build.Framework.dll false diff --git a/fcs/FSharp.Compiler.Service.Tests/App.config b/fcs/FSharp.Compiler.Service.Tests/App.config index ddb73d1dd9..380c93a453 100644 --- a/fcs/FSharp.Compiler.Service.Tests/App.config +++ b/fcs/FSharp.Compiler.Service.Tests/App.config @@ -3,6 +3,10 @@ + + + + diff --git a/fcs/FSharp.Compiler.Service.Tests/CSharp_Analysis/CSharp_Analysis.csproj b/fcs/FSharp.Compiler.Service.Tests/CSharp_Analysis/CSharp_Analysis.csproj index 49585864e4..fc00709da4 100644 --- a/fcs/FSharp.Compiler.Service.Tests/CSharp_Analysis/CSharp_Analysis.csproj +++ b/fcs/FSharp.Compiler.Service.Tests/CSharp_Analysis/CSharp_Analysis.csproj @@ -3,6 +3,7 @@ net45;netstandard2.0 false + $(NoWarn);0067;1591 diff --git a/fcs/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.Tests.fsproj b/fcs/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.Tests.fsproj index 7ea85c202a..010e69b95a 100644 --- a/fcs/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.Tests.fsproj +++ b/fcs/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.Tests.fsproj @@ -69,17 +69,23 @@ TokenizerTests.fs + + ServiceUntypedParseTests.fs + + + TreeVisitorTests.fs + Program.fs - + - + diff --git a/fcs/FSharp.Compiler.Service/FSharp.Compiler.Service.fsproj b/fcs/FSharp.Compiler.Service/FSharp.Compiler.Service.fsproj index a642413653..bfd4295003 100644 --- a/fcs/FSharp.Compiler.Service/FSharp.Compiler.Service.fsproj +++ b/fcs/FSharp.Compiler.Service/FSharp.Compiler.Service.fsproj @@ -1,23 +1,23 @@ - + $(MSBuildProjectDirectory)\..\..\src - + + net45;netstandard2.0 true $(DefineConstants);COMPILER_SERVICE_AS_DLL $(DefineConstants);COMPILER $(DefineConstants);ENABLE_MONO_SUPPORT $(DefineConstants);NO_STRONG_NAMES - ..\..\$(Configuration.ToLower())\fcs $(TargetFramework)\ $(TargetFramework)\ $(OtherFlags) /warnon:1182 $(OtherFlags) --times - $(NoWarn);44;62;69;65;54;61;75;62;9;2003; - true + $(NoWarn);44;62;69;65;54;61;75;62;9;2003;NU5125 + true true true @@ -46,12 +46,12 @@ AssemblyInfo/AssemblyInfo.fs - + FSComp.txt - - + + FSIstrings.txt - + FSStrings.resx FSStrings.resources @@ -635,11 +635,12 @@ - + + @@ -655,7 +656,5 @@ $(FSharpSourcesRoot)\..\packages\System.ValueTuple.4.4.0\lib\netstandard1.0\System.ValueTuple.dll - - - + \ No newline at end of file diff --git a/fcs/build.cmd b/fcs/build.cmd index 0289b3c480..16bbb2924b 100644 --- a/fcs/build.cmd +++ b/fcs/build.cmd @@ -18,6 +18,9 @@ if errorlevel 1 ( exit /b %errorlevel% ) +:: don't care if this fails +dotnet build-server shutdown >NUL 2>&1 + packages\FAKE\tools\FAKE.exe build.fsx %* if errorlevel 1 ( endlocal diff --git a/fcs/build.fsx b/fcs/build.fsx index a11ed814af..5690fb73b0 100644 --- a/fcs/build.fsx +++ b/fcs/build.fsx @@ -13,15 +13,15 @@ open Fake.ReleaseNotesHelper #if MONO // prevent incorrect output encoding (e.g. https://github.com/fsharp/FAKE/issues/1196) System.Console.OutputEncoding <- System.Text.Encoding.UTF8 -CleanDir (__SOURCE_DIRECTORY__ + "/../tests/TestResults") -File.WriteAllText(__SOURCE_DIRECTORY__ + "/../tests/TestResults/notestsyet.txt","No tests yet") +CleanDir (__SOURCE_DIRECTORY__ + "/../artifacts/TestResults") +File.WriteAllText(__SOURCE_DIRECTORY__ + "/../artifacts/TestResults/notestsyet.txt","No tests yet") let isMono = true #else let isMono = false #endif -let dotnetExePath = DotNetCli.InstallDotNetSDK "2.1.201" +let dotnetExePath = DotNetCli.InstallDotNetSDK "2.1.403" let runDotnet workingDir args = let result = @@ -51,13 +51,13 @@ let runCmdIn workDir (exe:string) = Printf.ksprintf (fun (args:string) -> // The rest of the code is standard F# build script // -------------------------------------------------------------------------------------- -let releaseDir = Path.Combine(__SOURCE_DIRECTORY__, "../release/fcs") +let releaseDir = Path.Combine(__SOURCE_DIRECTORY__, "../artifacts/bin/fcs") // Read release notes & version info from RELEASE_NOTES.md let release = LoadReleaseNotes (__SOURCE_DIRECTORY__ + "/RELEASE_NOTES.md") let isAppVeyorBuild = buildServer = BuildServer.AppVeyor let isJenkinsBuild = buildServer = BuildServer.Jenkins -let isVersionTag tag = Version.TryParse tag |> fst +let isVersionTag (tag: string) = Version.TryParse tag |> fst let hasRepoVersionTag = isAppVeyorBuild && AppVeyorEnvironment.RepoTag && isVersionTag AppVeyorEnvironment.RepoTagName let assemblyVersion = if hasRepoVersionTag then AppVeyorEnvironment.RepoTagName else release.NugetVersion @@ -72,15 +72,8 @@ Target "Clean" (fun _ -> Target "Restore" (fun _ -> // We assume a paket restore has already been run + runDotnet __SOURCE_DIRECTORY__ "restore ../src/buildtools/buildtools.proj -v n" runDotnet __SOURCE_DIRECTORY__ "restore FSharp.Compiler.Service.sln -v n" - for p in [ "../packages.config" ] do - let rec executeProcess count = - let result = ExecProcess (fun info -> - info.FileName <- FullName @"./../.nuget/NuGet.exe" - info.WorkingDirectory <- FullName @"./.." - info.Arguments <- sprintf "restore %s -PackagesDirectory \"%s\" -ConfigFile \"%s\"" (FullName p) (FullName "./../packages") (FullName "./../NuGet.Config")) TimeSpan.MaxValue - if result <> 0 && count > 1 then executeProcess (count - 1) else result - (executeProcess 5) |> assertExitCodeZero ) Target "BuildVersion" (fun _ -> @@ -88,7 +81,8 @@ Target "BuildVersion" (fun _ -> ) Target "Build" (fun _ -> - runDotnet __SOURCE_DIRECTORY__ "build FSharp.Compiler.Service.sln -v n -c Release" + runDotnet __SOURCE_DIRECTORY__ "build ../src/buildtools/buildtools.proj -v n -c Proto" + runDotnet __SOURCE_DIRECTORY__ "build FSharp.Compiler.Service.sln -v n -c release" ) Target "Test" (fun _ -> @@ -97,11 +91,11 @@ Target "Test" (fun _ -> runDotnet __SOURCE_DIRECTORY__ "build ../tests/projects/Sample_NETCoreSDK_FSharp_Library_netstandard2_0/Sample_NETCoreSDK_FSharp_Library_netstandard2_0.fsproj -v n" // Now run the tests - runDotnet __SOURCE_DIRECTORY__ "test FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.Tests.fsproj -v n -c Release" + runDotnet __SOURCE_DIRECTORY__ "test FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.Tests.fsproj --no-restore --no-build -v n -c release" ) Target "NuGet" (fun _ -> - runDotnet __SOURCE_DIRECTORY__ "pack FSharp.Compiler.Service.sln -v n -c Release" + runDotnet __SOURCE_DIRECTORY__ "pack FSharp.Compiler.Service.sln -v n -c release" ) Target "GenerateDocsEn" (fun _ -> diff --git a/fcs/docsrc/content/ja/symbols.fsx b/fcs/docsrc/content/ja/symbols.fsx index 2e3f53bdba..d6abee1233 100644 --- a/fcs/docsrc/content/ja/symbols.fsx +++ b/fcs/docsrc/content/ja/symbols.fsx @@ -175,8 +175,8 @@ argTy1c.TypeDefinition.CompiledName // "Int32" *) let projectContext = checkFileResults.ProjectContext -for ass in projectContext.GetReferencedAssemblies() do - match ass.FileName with +for assembly in projectContext.GetReferencedAssemblies() do + match assembly.FileName with | None -> printfn "コンパイル時にファイルの存在しないアセンブリを参照しました" | Some s -> printfn "コンパイル時にアセンブリ '%s' を参照しました" s diff --git a/fcs/docsrc/content/ja/tokenizer.fsx b/fcs/docsrc/content/ja/tokenizer.fsx index 589061e0b0..cf5117bfbd 100644 --- a/fcs/docsrc/content/ja/tokenizer.fsx +++ b/fcs/docsrc/content/ja/tokenizer.fsx @@ -73,7 +73,7 @@ let rec tokenizeLine (tokenizer:FSharpLineTokenizer) state = 必要となるような新しい状態を返します。 初期値としては `0L` を指定します: *) -tokenizeLine tokenizer 0L +tokenizeLine tokenizer FSharpTokenizerLexState.Initial (** この結果は LET WHITESPACE IDENT EQUALS INT32 という トークン名のシーケンスになります。 diff --git a/fcs/docsrc/content/symbols.fsx b/fcs/docsrc/content/symbols.fsx index fb6275fd37..ac38053a1b 100644 --- a/fcs/docsrc/content/symbols.fsx +++ b/fcs/docsrc/content/symbols.fsx @@ -168,8 +168,8 @@ used in the compilation, called the `ProjectContext`: *) let projectContext = checkFileResults.ProjectContext -for ass in projectContext.GetReferencedAssemblies() do - match ass.FileName with +for assembly in projectContext.GetReferencedAssemblies() do + match assembly.FileName with | None -> printfn "compilation referenced an assembly without a file" | Some s -> printfn "compilation references assembly '%s'" s diff --git a/fcs/docsrc/content/tokenizer.fsx b/fcs/docsrc/content/tokenizer.fsx index 09d842ba8a..9ac3d6f34d 100644 --- a/fcs/docsrc/content/tokenizer.fsx +++ b/fcs/docsrc/content/tokenizer.fsx @@ -65,7 +65,7 @@ let rec tokenizeLine (tokenizer:FSharpLineTokenizer) state = The function returns the new state, which is needed if you need to tokenize multiple lines and an earlier line ends with a multi-line comment. As an initial state, we can use `0L`: *) -tokenizeLine tokenizer 0L +tokenizeLine tokenizer FSharpTokenizerLexState.Initial (** The result is a sequence of tokens with names LET, WHITESPACE, IDENT, EQUALS and INT32. There is a number of interesting properties on `FSharpTokenInfo` including: diff --git a/fcs/fcs.props b/fcs/fcs.props index b698937373..3f6246ff7d 100644 --- a/fcs/fcs.props +++ b/fcs/fcs.props @@ -8,7 +8,7 @@ false - $(FSharpSourcesRoot)\..\packages\FSharp.Compiler.Tools.4.1.27\tools - fsi.exe + $(FSharpSourcesRoot)\..\packages\FSharp.Compiler.Tools.4.1.27\tools + fsi.exe \ No newline at end of file diff --git a/fcs/samples/EditorService/EditorService.fsproj b/fcs/samples/EditorService/EditorService.fsproj index 05847e67f9..447906070f 100644 --- a/fcs/samples/EditorService/EditorService.fsproj +++ b/fcs/samples/EditorService/EditorService.fsproj @@ -12,7 +12,7 @@ - + diff --git a/fcs/samples/FscExe/FscExe.fsproj b/fcs/samples/FscExe/FscExe.fsproj index c482656827..b2b146913a 100644 --- a/fcs/samples/FscExe/FscExe.fsproj +++ b/fcs/samples/FscExe/FscExe.fsproj @@ -14,7 +14,7 @@ - + diff --git a/fcs/samples/FsiExe/FsiExe.fsproj b/fcs/samples/FsiExe/FsiExe.fsproj index 7377f2c291..aae2ba0318 100644 --- a/fcs/samples/FsiExe/FsiExe.fsproj +++ b/fcs/samples/FsiExe/FsiExe.fsproj @@ -16,7 +16,7 @@ - + diff --git a/fcs/samples/InteractiveService/InteractiveService.fsproj b/fcs/samples/InteractiveService/InteractiveService.fsproj index 7aa4249726..387439fcfd 100644 --- a/fcs/samples/InteractiveService/InteractiveService.fsproj +++ b/fcs/samples/InteractiveService/InteractiveService.fsproj @@ -12,7 +12,7 @@ - + diff --git a/fcs/samples/Tokenizer/Program.fs b/fcs/samples/Tokenizer/Program.fs index 402fcc3029..9cc79e699f 100644 --- a/fcs/samples/Tokenizer/Program.fs +++ b/fcs/samples/Tokenizer/Program.fs @@ -3,7 +3,7 @@ let sourceTok = FSharpSourceTokenizer([], Some "C:\\test.fsx") let tokenizeLines (lines:string[]) = - [ let state = ref 0L + [ let state = ref FSharpTokenizerLexState.Initial for n, line in lines |> Seq.zip [ 0 .. lines.Length ] do let tokenizer = sourceTok.CreateLineTokenizer(line) let rec parseLine() = seq { diff --git a/fcs/samples/Tokenizer/Tokenizer.fsproj b/fcs/samples/Tokenizer/Tokenizer.fsproj index 7aa4249726..387439fcfd 100644 --- a/fcs/samples/Tokenizer/Tokenizer.fsproj +++ b/fcs/samples/Tokenizer/Tokenizer.fsproj @@ -12,7 +12,7 @@ - + diff --git a/fcs/samples/UntypedTree/UntypedTree.fsproj b/fcs/samples/UntypedTree/UntypedTree.fsproj index 7aa4249726..387439fcfd 100644 --- a/fcs/samples/UntypedTree/UntypedTree.fsproj +++ b/fcs/samples/UntypedTree/UntypedTree.fsproj @@ -12,7 +12,7 @@ - + diff --git a/fsharp.proj b/fsharp.proj new file mode 100644 index 0000000000..92b37d547e --- /dev/null +++ b/fsharp.proj @@ -0,0 +1,170 @@ + + + + Debug + AssemblySearchPaths={HintPathFromItem};{TargetFrameworkDirectory};{RawFileName} + + + + + true + false + false + false + false + + false + false + false + false + false + + + + + true + true + true + true + true + true + + true + true + true + true + true + true + true + + + + + true + true + + + + + + + + TargetFramework=netstandard1.6 + TargetFramework=net45 + + + TargetFramework=netstandard2.0 + TargetFramework=net46 + + + TargetFramework=netstandard1.6 + TargetFramework=net46 + + + TargetFramework=net46 + + + TargetFramework=netstandard1.6 + TargetFramework=net46 + + + TargetFramework=netcoreapp2.1 + TargetFramework=net46 + + + TargetFramework=netcoreapp2.1 + TargetFramework=net46 + + + TargetFramework=net46 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <_RunningRestore>true + + + + + + + + + + + + + + + + + + + + + diff --git a/global.json b/global.json new file mode 100644 index 0000000000..ac6900880b --- /dev/null +++ b/global.json @@ -0,0 +1,9 @@ +{ + "tools": { + "dotnet": "2.1.500" + }, + "msbuild-sdks": { + "Microsoft.DotNet.Arcade.Sdk": "1.0.0-beta.19069.2", + "Microsoft.DotNet.Helix.Sdk": "2.0.0-beta.19069.2" + } +} diff --git a/mono/cibuild.sh b/mono/cibuild.sh index e91b33e783..9a5ea5af57 100755 --- a/mono/cibuild.sh +++ b/mono/cibuild.sh @@ -1,7 +1,7 @@ #!/bin/bash # note: expects to run from top directory -./mono/latest-mono-stable.sh +#./mono/latest-mono-stable.sh make Configuration=$@ #sudo make install Configuration=$@ #./mono/test-mono.sh \ No newline at end of file diff --git a/packages.config b/packages.config index 25a939155f..709d225851 100644 --- a/packages.config +++ b/packages.config @@ -1,62 +1,4 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + diff --git a/proto.proj b/proto.proj new file mode 100644 index 0000000000..0974580af5 --- /dev/null +++ b/proto.proj @@ -0,0 +1,36 @@ + + + + Proto + AssemblySearchPaths={HintPathFromItem};{TargetFrameworkDirectory};{RawFileName} + + + + + + TargetFramework=net46 + TargetFramework=netcoreapp2.1 + + + TargetFramework=net46 + TargetFramework=netcoreapp2.1 + + + + + + + + + + + + + + + + + + + + diff --git a/src/Directory.Build.props b/src/Directory.Build.props new file mode 100644 index 0000000000..bb8eac309b --- /dev/null +++ b/src/Directory.Build.props @@ -0,0 +1,3 @@ + + + diff --git a/src/Directory.Build.targets b/src/Directory.Build.targets new file mode 100644 index 0000000000..ccd47cc0a9 --- /dev/null +++ b/src/Directory.Build.targets @@ -0,0 +1,3 @@ + + + diff --git a/src/absil/il.fs b/src/absil/il.fs index c2314418fe..61c5a33a84 100644 --- a/src/absil/il.fs +++ b/src/absil/il.fs @@ -154,12 +154,11 @@ let unsplitTypeName (ns, n) = | [] -> String.concat "." ns + "." + n | _ -> n -let splitTypeNameRightAux nm = - if String.contains nm '.' then - let idx = String.rindex nm '.' - let s1, s2 = splitNameAt nm idx - Some s1, s2 - else None, nm +let splitTypeNameRightAux (nm:string) = + let idx = nm.LastIndexOf '.' + if idx = -1 then None, nm else + let s1, s2 = splitNameAt nm idx + Some s1, s2 let splitTypeNameRight nm = memoizeNamespaceRightTable.GetOrAdd(nm, splitTypeNameRightAux) @@ -310,8 +309,12 @@ module SHA1 = let (_h0, _h1, _h2, h3, h4) = sha1Hash { stream = s; pos = 0; eof = false } // the result of the SHA algorithm is stored in registers 3 and 4 Array.map byte [| b0 h4; b1 h4; b2 h4; b3 h4; b0 h3; b1 h3; b2 h3; b3 h3; |] + let sha1HashInt64 s = + let (_h0,_h1,_h2,h3,h4) = sha1Hash { stream = s; pos = 0; eof = false } // the result of the SHA algorithm is stored in registers 3 and 4 + (int64 h3 <<< 32) ||| int64 h4 let sha1HashBytes s = SHA1.sha1HashBytes s +let sha1HashInt64 s = SHA1.sha1HashInt64 s // -------------------------------------------------------------------- // @@ -947,11 +950,25 @@ type ILAttribElem = type ILAttributeNamedArg = (string * ILType * bool * ILAttribElem) -[] -type ILAttribute = - { Method: ILMethodSpec - Data: byte[] - Elements: ILAttribElem list } +[] +type ILAttribute = + | Encoded of method: ILMethodSpec * data: byte[] * elements: ILAttribElem list + | Decoded of method: ILMethodSpec * fixedArgs: ILAttribElem list * namedArgs: ILAttributeNamedArg list + + member x.Method = + match x with + | Encoded (method, _, _) + | Decoded (method, _, _) -> method + + member x.Elements = + match x with + | Encoded (_, _, elements) -> elements + | Decoded (_, fixedArgs, namedArgs) -> fixedArgs @ (namedArgs |> List.map (fun (_, _, _, e) -> e)) + + member x.WithMethod(method: ILMethodSpec) = + match x with + | Encoded (_, data, elements) -> Encoded (method, data, elements) + | Decoded (_, fixedArgs, namedArgs) -> Decoded (method, fixedArgs, namedArgs) /// For debugging [] @@ -2313,7 +2330,7 @@ let mkILNonGenericValueTy tref = mkILNamedTy AsValue tref [] let mkILNonGenericBoxedTy tref = mkILNamedTy AsObject tref [] -let mkSimpleAssRef n = +let mkSimpleAssemblyRef n = ILAssemblyRef.Create(n, None, None, false, None, None) let mkSimpleModRef n = @@ -3174,9 +3191,9 @@ let destTypeDefsWithGlobalFunctionsFirst ilg (tdefs: ILTypeDefs) = let top2 = if isNil top then [ mkILTypeDefForGlobalFunctions ilg (emptyILMethods, emptyILFields) ] else top top2@nontop -let mkILSimpleModule assname modname dll subsystemVersion useHighEntropyVA tdefs hashalg locale flags exportedTypes metadataVersion = +let mkILSimpleModule assemblyName modname dll subsystemVersion useHighEntropyVA tdefs hashalg locale flags exportedTypes metadataVersion = let manifest = - { Name=assname + { Name=assemblyName AuxModuleHashAlgorithm= match hashalg with | Some(alg) -> alg | _ -> 0x8004 // SHA1 SecurityDeclsStored=emptyILSecurityDeclsStored PublicKey= None @@ -3572,21 +3589,30 @@ let encodeCustomAttrNamedArg ilg (nm, ty, prop, elem) = yield! encodeCustomAttrString nm yield! encodeCustomAttrValue ilg ty elem |] -let mkILCustomAttribMethRef (ilg: ILGlobals) (mspec:ILMethodSpec, fixedArgs: list<_>, namedArgs: list<_>) = +let encodeCustomAttrArgs (ilg: ILGlobals) (mspec:ILMethodSpec) (fixedArgs: list<_>) (namedArgs: list<_>) = let argtys = mspec.MethodRef.ArgTypes - let args = - [| yield! [| 0x01uy; 0x00uy; |] - for (argty, fixedArg) in Seq.zip argtys fixedArgs do - yield! encodeCustomAttrValue ilg argty fixedArg - yield! u16AsBytes (uint16 namedArgs.Length) - for namedArg in namedArgs do - yield! encodeCustomAttrNamedArg ilg namedArg |] - { Method = mspec - Data = args - Elements = fixedArgs @ (namedArgs |> List.map(fun (_, _, _, e) -> e)) } - -let mkILCustomAttribute ilg (tref, argtys, argvs, propvs) = - mkILCustomAttribMethRef ilg (mkILNonGenericCtorMethSpec (tref, argtys), argvs, propvs) + [| yield! [| 0x01uy; 0x00uy; |] + for (argty, fixedArg) in Seq.zip argtys fixedArgs do + yield! encodeCustomAttrValue ilg argty fixedArg + yield! u16AsBytes (uint16 namedArgs.Length) + for namedArg in namedArgs do + yield! encodeCustomAttrNamedArg ilg namedArg |] + +let encodeCustomAttr (ilg: ILGlobals) (mspec:ILMethodSpec, fixedArgs: list<_>, namedArgs: list<_>) = + let args = encodeCustomAttrArgs ilg mspec fixedArgs namedArgs + ILAttribute.Encoded (mspec, args, fixedArgs @ (namedArgs |> List.map (fun (_, _, _, e) -> e))) + +let mkILCustomAttribMethRef (ilg: ILGlobals) (mspec:ILMethodSpec, fixedArgs: list<_>, namedArgs: list<_>) = + encodeCustomAttr ilg (mspec, fixedArgs, namedArgs) + +let mkILCustomAttribute ilg (tref, argtys, argvs, propvs) = + encodeCustomAttr ilg (mkILNonGenericCtorMethSpec (tref, argtys), argvs, propvs) + +let getCustomAttrData (ilg: ILGlobals) cattr = + match cattr with + | ILAttribute.Encoded (_, data, _) -> data + | ILAttribute.Decoded (mspec, fixedArgs, namedArgs) -> + encodeCustomAttrArgs ilg mspec fixedArgs namedArgs let MscorlibScopeRef = ILScopeRef.Assembly (ILAssemblyRef.Create("mscorlib", None, Some ecmaPublicKey, true, None, None)) let EcmaMscorlibILGlobals = mkILGlobals MscorlibScopeRef @@ -3755,7 +3781,10 @@ type ILTypeSigParser(tstring : string) = ILAttribElem.Type(Some(ilty)) let decodeILAttribData (ilg: ILGlobals) (ca: ILAttribute) = - let bytes = ca.Data + match ca with + | ILAttribute.Decoded (_, fixedArgs, namedArgs) -> fixedArgs, namedArgs + | ILAttribute.Encoded (_, bytes, _) -> + let sigptr = 0 let bb0, sigptr = sigptr_get_byte bytes sigptr let bb1, sigptr = sigptr_get_byte bytes sigptr @@ -3892,13 +3921,13 @@ let emptyILRefs = ModuleReferences = [] } (* Now find references. *) -let refs_of_assref (s:ILReferencesAccumulator) x = s.refsA.Add x |> ignore +let refs_of_assemblyRef (s:ILReferencesAccumulator) x = s.refsA.Add x |> ignore let refs_of_modref (s:ILReferencesAccumulator) x = s.refsM.Add x |> ignore let refs_of_scoref s x = match x with | ILScopeRef.Local -> () - | ILScopeRef.Assembly assref -> refs_of_assref s assref + | ILScopeRef.Assembly assemblyRef -> refs_of_assemblyRef s assemblyRef | ILScopeRef.Module modref -> refs_of_modref s modref let refs_of_tref s (x:ILTypeRef) = refs_of_scoref s x.Scope @@ -3944,9 +3973,9 @@ and refs_of_token s x = | ILToken.ILMethod mr -> refs_of_mspec s mr | ILToken.ILField fr -> refs_of_fspec s fr -and refs_of_custom_attr s x = refs_of_mspec s x.Method +and refs_of_custom_attr s (cattr: ILAttribute) = refs_of_mspec s cattr.Method -and refs_of_custom_attrs s (cas : ILAttributes) = List.iter (refs_of_custom_attr s) cas.AsList +and refs_of_custom_attrs s (cas : ILAttributes) = Array.iter (refs_of_custom_attr s) cas.AsArray and refs_of_varargs s tyso = Option.iter (refs_of_tys s) tyso and refs_of_instr s x = match x with @@ -4070,7 +4099,7 @@ and refs_of_resource_where s x = | ILResourceLocation.LocalIn _ -> () | ILResourceLocation.LocalOut _ -> () | ILResourceLocation.File (mref, _) -> refs_of_modref s mref - | ILResourceLocation.Assembly aref -> refs_of_assref s aref + | ILResourceLocation.Assembly aref -> refs_of_assemblyRef s aref and refs_of_resource s x = refs_of_resource_where s x.Location @@ -4189,23 +4218,6 @@ let resolveILMethodRef td mref = resolveILMethodRefWithRescope id td mref let mkRefToILModule m = ILModuleRef.Create(m.Name, true, None) - -let ungenericizeTypeName n = - let sym = '`' - if - String.contains n sym && - (* check what comes after the symbol is a number *) - (let m = String.rindex n sym - let res = ref (m < n.Length - 1) - for i = m + 1 to n.Length - 1 do - res := !res && n.[i] >= '0' && n.[i] <= '9' - !res) - then - let pos = String.rindex n sym - String.sub n 0 pos - else n - - type ILEventRef = { erA: ILTypeRef; erB: string } static member Create(a, b) = {erA=a;erB=b} diff --git a/src/absil/il.fsi b/src/absil/il.fsi index 6ed4d42aa3..668459088f 100755 --- a/src/absil/il.fsi +++ b/src/absil/il.fsi @@ -752,12 +752,22 @@ type ILAttribElem = /// Named args: values and flags indicating if they are fields or properties. type ILAttributeNamedArg = string * ILType * bool * ILAttribElem -/// Custom attributes. See 'decodeILAttribData' for a helper to parse the byte[] -/// to ILAttribElem's as best as possible. +/// Custom attribute. type ILAttribute = - { Method: ILMethodSpec - Data: byte[] - Elements: ILAttribElem list} + /// Attribute with args encoded to a binary blob according to ECMA-335 II.21 and II.23.3. + /// 'decodeILAttribData' is used to parse the byte[] blob to ILAttribElem's as best as possible. + | Encoded of method: ILMethodSpec * data: byte[] * elements: ILAttribElem list + + /// Attribute with args in decoded form. + | Decoded of method: ILMethodSpec * fixedArgs: ILAttribElem list * namedArgs: ILAttributeNamedArg list + + /// Attribute instance constructor. + member Method: ILMethodSpec + + /// Decoded arguments. May be empty in encoded attribute form. + member Elements: ILAttribElem list + + member WithMethod: method: ILMethodSpec -> ILAttribute [] type ILAttributes = @@ -1540,9 +1550,6 @@ val typeNameForGlobalFunctions: string val isTypeNameForGlobalFunctions: string -> bool -val ungenericizeTypeName: string -> string (* e.g. List`1 --> List *) - - // ==================================================================== // PART 2 // @@ -1598,7 +1605,7 @@ val decodeILAttribData: ILAttributeNamedArg list (* named args: values and flags indicating if they are fields or properties *) /// Generate simple references to assemblies and modules. -val mkSimpleAssRef: string -> ILAssemblyRef +val mkSimpleAssemblyRef: string -> ILAssemblyRef val mkSimpleModRef: string -> ILModuleRef @@ -1682,6 +1689,8 @@ val mkILCustomAttribute: ILAttributeNamedArg list (* named args: values and flags indicating if they are fields or properties *) -> ILAttribute +val getCustomAttrData: ILGlobals -> ILAttribute -> byte[] + val mkPermissionSet: ILGlobals -> ILSecurityAction * (ILTypeRef * (string * ILType * ILAttribElem) list) list -> ILSecurityDecl /// Making code. @@ -1946,6 +1955,7 @@ val isILTypedReferenceTy: ILType -> bool val isILDoubleTy: ILType -> bool val isILSingleTy: ILType -> bool +val sha1HashInt64 : byte[] -> int64 /// Get a public key token from a public key. val sha1HashBytes: byte[] -> byte[] (* SHA1 hash *) diff --git a/src/absil/illib.fs b/src/absil/illib.fs index b2fd979a55..4426160638 100755 --- a/src/absil/illib.fs +++ b/src/absil/illib.fs @@ -41,6 +41,10 @@ let inline isNonNull x = not (isNull x) let inline nonNull msg x = if isNull x then failwith ("null: " + msg) else x let inline (===) x y = LanguagePrimitives.PhysicalEquality x y +/// Per the docs the threshold for the Large Object Heap is 85000 bytes: https://docs.microsoft.com/en-us/dotnet/standard/garbage-collection/large-object-heap#how-an-object-ends-up-on-the-large-object-heap-and-how-gc-handles-them +/// We set the limit to slightly under that to allow for some 'slop' +let LOH_SIZE_THRESHOLD_BYTES = 84_900 + //--------------------------------------------------------------------- // Library: ReportTime //--------------------------------------------------------------------- @@ -91,7 +95,7 @@ module Order = let toFunction (pxOrder: IComparer<'U>) x y = pxOrder.Compare(x,y) //------------------------------------------------------------------------- -// Library: arrays,lists,options +// Library: arrays,lists,options,resizearrays //------------------------------------------------------------------------- module Array = @@ -432,18 +436,57 @@ module List = let existsSquared f xss = xss |> List.exists (fun xs -> xs |> List.exists (fun x -> f x)) let mapiFoldSquared f z xss = mapFoldSquared f z (xss |> mapiSquared (fun i j x -> (i,j,x))) -[] -type ValueOption<'T> = - | ValueSome of 'T - | ValueNone - member x.IsSome = match x with ValueSome _ -> true | ValueNone -> false - member x.IsNone = match x with ValueSome _ -> false | ValueNone -> true - member x.Value = match x with ValueSome r -> r | ValueNone -> failwith "ValueOption.Value: value is None" +module ResizeArray = -[] -module ValueOption = + /// Split a ResizeArray into an array of smaller chunks. + /// This requires `items/chunkSize` Array copies of length `chunkSize` if `items/chunkSize % 0 = 0`, + /// otherwise `items/chunkSize + 1` Array copies. + let chunkBySize chunkSize f (items: ResizeArray<'t>) = + // we could use Seq.chunkBySize here, but that would involve many enumerator.MoveNext() calls that we can sidestep with a bit of math + let itemCount = items.Count + if itemCount = 0 + then [||] + else + let chunksCount = + match itemCount / chunkSize with + | n when itemCount % chunkSize = 0 -> n + | n -> n + 1 // any remainder means we need an additional chunk to store it + + [| for index in 0..chunksCount-1 do + let startIndex = index * chunkSize + let takeCount = min (itemCount - startIndex) chunkSize + + let holder = Array.zeroCreate takeCount + // we take a bounds-check hit here on each access. + // other alternatives here include + // * iterating across an IEnumerator (incurs MoveNext penalty) + // * doing a block copy using `List.CopyTo(index, array, index, count)` (requires more copies to do the mapping) + // none are significantly better. + for i in 0 .. takeCount - 1 do + holder.[i] <- f items.[i] + yield holder |] + + /// Split a large ResizeArray into a series of array chunks that are each under the Large Object Heap limit. + /// This is done to help prevent a stop-the-world collection of the single large array, instead allowing for a greater + /// probability of smaller collections. Stop-the-world is still possible, just less likely. + let mapToSmallArrayChunks f (inp: ResizeArray<'t>) = + let itemSizeBytes = sizeof<'t> + // rounding down here is good because it ensures we don't go over + let maxArrayItemCount = LOH_SIZE_THRESHOLD_BYTES / itemSizeBytes + + /// chunk the provided input into arrays that are smaller than the LOH limit + /// in order to prevent long-term storage of those values + chunkBySize maxArrayItemCount f inp + + +/// Because FSharp.Compiler.Service is a library that will target FSharp.Core 4.5.2 for the forseeable future, +/// we need to stick these functions in this module rather than using the module functions for ValueOption +/// that come after FSharp.Core 4.5.2. +module ValueOptionInternal = let inline ofOption x = match x with Some x -> ValueSome x | None -> ValueNone let inline bind f x = match x with ValueSome x -> f x | ValueNone -> ValueNone + let inline isSome x = match x with ValueSome _ -> true | ValueNone -> false + let inline isNone x = match x with ValueSome _ -> false | ValueNone -> true type String with member inline x.StartsWithOrdinal(value) = @@ -452,25 +495,14 @@ type String with member inline x.EndsWithOrdinal(value) = x.EndsWith(value, StringComparison.Ordinal) -module String = - let indexNotFound() = raise (new KeyNotFoundException("An index for the character was not found in the string")) - +module String = let make (n: int) (c: char) : string = new String(c, n) let get (str:string) i = str.[i] let sub (s:string) (start:int) (len:int) = s.Substring(start,len) - let index (s:string) (c:char) = - let r = s.IndexOf(c) - if r = -1 then indexNotFound() else r - - let rindex (s:string) (c:char) = - let r = s.LastIndexOf(c) - if r = -1 then indexNotFound() else r - - let contains (s:string) (c:char) = - s.IndexOf(c,0,String.length s) <> -1 + let contains (s:string) (c:char) = s.IndexOf(c) <> -1 let order = LanguagePrimitives.FastGenericComparer @@ -1134,7 +1166,7 @@ module NameMap = [] module NameMultiMap = let existsInRange f (m: NameMultiMap<'T>) = NameMap.exists (fun _ l -> List.exists f l) m - let find v (m: NameMultiMap<'T>) = match Map.tryFind v m with None -> [] | Some r -> r + let find v (m: NameMultiMap<'T>) = match m.TryGetValue v with true, r -> r | _ -> [] let add v x (m: NameMultiMap<'T>) = NameMap.add v (x :: find v m) m let range (m: NameMultiMap<'T>) = Map.foldBack (fun _ x sofar -> x @ sofar) m [] let rangeReversingEachBucket (m: NameMultiMap<'T>) = Map.foldBack (fun _ x sofar -> List.rev x @ sofar) m [] @@ -1148,7 +1180,7 @@ module NameMultiMap = [] module MultiMap = let existsInRange f (m: MultiMap<_,_>) = Map.exists (fun _ l -> List.exists f l) m - let find v (m: MultiMap<_,_>) = match Map.tryFind v m with None -> [] | Some r -> r + let find v (m: MultiMap<_,_>) = match m.TryGetValue v with true, r -> r | _ -> [] let add v x (m: MultiMap<_,_>) = Map.add v (x :: find v m) m let range (m: MultiMap<_,_>) = Map.foldBack (fun _ x sofar -> x @ sofar) m [] let empty : MultiMap<_,_> = Map.empty @@ -1159,11 +1191,6 @@ type LayeredMap<'Key,'Value when 'Key : comparison> = Map<'Key,'Value> type Map<'Key,'Value when 'Key : comparison> with static member Empty : Map<'Key,'Value> = Map.empty - member m.TryGetValue (key,res:byref<'Value>) = - match m.TryFind key with - | None -> false - | Some r -> res <- r; true - member x.Values = [ for (KeyValue(_,v)) in x -> v ] member x.AddAndMarkAsCollapsible (kvs: _[]) = (x,kvs) ||> Array.fold (fun x (KeyValue(k,v)) -> x.Add(k,v)) member x.LinearTryModifyThenLaterFlatten (key, f: 'Value option -> 'Value) = x.Add (key, f (x.TryFind key)) @@ -1173,12 +1200,13 @@ type Map<'Key,'Value when 'Key : comparison> with [] type LayeredMultiMap<'Key,'Value when 'Key : equality and 'Key : comparison>(contents : LayeredMap<'Key,'Value list>) = member x.Add (k,v) = LayeredMultiMap(contents.Add(k,v :: x.[k])) - member x.Item with get k = match contents.TryFind k with None -> [] | Some l -> l + member x.Item with get k = match contents.TryGetValue k with true, l -> l | _ -> [] member x.AddAndMarkAsCollapsible (kvs: _[]) = let x = (x,kvs) ||> Array.fold (fun x (KeyValue(k,v)) -> x.Add(k,v)) x.MarkAsCollapsible() member x.MarkAsCollapsible() = LayeredMultiMap(contents.MarkAsCollapsible()) member x.TryFind k = contents.TryFind k + member x.TryGetValue k = contents.TryGetValue k member x.Values = contents.Values |> List.concat static member Empty : LayeredMultiMap<'Key,'Value> = LayeredMultiMap LayeredMap.Empty diff --git a/src/absil/ilmorph.fs b/src/absil/ilmorph.fs index c6d009cd4d..d5398099e0 100755 --- a/src/absil/ilmorph.fs +++ b/src/absil/ilmorph.fs @@ -136,7 +136,7 @@ let rec celem_ty2ty f celem = let cnamedarg_ty2ty f ((nm, ty, isProp, elem) : ILAttributeNamedArg) = (nm, f ty, isProp, celem_ty2ty f elem) -let cattr_ty2ty ilg f c = +let cattr_ty2ty ilg f (c: ILAttribute) = let meth = mspec_ty2ty (f, (fun _ -> f)) c.Method // dev11 M3 defensive coding: if anything goes wrong with attribute decoding or encoding, then back out. if morphCustomAttributeData then @@ -144,11 +144,11 @@ let cattr_ty2ty ilg f c = let elems,namedArgs = IL.decodeILAttribData ilg c let elems = elems |> List.map (celem_ty2ty f) let namedArgs = namedArgs |> List.map (cnamedarg_ty2ty f) - IL.mkILCustomAttribMethRef ilg (meth, elems, namedArgs) - with _ -> - { c with Method = meth } + mkILCustomAttribMethRef ilg (meth, elems, namedArgs) + with _ -> + c.WithMethod(meth) else - { c with Method = meth } + c.WithMethod(meth) let cattrs_ty2ty ilg f (cs: ILAttributes) = diff --git a/src/absil/ilprint.fs b/src/absil/ilprint.fs index f11524bc8d..58c13ba148 100755 --- a/src/absil/ilprint.fs +++ b/src/absil/ilprint.fs @@ -30,13 +30,14 @@ let tyvar_generator = // Carry an environment because the way we print method variables // depends on the gparams of the current scope. type ppenv = - { ppenvClassFormals: int; + { ilGlobals: ILGlobals + ppenvClassFormals: int; ppenvMethodFormals: int } let ppenv_enter_method mgparams env = {env with ppenvMethodFormals=mgparams} let ppenv_enter_tdef gparams env = {env with ppenvClassFormals=List.length gparams; ppenvMethodFormals=0} -let mk_ppenv = { ppenvClassFormals=0; ppenvMethodFormals=0 } +let mk_ppenv ilg = { ilGlobals = ilg; ppenvClassFormals = 0; ppenvMethodFormals = 0 } let debug_ppenv = mk_ppenv let ppenv_enter_modul env = { env with ppenvClassFormals=0; ppenvMethodFormals=0 } @@ -97,6 +98,13 @@ let output_seq sep f os (a:seq<_>) = output_string os sep; f os e.Current +let output_array sep f os (a:_ []) = + if not (Array.isEmpty a) then + for i in 0..a.Length-2 do + f os a.[i] + output_string os sep + f os (a.[a.Length - 1]) + let output_parens f os a = output_string os "("; f os a; output_string os ")" let output_angled f os a = output_string os "<"; f os a; output_string os ">" let output_bracks f os a = output_string os "["; f os a; output_string os "]" @@ -436,12 +444,12 @@ let output_option f os = function None -> () | Some x -> f os x let goutput_alternative_ref env os (alt: IlxUnionAlternative) = output_id os alt.Name; - alt.FieldDefs |> Array.toList |> output_parens (output_seq "," (fun os fdef -> goutput_typ env os fdef.Type)) os + alt.FieldDefs |> output_parens (output_array "," (fun os fdef -> goutput_typ env os fdef.Type)) os let goutput_curef env os (IlxUnionRef(_,tref,alts,_,_)) = output_string os " .classunion import "; goutput_tref env os tref; - output_parens (output_seq "," (goutput_alternative_ref env)) os (Array.toList alts) + output_parens (output_array "," (goutput_alternative_ref env)) os alts let goutput_cuspec env os (IlxUnionSpec(IlxUnionRef(_,tref,_,_,_),i)) = output_string os "class /* classunion */ "; @@ -469,13 +477,14 @@ let output_basic_type os x = let output_custom_attr_data os data = output_string os " = "; output_parens output_bytes os data -let goutput_custom_attr env os attr = +let goutput_custom_attr env os (attr: ILAttribute) = output_string os " .custom " goutput_mspec env os attr.Method - output_custom_attr_data os attr.Data + let data = getCustomAttrData env.ilGlobals attr + output_custom_attr_data os data let goutput_custom_attrs env os (attrs : ILAttributes) = - List.iter (fun attr -> goutput_custom_attr env os attr; output_string os "\n" ) attrs.AsList + Array.iter (fun attr -> goutput_custom_attr env os attr; output_string os "\n" ) attrs.AsArray let goutput_fdef _tref env os (fd: ILFieldDef) = output_string os " .field " @@ -702,7 +711,7 @@ let rec goutput_instr env os inst = goutput_dlocref env os (mkILArrTy(typ,shape)); output_string os ".ctor"; let rank = shape.Rank - output_parens (output_seq "," (goutput_typ env)) os (Array.toList (Array.create ( rank) EcmaMscorlibILGlobals.typ_Int32)) + output_parens (output_array "," (goutput_typ env)) os (Array.create ( rank) EcmaMscorlibILGlobals.typ_Int32) | I_stelem_any (shape,dt) -> if shape = ILArrayShape.SingleDimensional then output_string os "stelem.any "; goutput_typ env os dt @@ -711,7 +720,9 @@ let rec goutput_instr env os inst = goutput_dlocref env os (mkILArrTy(dt,shape)); output_string os "Set"; let rank = shape.Rank - output_parens (output_seq "," (goutput_typ env)) os (Array.toList (Array.create ( rank) EcmaMscorlibILGlobals.typ_Int32) @ [dt]) + let arr = Array.create (rank + 1) EcmaMscorlibILGlobals.typ_Int32 + arr.[rank] <- dt + output_parens (output_array "," (goutput_typ env)) os arr | I_ldelem_any (shape,tok) -> if shape = ILArrayShape.SingleDimensional then output_string os "ldelem.any "; goutput_typ env os tok @@ -722,7 +733,7 @@ let rec goutput_instr env os inst = goutput_dlocref env os (mkILArrTy(tok,shape)); output_string os "Get"; let rank = shape.Rank - output_parens (output_seq "," (goutput_typ env)) os (Array.toList (Array.create ( rank) EcmaMscorlibILGlobals.typ_Int32)) + output_parens (output_array "," (goutput_typ env)) os (Array.create ( rank) EcmaMscorlibILGlobals.typ_Int32) | I_ldelema (ro,_,shape,tok) -> if ro = ReadonlyAddress then output_string os "readonly. "; if shape = ILArrayShape.SingleDimensional then @@ -734,7 +745,7 @@ let rec goutput_instr env os inst = goutput_dlocref env os (mkILArrTy(tok,shape)); output_string os "Address"; let rank = shape.Rank - output_parens (output_seq "," (goutput_typ env)) os (Array.toList (Array.create ( rank) EcmaMscorlibILGlobals.typ_Int32)) + output_parens (output_array "," (goutput_typ env)) os (Array.create ( rank) EcmaMscorlibILGlobals.typ_Int32) | I_box tok -> output_string os "box "; goutput_typ env os tok | I_unbox tok -> output_string os "unbox "; goutput_typ env os tok @@ -888,7 +899,7 @@ let splitTypeLayout = function let goutput_fdefs tref env os (fdefs: ILFieldDefs) = List.iter (fun f -> (goutput_fdef tref env) os f; output_string os "\n" ) fdefs.AsList let goutput_mdefs env os (mdefs: ILMethodDefs) = - List.iter (fun f -> (goutput_mdef env) os f; output_string os "\n" ) mdefs.AsList + Array.iter (fun f -> (goutput_mdef env) os f; output_string os "\n" ) mdefs.AsArray let goutput_pdefs env os (pdefs: ILPropertyDefs) = List.iter (fun f -> (goutput_pdef env) os f; output_string os "\n" ) pdefs.AsList @@ -975,7 +986,7 @@ let output_publickeyinfo os = function | PublicKey k -> output_publickey os k | PublicKeyToken k -> output_publickeytoken os k -let output_assref os (aref:ILAssemblyRef) = +let output_assemblyRef os (aref:ILAssemblyRef) = output_string os " .assembly extern "; output_sqstring os aref.Name; if aref.Retargetable then output_string os " retargetable "; @@ -1029,9 +1040,9 @@ let goutput_manifest env os m = output_string os " } \n" -let output_module_fragment_aux _refs os modul = +let output_module_fragment_aux _refs os (ilg: ILGlobals) modul = try - let env = mk_ppenv + let env = mk_ppenv ilg let env = ppenv_enter_modul env goutput_tdefs false ([]) env os modul.TypeDefs; goutput_tdefs true ([]) env os modul.TypeDefs; @@ -1039,13 +1050,13 @@ let output_module_fragment_aux _refs os modul = output_string os "*** Error during printing : "; output_string os (e.ToString()); os.Flush(); reraise() -let output_module_fragment os modul = +let output_module_fragment os (ilg: ILGlobals) modul = let refs = computeILRefs modul - output_module_fragment_aux refs os modul; + output_module_fragment_aux refs os ilg modul refs let output_module_refs os refs = - List.iter (fun x -> output_assref os x; output_string os "\n") refs.AssemblyReferences; + List.iter (fun x -> output_assemblyRef os x; output_string os "\n") refs.AssemblyReferences; List.iter (fun x -> output_modref os x; output_string os "\n") refs.ModuleReferences let goutput_module_manifest env os modul = @@ -1059,14 +1070,14 @@ let goutput_module_manifest env os modul = output_string os "\n"; (output_option (goutput_manifest env)) os modul.Manifest -let output_module os modul = +let output_module os (ilg: ILGlobals) modul = try let refs = computeILRefs modul - let env = mk_ppenv + let env = mk_ppenv ilg let env = ppenv_enter_modul env output_module_refs os refs; goutput_module_manifest env os modul; - output_module_fragment_aux refs os modul; + output_module_fragment_aux refs os ilg modul; with e -> output_string os "*** Error during printing : "; output_string os (e.ToString()); os.Flush(); raise e diff --git a/src/absil/ilprint.fsi b/src/absil/ilprint.fsi index 55e768ab68..5f7ebe4f11 100755 --- a/src/absil/ilprint.fsi +++ b/src/absil/ilprint.fsi @@ -9,6 +9,6 @@ open Microsoft.FSharp.Compiler.AbstractIL.Internal open System.IO #if DEBUG -val public output_module : TextWriter -> ILModuleDef -> unit +val public output_module: TextWriter -> ilg: ILGlobals -> ILModuleDef -> unit #endif diff --git a/src/absil/ilread.fs b/src/absil/ilread.fs index 5d94041dae..c2c10e9479 100755 --- a/src/absil/ilread.fs +++ b/src/absil/ilread.fs @@ -2101,7 +2101,7 @@ and sigptrGetTy (ctxt: ILMetadataReader) numtypars bytes sigptr = let dim i = (if i < numLoBounded then Some (List.item i lobounds) else None), (if i < numSized then Some (List.item i sizes) else None) - ILArrayShape (Array.toList (Array.init rank dim)) + ILArrayShape (List.init rank dim) mkILArrTy (ty, shape), sigptr elif b0 = et_VOID then ILType.Void, sigptr @@ -2567,12 +2567,13 @@ and seekReadCustomAttr ctxt (TaggedIndex(cat, idx), b) = and seekReadCustomAttrUncached ctxtH (CustomAttrIdx (cat, idx, valIdx)) = let ctxt = getHole ctxtH - { Method=seekReadCustomAttrType ctxt (TaggedIndex(cat, idx)) - Data= + let method = seekReadCustomAttrType ctxt (TaggedIndex(cat, idx)) + let data = match readBlobHeapOption ctxt valIdx with | Some bytes -> bytes - | None -> Bytes.ofInt32Array [| |] - Elements = [] } + | None -> Bytes.ofInt32Array [| |] + let elements = [] + ILAttribute.Encoded (method, data, elements) and securityDeclsReader ctxtH tag = mkILSecurityDeclsReader diff --git a/src/absil/ilreflect.fs b/src/absil/ilreflect.fs index c07408e8ab..5e15cbbd37 100755 --- a/src/absil/ilreflect.fs +++ b/src/absil/ilreflect.fs @@ -289,6 +289,7 @@ module Zmap = let equalTypes (s:Type) (t:Type) = s.Equals(t) let equalTypeLists ss tt = List.lengthsEqAndForall2 equalTypes ss tt +let equalTypeArrays ss tt = Array.lengthsEqAndForall2 equalTypes ss tt let getGenericArgumentsOfType (typT : Type) = if typT.IsGenericType then typT.GetGenericArguments() else [| |] @@ -763,7 +764,9 @@ let queryableTypeGetMethodBySearch cenv emEnv parentT (mref:ILMethodRef) = res match List.tryFind select methInfos with - | None -> failwith "convMethodRef: could not bind to method" + | None -> + let methNames = methInfos |> List.map (fun m -> m.Name) |> List.distinct + failwithf "convMethodRef: could not bind to method '%A' of type '%s'" (System.String.Join(", ", methNames)) parentT.AssemblyQualifiedName | Some methInfo -> methInfo (* return MethodInfo for (generic) type's (generic) method *) let queryableTypeGetMethod cenv emEnv parentT (mref:ILMethodRef) = @@ -1412,16 +1415,16 @@ let emitMethodBody cenv modB emEnv ilG _name (mbody: ILLazyMethodBody) = | MethodBody.Native -> failwith "emitMethodBody: native" | MethodBody.NotAvailable -> failwith "emitMethodBody: metadata only" -let convCustomAttr cenv emEnv cattr = +let convCustomAttr cenv emEnv (cattr: ILAttribute) = let methInfo = match convConstructorSpec cenv emEnv cattr.Method with | null -> failwithf "convCustomAttr: %+A" cattr.Method | res -> res - let data = cattr.Data + let data = getCustomAttrData cenv.ilg cattr (methInfo, data) let emitCustomAttr cenv emEnv add cattr = add (convCustomAttr cenv emEnv cattr) -let emitCustomAttrs cenv emEnv add (cattrs : ILAttributes) = List.iter (emitCustomAttr cenv emEnv add) cattrs.AsList +let emitCustomAttrs cenv emEnv add (cattrs : ILAttributes) = Array.iter (emitCustomAttr cenv emEnv add) cattrs.AsArray //---------------------------------------------------------------------------- // buildGenParams @@ -1595,9 +1598,7 @@ let rec buildMethodPass3 cenv tref modB (typB:TypeBuilder) emEnv (mdef : ILMetho (getGenericArgumentsOfType (typB.AsType())) (getGenericArgumentsOfMethod methB)) - match mdef.Return.CustomAttrs.AsList with - | [] -> () - | _ -> + if not (Array.isEmpty mdef.Return.CustomAttrs.AsArray) then let retB = methB.DefineParameterAndLog(0, System.Reflection.ParameterAttributes.Retval, null) emitCustomAttrs cenv emEnv (wrapCustomAttr retB.SetCustomAttribute) mdef.Return.CustomAttrs @@ -1823,7 +1824,7 @@ let rec buildTypeDefPass2 cenv nesting emEnv (tdef : ILTypeDef) = // add interface impls tdef.Implements |> convTypes cenv emEnv |> List.iter (fun implT -> typB.AddInterfaceImplementationAndLog(implT)); // add methods, properties - let emEnv = List.fold (buildMethodPass2 cenv tref typB) emEnv tdef.Methods.AsList + let emEnv = Array.fold (buildMethodPass2 cenv tref typB) emEnv tdef.Methods.AsArray let emEnv = List.fold (buildFieldPass2 cenv tref typB) emEnv tdef.Fields.AsList let emEnv = List.fold (buildPropertyPass2 cenv tref typB) emEnv tdef.Properties.AsList let emEnv = envPopTyvars emEnv @@ -1940,7 +1941,7 @@ let createTypeRef (visited : Dictionary<_, _>, created : Dictionary<_, _>) emEnv traverseType CollectTypes.All cx if verbose2 then dprintf "buildTypeDefPass4: Doing method constraints of %s\n" tdef.Name - for md in tdef.Methods.AsList do + for md in tdef.Methods.AsArray do for gp in md.GenericParams do for cx in gp.Constraints do traverseType CollectTypes.All cx diff --git a/src/absil/ilwrite.fs b/src/absil/ilwrite.fs index d28348bf86..12541d5089 100755 --- a/src/absil/ilwrite.fs +++ b/src/absil/ilwrite.fs @@ -1382,8 +1382,9 @@ and GetMethodRefAsCustomAttribType cenv (mref:ILMethodRef) = let rec GetCustomAttrDataAsBlobIdx cenv (data:byte[]) = if data.Length = 0 then 0 else GetBytesAsBlobIdx cenv data -and GetCustomAttrRow cenv hca attr = +and GetCustomAttrRow cenv hca (attr: ILAttribute) = let cat = GetMethodRefAsCustomAttribType cenv attr.Method.MethodRef + let data = getCustomAttrData cenv.ilg attr for element in attr.Elements do match element with | ILAttribElem.Type (Some ty) when ty.IsNominal -> GetTypeRefAsTypeRefIdx cenv ty.TypeRef |> ignore @@ -1393,14 +1394,14 @@ and GetCustomAttrRow cenv hca attr = UnsharedRow [| HasCustomAttribute (fst hca, snd hca); CustomAttributeType (fst cat, snd cat); - Blob (GetCustomAttrDataAsBlobIdx cenv attr.Data) + Blob (GetCustomAttrDataAsBlobIdx cenv data) |] and GenCustomAttrPass3Or4 cenv hca attr = AddUnsharedRow cenv TableNames.CustomAttribute (GetCustomAttrRow cenv hca attr) |> ignore and GenCustomAttrsPass3Or4 cenv hca (attrs: ILAttributes) = - attrs.AsList |> List.iter (GenCustomAttrPass3Or4 cenv hca) + attrs.AsArray |> Array.iter (GenCustomAttrPass3Or4 cenv hca) // -------------------------------------------------------------------- // ILSecurityDecl --> DeclSecurity rows @@ -2462,7 +2463,7 @@ let GenReturnAsParamRow (returnv : ILReturn) = StringE 0 |] let GenReturnPass3 cenv (returnv: ILReturn) = - if Option.isSome returnv.Marshal || not (isNil returnv.CustomAttrs.AsList) then + if Option.isSome returnv.Marshal || not (Array.isEmpty returnv.CustomAttrs.AsArray) then let pidx = AddUnsharedRow cenv TableNames.Param (GenReturnAsParamRow returnv) GenCustomAttrsPass3Or4 cenv (hca_ParamDef, pidx) returnv.CustomAttrs match returnv.Marshal with diff --git a/src/buildtools/buildtools.proj b/src/buildtools/buildtools.proj new file mode 100644 index 0000000000..593f086dd0 --- /dev/null +++ b/src/buildtools/buildtools.proj @@ -0,0 +1,32 @@ + + + + Debug + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/buildtools/buildtools.targets b/src/buildtools/buildtools.targets new file mode 100644 index 0000000000..9b00e18cf7 --- /dev/null +++ b/src/buildtools/buildtools.targets @@ -0,0 +1,56 @@ + + + + dotnet + dotnet.exe + + $(DotNetExe) + + + + + + + $(ArtifactsBinDir)\fslex\Proto\netcoreapp2.0\fslex.dll + + + + + + + + + + + + + + + + + + + $(ArtifactsBinDir)\fsyacc\Proto\netcoreapp2.0\fsyacc.dll + + + + + + + + + + + + + + + diff --git a/src/buildtools/fslex/App.config b/src/buildtools/fslex/App.config new file mode 100644 index 0000000000..e1b09eda9f --- /dev/null +++ b/src/buildtools/fslex/App.config @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/buildtools/fslex/Arg.fs b/src/buildtools/fslex/Arg.fs new file mode 100644 index 0000000000..a1f63bd963 --- /dev/null +++ b/src/buildtools/fslex/Arg.fs @@ -0,0 +1,133 @@ +// (c) Microsoft Corporation 2005-2009. + +#if INTERNALIZED_FSLEXYACC_RUNTIME +namespace Internal.Utilities +#else +namespace Microsoft.FSharp.Text +#endif + + +type ArgType = + | ClearArg of bool ref + | FloatArg of (float -> unit) + | IntArg of (int -> unit) + | RestArg of (string -> unit) + | SetArg of bool ref + | StringArg of (string -> unit) + | UnitArg of (unit -> unit) + static member Clear r = ClearArg r + static member Float r = FloatArg r + static member Int r = IntArg r + static member Rest r = RestArg r + static member Set r = SetArg r + static member String r = StringArg r + static member Unit r = UnitArg r + + +type ArgInfo (name,action,help) = + member x.Name = name + member x.ArgType = action + member x.HelpText = help + +exception Bad of string +exception HelpText of string + +[] +type ArgParser() = + static let getUsage specs u = + let sbuf = new System.Text.StringBuilder 100 + let pstring (s:string) = sbuf.Append s |> ignore + let pendline s = pstring s; pstring "\n" + pendline u; + List.iter (fun (arg:ArgInfo) -> + match arg.Name, arg.ArgType, arg.HelpText with + | (s, (UnitArg _ | SetArg _ | ClearArg _), helpText) -> pstring "\t"; pstring s; pstring ": "; pendline helpText + | (s, StringArg _, helpText) -> pstring "\t"; pstring s; pstring " : "; pendline helpText + | (s, IntArg _, helpText) -> pstring "\t"; pstring s; pstring " : "; pendline helpText + | (s, FloatArg _, helpText) -> pstring "\t"; pstring s; pstring " : "; pendline helpText + | (s, RestArg _, helpText) -> pstring "\t"; pstring s; pstring " ...: "; pendline helpText) + specs; + pstring "\t"; pstring "--help"; pstring ": "; pendline "display this list of options"; + pstring "\t"; pstring "-help"; pstring ": "; pendline "display this list of options"; + sbuf.ToString() + + + static member ParsePartial(cursor,argv,argSpecs:seq,?other,?usageText) = + let other = defaultArg other (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) + while !cursor < nargs do + let arg = argv.[!cursor] + let rec findMatchingArg args = + match args with + | ((s, action) :: _) when s = arg -> + let getSecondArg () = + if !cursor + 1 >= nargs then + raise(Bad("option "+s+" needs an argument.\n"+getUsage argSpecs usageText)); + argv.[!cursor+1] + + match action with + | UnitArg f -> + f (); + incr cursor + | SetArg f -> + f := true; + incr cursor + | ClearArg f -> + f := false; + incr cursor + | StringArg f-> + let arg2 = getSecondArg() + f arg2; + cursor := !cursor + 2 + | IntArg f -> + let arg2 = getSecondArg () + let arg2 = try int32 arg2 with _ -> raise(Bad(getUsage argSpecs usageText)) in + f arg2; + cursor := !cursor + 2; + | FloatArg f -> + let arg2 = getSecondArg() + let arg2 = try float arg2 with _ -> raise(Bad(getUsage argSpecs usageText)) in + f arg2; + cursor := !cursor + 2; + | RestArg f -> + incr cursor; + while !cursor < nargs do + f (argv.[!cursor]); + incr cursor; + + | (_ :: more) -> findMatchingArg more + | [] -> + if arg = "-help" || arg = "--help" || arg = "/help" || arg = "/help" || arg = "/?" then + raise (HelpText (getUsage argSpecs 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)) + else + other arg; + incr cursor + findMatchingArg specs + + static member Usage (specs,?usage) = + let usage = defaultArg usage "" + System.Console.Error.WriteLine (getUsage (Seq.toList specs) usage) + + #if FX_NO_COMMAND_LINE_ARGS + #else + static member Parse (specs,?other,?usageText) = + let current = ref 0 + let argv = System.Environment.GetCommandLineArgs() + try ArgParser.ParsePartial (current, argv, specs, ?other=other, ?usageText=usageText) + with + | Bad h + | HelpText h -> + System.Console.Error.WriteLine h; + System.Console.Error.Flush(); + System.Environment.Exit(1); + | e -> + reraise() + #endif diff --git a/src/buildtools/fslex/Arg.fsi b/src/buildtools/fslex/Arg.fsi new file mode 100644 index 0000000000..367f69f959 --- /dev/null +++ b/src/buildtools/fslex/Arg.fsi @@ -0,0 +1,50 @@ +// (c) Microsoft Corporation 2005-2009. + +/// A simple command-line argument processor. +#if INTERNALIZED_FSLEXYACC_RUNTIME +namespace Internal.Utilities +#else +namespace Microsoft.FSharp.Text +#endif + +/// The spec value describes the action of the argument, +/// and whether it expects a following parameter. +[] +type ArgType = + static member Clear : bool ref -> ArgType + static member Float : (float -> unit) -> ArgType + static member Int : (int -> unit) -> ArgType + static member Rest : (string -> unit) -> ArgType + static member Set : bool ref -> ArgType + static member String : (string -> unit) -> ArgType + static member Unit : (unit -> unit) -> ArgType + +type ArgInfo = + new : name:string * action:ArgType * help:string -> ArgInfo + /// Return the name of the argument + member Name : string + /// Return the argument type and action of the argument + member ArgType : ArgType + /// Return the usage help associated with the argument + member HelpText : string + +[] +type ArgParser = + #if FX_NO_COMMAND_LINE_ARGS + #else + + /// Parse some of the arguments given by 'argv', starting at the given position + [] + static member ParsePartial: cursor: int ref * argv: string[] * arguments:seq * ?otherArgs: (string -> unit) * ?usageText:string -> unit + + /// Parse the arguments given by System.Environment.GetEnvironmentVariables() + /// according to the argument processing specifications "specs". + /// Args begin with "-". Non-arguments are passed to "f" in + /// order. "use" is printed as part of the usage line if an error occurs. + + static member Parse: arguments:seq * ?otherArgs: (string -> unit) * ?usageText:string -> unit + #endif + + /// Prints the help for each argument. + static member Usage : arguments:seq * ?usage:string -> unit + diff --git a/src/buildtools/fslex/Lexing.fs b/src/buildtools/fslex/Lexing.fs new file mode 100644 index 0000000000..8337717d6f --- /dev/null +++ b/src/buildtools/fslex/Lexing.fs @@ -0,0 +1,423 @@ +// (c) Microsoft Corporation 2005-2009. + +#nowarn "47" // recursive initialization of LexBuffer + + +#if INTERNALIZED_FSLEXYACC_RUNTIME +namespace Internal.Utilities.Text.Lexing + +#else +namespace Microsoft.FSharp.Text.Lexing +#endif + + open System.Collections.Generic + + // REVIEW: This type showed up on a parsing-intensive performance measurement. Consider whether it can be a struct-record later when we have this feature. -jomo +#if INTERNALIZED_FSLEXYACC_RUNTIME + type internal Position = +#else + type Position = +#endif + { pos_fname : string; + pos_lnum : int; +#if INTERNALIZED_FSLEXYACC_RUNTIME + pos_orig_lnum : int; +#endif + pos_bol : int; + pos_cnum : int; } + member x.FileName = x.pos_fname + member x.Line = x.pos_lnum +#if INTERNALIZED_FSLEXYACC_RUNTIME + member x.OriginalLine = x.pos_orig_lnum +#endif + member x.Char = x.pos_cnum + member x.AbsoluteOffset = x.pos_cnum + member x.StartOfLine = x.pos_bol + member x.StartOfLineAbsoluteOffset = x.pos_bol + member x.Column = x.pos_cnum - x.pos_bol + member pos.NextLine = + { pos with +#if INTERNALIZED_FSLEXYACC_RUNTIME + pos_orig_lnum = pos.OriginalLine + 1; +#endif + pos_lnum = pos.Line+1; + pos_bol = pos.AbsoluteOffset } + member pos.EndOfToken(n) = {pos with pos_cnum=pos.pos_cnum + n } + member pos.AsNewLinePos() = pos.NextLine + member pos.ShiftColumnBy(by) = {pos with pos_cnum = pos.pos_cnum + by} + static member Empty = + { pos_fname=""; + pos_lnum= 0; +#if INTERNALIZED_FSLEXYACC_RUNTIME + pos_orig_lnum = 0; +#endif + pos_bol= 0; + pos_cnum=0 } + static member FirstLine(filename) = + { pos_fname=filename; +#if INTERNALIZED_FSLEXYACC_RUNTIME + pos_orig_lnum = 1; +#endif + pos_lnum= 1; + pos_bol= 0; + pos_cnum=0 } + +#if INTERNALIZED_FSLEXYACC_RUNTIME + type internal LexBufferFiller<'char> = +#else + type LexBufferFiller<'char> = +#endif + { fillSync : (LexBuffer<'char> -> unit) option + fillAsync : (LexBuffer<'char> -> Async) option } + + and [] +#if INTERNALIZED_FSLEXYACC_RUNTIME + internal LexBuffer<'char>(filler: LexBufferFiller<'char>) as this = +#else + LexBuffer<'char>(filler: LexBufferFiller<'char>) as this = +#endif + let context = new Dictionary(1) in + let extendBufferSync = (fun () -> match filler.fillSync with Some refill -> refill this | None -> invalidOp "attempt to read synchronously from an asynchronous lex buffer") + let extendBufferAsync = (fun () -> match filler.fillAsync with Some refill -> refill this | None -> invalidOp "attempt to read asynchronously from a synchronous lex buffer") + let mutable buffer=[||]; + /// number of valid charactes beyond bufferScanStart + let mutable bufferMaxScanLength=0; + /// count into the buffer when scanning + let mutable bufferScanStart=0; + /// number of characters scanned so far + let mutable bufferScanLength=0; + /// length of the scan at the last accepting state + let mutable lexemeLength=0; + /// action related to the last accepting state + let mutable bufferAcceptAction=0; + let mutable eof = false; + let mutable startPos = Position.Empty ; + let mutable endPos = Position.Empty + + // Throw away all the input besides the lexeme + + let discardInput () = + let keep = Array.sub buffer bufferScanStart bufferScanLength + let nkeep = keep.Length + Array.blit keep 0 buffer 0 nkeep; + bufferScanStart <- 0; + bufferMaxScanLength <- nkeep + + + member lexbuf.EndOfScan () : int = + // Printf.eprintf "endOfScan, lexBuffer.lexemeLength = %d\n" lexBuffer.lexemeLength; + if bufferAcceptAction < 0 then + failwith "unrecognized input" + + // Printf.printf "endOfScan %d state %d on unconsumed input '%c' (%d)\n" a s (Char.chr inp) inp; + // Printf.eprintf "accept, lexeme = %s\n" (lexeme lexBuffer); + lexbuf.StartPos <- endPos; + lexbuf.EndPos <- endPos.EndOfToken(lexbuf.LexemeLength); + bufferAcceptAction + + member lexbuf.StartPos + with get() = startPos + and set(b) = startPos <- b + + member lexbuf.EndPos + with get() = endPos + and set(b) = endPos <- b + + member lexbuf.Lexeme = Array.sub buffer bufferScanStart lexemeLength + member lexbuf.LexemeChar(n) = buffer.[n+bufferScanStart] + + member lexbuf.BufferLocalStore = (context :> IDictionary<_,_>) + member lexbuf.LexemeLength with get() : int = lexemeLength and set v = lexemeLength <- v + member internal lexbuf.Buffer with get() : 'char[] = buffer and set v = buffer <- v + member internal lexbuf.BufferMaxScanLength with get() = bufferMaxScanLength and set v = bufferMaxScanLength <- v + member internal lexbuf.BufferScanLength with get() = bufferScanLength and set v = bufferScanLength <- v + member internal lexbuf.BufferScanStart with get() : int = bufferScanStart and set v = bufferScanStart <- v + member internal lexbuf.BufferAcceptAction with get() = bufferAcceptAction and set v = bufferAcceptAction <- v + member internal lexbuf.RefillBuffer = extendBufferSync + member internal lexbuf.AsyncRefillBuffer = extendBufferAsync + + static member LexemeString(lexbuf:LexBuffer) = + new System.String(lexbuf.Buffer,lexbuf.BufferScanStart,lexbuf.LexemeLength) + + member lexbuf.IsPastEndOfStream + with get() = eof + and set(b) = eof <- b + + member lexbuf.DiscardInput() = discardInput () + + member x.BufferScanPos = bufferScanStart + bufferScanLength + + member lexbuf.EnsureBufferSize n = + if lexbuf.BufferScanPos + n >= buffer.Length then + let repl = Array.zeroCreate (lexbuf.BufferScanPos + n) + Array.blit buffer bufferScanStart repl bufferScanStart bufferScanLength; + buffer <- repl + + static member FromReadFunctions (syncRead : ('char[] * int * int -> int) option, asyncRead : ('char[] * int * int -> Async) option) : LexBuffer<'char> = + let extension= Array.zeroCreate 4096 + let fillers = + { fillSync = + match syncRead with + | None -> None + | Some read -> + Some (fun lexBuffer -> + let n = read(extension,0,extension.Length) + lexBuffer.EnsureBufferSize n; + Array.blit extension 0 lexBuffer.Buffer lexBuffer.BufferScanPos n; + lexBuffer.BufferMaxScanLength <- lexBuffer.BufferScanLength + n); + fillAsync = + match asyncRead with + | None -> None + | Some read -> + Some (fun lexBuffer -> + async { + let! n = read(extension,0,extension.Length) + lexBuffer.EnsureBufferSize n; + Array.blit extension 0 lexBuffer.Buffer lexBuffer.BufferScanPos n; + lexBuffer.BufferMaxScanLength <- lexBuffer.BufferScanLength + n }) } + new LexBuffer<_>(fillers) + + // A full type signature is required on this method because it is used at more specific types within its own scope + static member FromFunction (f : 'char[] * int * int -> int) : LexBuffer<'char> = LexBuffer<_>.FromReadFunctions(Some(f),None) + static member FromAsyncFunction (f : 'char[] * int * int -> Async) : LexBuffer<'char> = LexBuffer<_>.FromReadFunctions(None,Some(f)) + + static member FromCharFunction f : LexBuffer = + LexBuffer.FromFunction(fun (buff,start,len) -> + let buff2 = Array.zeroCreate len + let n = f buff2 len + Array.blit buff2 0 buff start len + n) + static member FromByteFunction f : LexBuffer = + LexBuffer.FromFunction(fun (buff,start,len) -> + let buff2 = Array.zeroCreate len + let n = f buff2 len + Array.blit buff2 0 buff start len + n) + + // A full type signature is required on this method because it is used at more specific types within its own scope + static member FromArray (s: 'char[]) : LexBuffer<'char> = + let lexBuffer = + new LexBuffer<_> + { fillSync = Some (fun _ -> ()); + fillAsync = Some (fun _ -> async { return () }) } + let buffer = Array.copy s + lexBuffer.Buffer <- buffer; + lexBuffer.BufferMaxScanLength <- buffer.Length; + lexBuffer + + static member FromBytes (arr) = LexBuffer.FromArray(arr) + static member FromChars (arr) = LexBuffer.FromArray(arr) + static member FromString (s:string) = LexBuffer.FromChars (s.ToCharArray()) + + static member FromTextReader (tr:System.IO.TextReader) : LexBuffer = + LexBuffer.FromFunction(tr.Read) + + static member FromBinaryReader (br:System.IO.BinaryReader) : LexBuffer = + LexBuffer.FromFunction(br.Read) + + static member FromStream (stream:System.IO.Stream) : LexBuffer = + LexBuffer.FromReadFunctions(Some(stream.Read),Some(fun (buf,offset,len) -> stream.AsyncRead(buf,offset=offset,count=len))) + + module GenericImplFragments = + let startInterpret(lexBuffer:LexBuffer<_>)= + lexBuffer.BufferScanStart <- lexBuffer.BufferScanStart + lexBuffer.LexemeLength; + lexBuffer.BufferMaxScanLength <- lexBuffer.BufferMaxScanLength - lexBuffer.LexemeLength; + lexBuffer.BufferScanLength <- 0; + lexBuffer.LexemeLength <- 0; + lexBuffer.BufferAcceptAction <- -1; + + let afterRefill (trans: uint16[] array,sentinel,lexBuffer:LexBuffer<_>,scanUntilSentinel,endOfScan,state,eofPos) = + // end of file occurs if we couldn't extend the buffer + if lexBuffer.BufferScanLength = lexBuffer.BufferMaxScanLength then + let snew = int trans.[state].[eofPos] // == EOF + if snew = sentinel then + endOfScan() + else + if lexBuffer.IsPastEndOfStream then failwith "End of file on lexing stream"; + lexBuffer.IsPastEndOfStream <- true; + // Printf.printf "state %d --> %d on eof\n" state snew; + scanUntilSentinel(lexBuffer,snew) + else + scanUntilSentinel(lexBuffer, state) + + let onAccept (lexBuffer:LexBuffer<_>,a) = + lexBuffer.LexemeLength <- lexBuffer.BufferScanLength; + lexBuffer.BufferAcceptAction <- a; + + open GenericImplFragments + + [] +#if INTERNALIZED_FSLEXYACC_RUNTIME + type internal AsciiTables(trans: uint16[] array, accept: uint16[]) = +#else + type AsciiTables(trans: uint16[] array, accept: uint16[]) = +#endif + let rec scanUntilSentinel(lexBuffer, state) = + let sentinel = 255 * 256 + 255 + // Return an endOfScan after consuming the input + let a = int accept.[state] + if a <> sentinel then + onAccept (lexBuffer,a) + + if lexBuffer.BufferScanLength = lexBuffer.BufferMaxScanLength then + lexBuffer.DiscardInput(); + lexBuffer.RefillBuffer (); + // end of file occurs if we couldn't extend the buffer + afterRefill (trans,sentinel,lexBuffer,scanUntilSentinel,lexBuffer.EndOfScan,state,256 (* == EOF *) ) + else + // read a character - end the scan if there are no further transitions + let inp = int(lexBuffer.Buffer.[lexBuffer.BufferScanPos]) + let snew = int trans.[state].[inp] + if snew = sentinel then + lexBuffer.EndOfScan() + else + lexBuffer.BufferScanLength <- lexBuffer.BufferScanLength + 1; + // Printf.printf "state %d --> %d on '%c' (%d)\n" state snew (Char.chr inp) inp; + scanUntilSentinel(lexBuffer, snew) + + /// Interpret tables for an ascii lexer generated by fslex. + member tables.Interpret(initialState,lexBuffer : LexBuffer) = + startInterpret(lexBuffer) + scanUntilSentinel(lexBuffer, initialState) + + /// Interpret tables for an ascii lexer generated by fslex. + member tables.AsyncInterpret(initialState,lexBuffer : LexBuffer) = + + let rec scanUntilSentinel(lexBuffer,state) : Async = + async { + let sentinel = 255 * 256 + 255 + // Return an endOfScan after consuming the input + let a = int accept.[state] + if a <> sentinel then + onAccept (lexBuffer,a) + + if lexBuffer.BufferScanLength = lexBuffer.BufferMaxScanLength then + lexBuffer.DiscardInput(); + do! lexBuffer.AsyncRefillBuffer (); + // end of file occurs if we couldn't extend the buffer + return! afterRefill (trans,sentinel,lexBuffer,scanUntilSentinel,endOfScan,state,256 (* == EOF *) ) + else + // read a character - end the scan if there are no further transitions + let inp = int(lexBuffer.Buffer.[lexBuffer.BufferScanPos]) + let snew = int trans.[state].[inp] + if snew = sentinel then + return! endOfScan() + else + lexBuffer.BufferScanLength <- lexBuffer.BufferScanLength + 1; + return! scanUntilSentinel(lexBuffer,snew) + } + and endOfScan() = + async { return lexBuffer.EndOfScan() } + startInterpret(lexBuffer) + scanUntilSentinel(lexBuffer, initialState) + + + static member Create(trans,accept) = new AsciiTables(trans,accept) + + [] +#if INTERNALIZED_FSLEXYACC_RUNTIME + type internal UnicodeTables(trans: uint16[] array, accept: uint16[]) = +#else + type UnicodeTables(trans: uint16[] array, accept: uint16[]) = +#endif + let sentinel = 255 * 256 + 255 + let numUnicodeCategories = 30 + let numLowUnicodeChars = 128 + let numSpecificUnicodeChars = (trans.[0].Length - 1 - numLowUnicodeChars - numUnicodeCategories)/2 + let lookupUnicodeCharacters (state,inp) = + let inpAsInt = int inp + // Is it a fast ASCII character? + if inpAsInt < numLowUnicodeChars then + int trans.[state].[inpAsInt] + else + // Search for a specific unicode character + let baseForSpecificUnicodeChars = numLowUnicodeChars + let rec loop i = + if i >= numSpecificUnicodeChars then + // OK, if we failed then read the 'others' entry in the alphabet, + // which covers all Unicode characters not covered in other + // ways + let baseForUnicodeCategories = numLowUnicodeChars+numSpecificUnicodeChars*2 + let unicodeCategory = System.Globalization.CharUnicodeInfo.GetUnicodeCategory(inp) + //System.Console.WriteLine("inp = {0}, unicodeCategory = {1}", [| box inp; box unicodeCategory |]); + int trans.[state].[baseForUnicodeCategories + int32 unicodeCategory] + else + // This is the specific unicode character + let c = char (int trans.[state].[baseForSpecificUnicodeChars+i*2]) + //System.Console.WriteLine("c = {0}, inp = {1}, i = {2}", [| box c; box inp; box i |]); + // OK, have we found the entry for a specific unicode character? + if c = inp + then int trans.[state].[baseForSpecificUnicodeChars+i*2+1] + else loop(i+1) + + loop 0 + let eofPos = numLowUnicodeChars + 2*numSpecificUnicodeChars + numUnicodeCategories + + let rec scanUntilSentinel(lexBuffer,state) = + // Return an endOfScan after consuming the input + let a = int accept.[state] + if a <> sentinel then + onAccept(lexBuffer,a) + + if lexBuffer.BufferScanLength = lexBuffer.BufferMaxScanLength then + lexBuffer.DiscardInput(); + lexBuffer.RefillBuffer (); + // end of file occurs if we couldn't extend the buffer + afterRefill (trans,sentinel,lexBuffer,scanUntilSentinel,lexBuffer.EndOfScan,state,eofPos) + else + // read a character - end the scan if there are no further transitions + let inp = lexBuffer.Buffer.[lexBuffer.BufferScanPos] + + // Find the new state + let snew = lookupUnicodeCharacters (state,inp) + + if snew = sentinel then + lexBuffer.EndOfScan() + else + lexBuffer.BufferScanLength <- lexBuffer.BufferScanLength + 1; + // Printf.printf "state %d --> %d on '%c' (%d)\n" s snew (char inp) inp; + scanUntilSentinel(lexBuffer,snew) + + // Each row for the Unicode table has format + // 128 entries for ASCII characters + // A variable number of 2*UInt16 entries for SpecificUnicodeChars + // 30 entries, one for each UnicodeCategory + // 1 entry for EOF + + member tables.Interpret(initialState,lexBuffer : LexBuffer) = + startInterpret(lexBuffer) + scanUntilSentinel(lexBuffer, initialState) + + member tables.AsyncInterpret(initialState,lexBuffer : LexBuffer) = + + let rec scanUntilSentinel(lexBuffer, state) = + async { + // Return an endOfScan after consuming the input + let a = int accept.[state] + if a <> sentinel then + onAccept(lexBuffer,a) + + if lexBuffer.BufferScanLength = lexBuffer.BufferMaxScanLength then + lexBuffer.DiscardInput(); + lexBuffer.RefillBuffer (); + // end of file occurs if we couldn't extend the buffer + return! afterRefill (trans,sentinel,lexBuffer,scanUntilSentinel,endOfScan,state,eofPos) + else + // read a character - end the scan if there are no further transitions + let inp = lexBuffer.Buffer.[lexBuffer.BufferScanPos] + + // Find the new state + let snew = lookupUnicodeCharacters (state,inp) + + if snew = sentinel then + return! endOfScan() + else + lexBuffer.BufferScanLength <- lexBuffer.BufferScanLength + 1; + return! scanUntilSentinel(lexBuffer, snew) + } + and endOfScan() = + async { return lexBuffer.EndOfScan() } + startInterpret(lexBuffer) + scanUntilSentinel(lexBuffer, initialState) + + static member Create(trans,accept) = new UnicodeTables(trans,accept) diff --git a/src/buildtools/fslex/Lexing.fsi b/src/buildtools/fslex/Lexing.fsi new file mode 100644 index 0000000000..e31ad411aa --- /dev/null +++ b/src/buildtools/fslex/Lexing.fsi @@ -0,0 +1,151 @@ +//========================================================================== +// LexBuffers are for use with automatically generated lexical analyzers, +// in particular those produced by 'fslex'. +// +// (c) Microsoft Corporation 2005-2008. +//=========================================================================== + +#if INTERNALIZED_FSLEXYACC_RUNTIME +namespace Internal.Utilities.Text.Lexing +#else +namespace Microsoft.FSharp.Text.Lexing +#endif + +open System.Collections.Generic + +/// Position information stored for lexing tokens +// +// Note: this is an OCaml compat record type. +#if INTERNALIZED_FSLEXYACC_RUNTIME +type internal Position = +#else +type Position = +#endif + { /// The file name for the position + pos_fname: string; + /// The line number for the position + pos_lnum: int; +#if INTERNALIZED_FSLEXYACC_RUNTIME + /// The line number for the position in the original source file + pos_orig_lnum : int; +#endif + /// The absolute offset of the beginning of the line + pos_bol: int; + /// The absolute offset of the column for the position + pos_cnum: int; } + /// The file name associated with the input stream. + member FileName : string + /// The line number in the input stream, assuming fresh positions have been updated + /// using AsNewLinePos() and by modifying the EndPos property of the LexBuffer. + member Line : int +#if INTERNALIZED_FSLEXYACC_RUNTIME + /// The line number for the position in the input stream, assuming fresh positions have been updated + /// using AsNewLinePos() + member OriginalLine : int +#endif + [] + member Char : int + /// The character number in the input stream + member AbsoluteOffset : int + /// Return absolute offset of the start of the line marked by the position + member StartOfLineAbsoluteOffset : int + /// Return the column number marked by the position, i.e. the difference between the AbsoluteOffset and the StartOfLineAbsoluteOffset + member Column : int + // Given a position just beyond the end of a line, return a position at the start of the next line + member NextLine : Position + + /// Given a position at the start of a token of length n, return a position just beyond the end of the token + member EndOfToken: n:int -> Position + /// Gives a position shifted by specified number of characters + member ShiftColumnBy: by:int -> Position + + [] + member AsNewLinePos : unit -> Position + + /// Get an arbitrary position, with the empty string as filename, and + static member Empty : Position + + /// Get a position corresponding to the first line (line number 1) in a given file + static member FirstLine : filename:string -> Position + +[] +#if INTERNALIZED_FSLEXYACC_RUNTIME +type internal LexBuffer<'char> = +#else +/// Input buffers consumed by lexers generated by fslex.exe +type LexBuffer<'char> = +#endif + /// The start position for the lexeme + member StartPos: Position with get,set + /// The end position for the lexeme + member EndPos: Position with get,set + /// The matched string + member Lexeme: 'char array + + /// Fast helper to turn the matched characters into a string, avoiding an intermediate array + static member LexemeString : LexBuffer -> string + + /// The length of the matched string + member LexemeLength: int + /// Fetch a particular character in the matched string + member LexemeChar: int -> 'char + + /// Dynamically typed, non-lexically scoped parameter table + member BufferLocalStore : IDictionary + + /// True if the refill of the buffer ever failed , or if explicitly set to true. + member IsPastEndOfStream: bool with get,set + /// Remove all input, though don't discard the current lexeme + member DiscardInput: unit -> unit + + /// Create a lex buffer suitable for byte lexing that reads characters from the given array + static member FromBytes: byte[] -> LexBuffer + /// Create a lex buffer suitable for Unicode lexing that reads characters from the given array + static member FromChars: char[] -> LexBuffer + /// Create a lex buffer suitable for Unicode lexing that reads characters from the given string + static member FromString: string -> LexBuffer + /// Create a lex buffer that reads character or byte inputs by using the given function + static member FromFunction: ('char[] * int * int -> int) -> LexBuffer<'char> + /// Create a lex buffer that asynchronously reads character or byte inputs by using the given function + static member FromAsyncFunction: ('char[] * int * int -> Async) -> LexBuffer<'char> + + + [.FromFunction instead")>] + static member FromCharFunction: (char[] -> int -> int) -> LexBuffer + [.FromFunction instead")>] + static member FromByteFunction: (byte[] -> int -> int) -> LexBuffer + + /// Create a lex buffer suitable for use with a Unicode lexer that reads character inputs from the given text reader + static member FromTextReader: System.IO.TextReader -> LexBuffer + /// Create a lex buffer suitable for use with ASCII byte lexing that reads byte inputs from the given binary reader + static member FromBinaryReader: System.IO.BinaryReader -> LexBuffer + + +/// The type of tables for an ascii lexer generated by fslex. +[] +#if INTERNALIZED_FSLEXYACC_RUNTIME +type internal AsciiTables = +#else +type AsciiTables = +#endif + static member Create : uint16[] array * uint16[] -> AsciiTables + /// Interpret tables for an ascii lexer generated by fslex. + member Interpret: initialState:int * LexBuffer -> int + /// Interpret tables for an ascii lexer generated by fslex, processing input asynchronously + member AsyncInterpret: initialState:int * LexBuffer -> Async + + +/// The type of tables for an unicode lexer generated by fslex. +[] +#if INTERNALIZED_FSLEXYACC_RUNTIME +type internal UnicodeTables = +#else +type UnicodeTables = +#endif + static member Create : uint16[] array * uint16[] -> UnicodeTables + /// Interpret tables for a unicode lexer generated by fslex. + member Interpret: initialState:int * LexBuffer -> int + + /// Interpret tables for a unicode lexer generated by fslex, processing input asynchronously + member AsyncInterpret: initialState:int * LexBuffer -> Async + diff --git a/src/buildtools/fslex/Parsing.fs b/src/buildtools/fslex/Parsing.fs new file mode 100644 index 0000000000..01dccfb610 --- /dev/null +++ b/src/buildtools/fslex/Parsing.fs @@ -0,0 +1,514 @@ +// (c) Microsoft Corporation 2005-2009. + +#if INTERNALIZED_FSLEXYACC_RUNTIME + +namespace Internal.Utilities.Text.Parsing +open Internal.Utilities +open Internal.Utilities.Text.Lexing + +#else +namespace Microsoft.FSharp.Text.Parsing +open Microsoft.FSharp.Text.Lexing +#endif + + + +open System +open System.Collections.Generic + +#if INTERNALIZED_FSLEXYACC_RUNTIME +type internal IParseState = +#else +type IParseState = +#endif + abstract InputRange: int -> Position * Position + abstract InputEndPosition: int -> Position + abstract InputStartPosition: int -> Position + abstract ResultRange: Position * Position + abstract GetInput: int -> obj + abstract ParserLocalStore : IDictionary + abstract RaiseError<'b> : unit -> 'b + +//------------------------------------------------------------------------- +// This context is passed to the error reporter when a syntax error occurs + +[] +#if INTERNALIZED_FSLEXYACC_RUNTIME +type internal ParseErrorContext<'tok> +#else +type ParseErrorContext<'tok> +#endif + (//lexbuf: LexBuffer<_>, + stateStack:int list, + parseState: IParseState, + reduceTokens: int list, + currentToken: 'tok option, + reducibleProductions: int list list, + shiftableTokens: int list , + message : string) = + //member x.LexBuffer = lexbuf + member x.StateStack = stateStack + member x.ReduceTokens = reduceTokens + member x.CurrentToken = currentToken + member x.ParseState = parseState + member x.ReducibleProductions = reducibleProductions + member x.ShiftTokens = shiftableTokens + member x.Message = message + + +//------------------------------------------------------------------------- +// This is the data structure emitted as code by FSYACC. + +#if INTERNALIZED_FSLEXYACC_RUNTIME +type internal Tables<'tok> = +#else +type Tables<'tok> = +#endif + { reductions: (IParseState -> obj) array; + endOfInputTag: int; + tagOfToken: 'tok -> int; + dataOfToken: 'tok -> obj; + actionTableElements: uint16[]; + actionTableRowOffsets: uint16[]; + reductionSymbolCounts: uint16[]; + immediateActions: uint16[]; + gotos: uint16[]; + sparseGotoTableRowOffsets: uint16[]; + stateToProdIdxsTableElements: uint16[]; + stateToProdIdxsTableRowOffsets: uint16[]; + productionToNonTerminalTable: uint16[]; + /// For fsyacc.exe, this entry is filled in by context from the generated parser file. If no 'parse_error' function + /// is defined by the user then ParseHelpers.parse_error is used by default (ParseHelpers is opened + /// at the top of the generated parser file) + parseError: ParseErrorContext<'tok> -> unit; + numTerminals: int; + tagOfErrorTerminal: int } + +//------------------------------------------------------------------------- +// An implementation of stacks. + +// This type is in System.dll so for the moment we can't use it in FSharp.Core.dll +//type Stack<'a> = System.Collections.Generic.Stack<'a> + +#if INTERNALIZED_FSLEXYACC_RUNTIME +type Stack<'a>(n) = +#else +type internal Stack<'a>(n) = +#endif + let mutable contents = Array.zeroCreate<'a>(n) + let mutable count = 0 + + member buf.Ensure newSize = + let oldSize = Array.length contents + if newSize > oldSize then + let old = contents + contents <- Array.zeroCreate (max newSize (oldSize * 2)); + Array.blit old 0 contents 0 count; + + member buf.Count = count + member buf.Pop() = count <- count - 1 + member buf.Peep() = contents.[count - 1] + member buf.Top(n) = [ for x in contents.[max 0 (count-n)..count - 1] -> x ] |> List.rev + member buf.Push(x) = + buf.Ensure(count + 1); + contents.[count] <- x; + count <- count + 1 + + member buf.IsEmpty = (count = 0) +#if __DEBUG + member buf.PrintStack() = + for i = 0 to (count - 1) do +#if FX_NO_CONSOLE + () +#else + System.Console.Write("{0}{1}",(contents.[i]),if i=count-1 then ":" else "-") +#endif +#endif +exception RecoverableParseError +exception Accept of obj + +#if __DEBUG +module Flags = + let mutable debug = false +#endif + +#if INTERNALIZED_FSLEXYACC_RUNTIME +module internal Implementation = +#else +module Implementation = +#endif + + // Definitions shared with fsyacc + let anyMarker = 0xffff + let shiftFlag = 0x0000 + let reduceFlag = 0x4000 + let errorFlag = 0x8000 + let acceptFlag = 0xc000 + let actionMask = 0xc000 + + let actionValue action = action &&& (~~~ actionMask) + let actionKind action = action &&& actionMask + + //------------------------------------------------------------------------- + // Read the tables written by FSYACC. + + type AssocTable(elemTab:uint16[], offsetTab:uint16[]) = + let cache = new Dictionary<_,_>(2000) + + member t.readAssoc (minElemNum,maxElemNum,defaultValueOfAssoc,keyToFind) = + // do a binary chop on the table + let elemNumber : int = (minElemNum+maxElemNum)/2 + if elemNumber = maxElemNum + then defaultValueOfAssoc + else + let x = int elemTab.[elemNumber*2] + if keyToFind = x then + int elemTab.[elemNumber*2+1] + elif keyToFind < x then t.readAssoc (minElemNum ,elemNumber,defaultValueOfAssoc,keyToFind) + else t.readAssoc (elemNumber+1,maxElemNum,defaultValueOfAssoc,keyToFind) + + member t.Read(rowNumber ,keyToFind) = + + // First check the sparse lookaside table + // Performance note: without this lookaside table the binary chop in readAssoc + // takes up around 10% of of parsing time + // for parsing intensive samples such as the bootstrapped F# compiler. + // + // Note: using a .NET Dictionary for this int -> int table looks like it could be sub-optimal. + // Some other better sparse lookup table may be better. + let mutable res = 0 + let cacheKey = (rowNumber <<< 16) ||| keyToFind + let ok = cache.TryGetValue(cacheKey, &res) + if ok then res + else + let headOfTable = int offsetTab.[rowNumber] + let firstElemNumber = headOfTable + 1 + let numberOfElementsInAssoc = int elemTab.[headOfTable*2] + let defaultValueOfAssoc = int elemTab.[headOfTable*2+1] + let res = t.readAssoc (firstElemNumber,(firstElemNumber+numberOfElementsInAssoc),defaultValueOfAssoc,keyToFind) + cache.[cacheKey] <- res + res + + // Read all entries in the association table + // Used during error recovery to find all valid entries in the table + member x.ReadAll(n) = + let headOfTable = int offsetTab.[n] + let firstElemNumber = headOfTable + 1 + let numberOfElementsInAssoc = int32 elemTab.[headOfTable*2] + let defaultValueOfAssoc = int elemTab.[headOfTable*2+1] + [ for i in firstElemNumber .. (firstElemNumber+numberOfElementsInAssoc-1) -> + (int elemTab.[i*2], int elemTab.[i*2+1]) ], defaultValueOfAssoc + + type IdxToIdxListTable(elemTab:uint16[], offsetTab:uint16[]) = + + // Read all entries in a row of the table + member x.ReadAll(n) = + let headOfTable = int offsetTab.[n] + let firstElemNumber = headOfTable + 1 + let numberOfElements = int32 elemTab.[headOfTable] + [ for i in firstElemNumber .. (firstElemNumber+numberOfElements-1) -> int elemTab.[i] ] + + //------------------------------------------------------------------------- + // interpret the tables emitted by FSYACC. + + [] + [] + type ValueInfo = + val value: obj + val startPos: Position + val endPos: Position + new(value,startPos,endPos) = { value=value; startPos=startPos;endPos=endPos } + + let interpret (tables: Tables<'tok>) lexer (lexbuf : LexBuffer<_>) initialState = + let localStore = new Dictionary() in + localStore.["LexBuffer"] <- lexbuf; +#if __DEBUG + if Flags.debug then System.Console.WriteLine("\nParser: interpret tables"); +#endif + let stateStack : Stack = new Stack<_>(100) + stateStack.Push(initialState); + let valueStack = new Stack(100) + let mutable haveLookahead = false + let mutable lookaheadToken = Unchecked.defaultof<'tok> + let mutable lookaheadEndPos = Unchecked.defaultof + let mutable lookaheadStartPos = Unchecked.defaultof + let mutable finished = false + // After an error occurs, we suppress errors until we've shifted three tokens in a row. + let mutable errorSuppressionCountDown = 0 + + // When we hit the end-of-file we don't fail straight away but rather keep permitting shift + // and reduce against the last token in the token stream 20 times or until we've accepted + // or exhausted the stack. This allows error recovery rules of the form + // input : realInput EOF | realInput error EOF | error EOF + // where consuming one EOF to trigger an error doesn't result in overall parse failure + // catastrophe and the loss of intermediate results. + // + let mutable inEofCountDown = false + let mutable eofCountDown = 20 // Number of EOFs to supply at the end for error recovery + // The 100 here means a maximum of 100 elements for each rule + let ruleStartPoss = (Array.zeroCreate 100 : Position array) + let ruleEndPoss = (Array.zeroCreate 100 : Position array) + let ruleValues = (Array.zeroCreate 100 : obj array) + let lhsPos = (Array.zeroCreate 2 : Position array) + let reductions = tables.reductions + let actionTable = new AssocTable(tables.actionTableElements, tables.actionTableRowOffsets) + let gotoTable = new AssocTable(tables.gotos, tables.sparseGotoTableRowOffsets) + let stateToProdIdxsTable = new IdxToIdxListTable(tables.stateToProdIdxsTableElements, tables.stateToProdIdxsTableRowOffsets) + + let parseState = + { new IParseState with + member p.InputRange(n) = ruleStartPoss.[n-1], ruleEndPoss.[n-1]; + member p.InputStartPosition(n) = ruleStartPoss.[n-1] + member p.InputEndPosition(n) = ruleEndPoss.[n-1]; + member p.GetInput(n) = ruleValues.[n-1]; + member p.ResultRange = (lhsPos.[0], lhsPos.[1]); + member p.ParserLocalStore = (localStore :> IDictionary<_,_>); + member p.RaiseError() = raise RecoverableParseError (* NOTE: this binding tests the fairly complex logic associated with an object expression implementing a generic abstract method *) + } + +#if __DEBUG + let report haveLookahead lookaheadToken = + if haveLookahead then sprintf "%A" lookaheadToken + else "[TBC]" +#endif + + // Pop the stack until we can shift the 'error' token. If 'tokenOpt' is given + // then keep popping until we can shift both the 'error' token and the token in 'tokenOpt'. + // This is used at end-of-file to make sure we can shift both the 'error' token and the 'EOF' token. + let rec popStackUntilErrorShifted(tokenOpt) = + // Keep popping the stack until the "error" terminal is shifted +#if __DEBUG + if Flags.debug then System.Console.WriteLine("popStackUntilErrorShifted"); +#endif + if stateStack.IsEmpty then +#if __DEBUG + if Flags.debug then + System.Console.WriteLine("state stack empty during error recovery - generating parse error"); +#endif + failwith "parse error"; + + let currState = stateStack.Peep() +#if __DEBUG + if Flags.debug then + System.Console.WriteLine("In state {0} during error recovery", currState); +#endif + + let action = actionTable.Read(currState, tables.tagOfErrorTerminal) + + if actionKind action = shiftFlag && + (match tokenOpt with + | None -> true + | Some(token) -> + let nextState = actionValue action + actionKind (actionTable.Read(nextState, tables.tagOfToken(token))) = shiftFlag) then + +#if __DEBUG + if Flags.debug then System.Console.WriteLine("shifting error, continuing with error recovery"); +#endif + let nextState = actionValue action + // The "error" non terminal needs position information, though it tends to be unreliable. + // Use the StartPos/EndPos from the lex buffer + valueStack.Push(ValueInfo(box (), lexbuf.StartPos, lexbuf.EndPos)); + stateStack.Push(nextState) + else + if valueStack.IsEmpty then + failwith "parse error"; +#if __DEBUG + if Flags.debug then + System.Console.WriteLine("popping stack during error recovery"); +#endif + valueStack.Pop(); + stateStack.Pop(); + popStackUntilErrorShifted(tokenOpt) + + while not finished do + if stateStack.IsEmpty then + finished <- true + else + let state = stateStack.Peep() +#if __DEBUG + if Flags.debug then (Console.Write("{0} value(state), state ",valueStack.Count); stateStack.PrintStack()) +#endif + let action = + let immediateAction = int tables.immediateActions.[state] + if not (immediateAction = anyMarker) then + // Action has been pre-determined, no need to lookahead + // Expecting it to be a Reduce action on a non-fakeStartNonTerminal ? + immediateAction + else + // Lookahead required to determine action + if not haveLookahead then + if lexbuf.IsPastEndOfStream then + // When the input runs out, keep supplying the last token for eofCountDown times + if eofCountDown>0 then + haveLookahead <- true + eofCountDown <- eofCountDown - 1 + inEofCountDown <- true + else + haveLookahead <- false + else + lookaheadToken <- lexer lexbuf + lookaheadStartPos <- lexbuf.StartPos + lookaheadEndPos <- lexbuf.EndPos + haveLookahead <- true; + + let tag = + if haveLookahead then tables.tagOfToken lookaheadToken + else tables.endOfInputTag + + // Printf.printf "state %d\n" state + actionTable.Read(state,tag) + + let kind = actionKind action + if kind = shiftFlag then ( + if errorSuppressionCountDown > 0 then + errorSuppressionCountDown <- errorSuppressionCountDown - 1; +#if __DEBUG + if Flags.debug then Console.WriteLine("shifting, reduced errorRecoverylevel to {0}\n", errorSuppressionCountDown); +#endif + let nextState = actionValue action + if not haveLookahead then failwith "shift on end of input!"; + let data = tables.dataOfToken lookaheadToken + valueStack.Push(ValueInfo(data, lookaheadStartPos, lookaheadEndPos)); + stateStack.Push(nextState); +#if __DEBUG + if Flags.debug then Console.WriteLine("shift/consume input {0}, shift to state {1}", report haveLookahead lookaheadToken, nextState); +#endif + haveLookahead <- false + + ) elif kind = reduceFlag then + let prod = actionValue action + let reduction = reductions.[prod] + let n = int tables.reductionSymbolCounts.[prod] + // pop the symbols, populate the values and populate the locations +#if __DEBUG + if Flags.debug then Console.Write("reduce popping {0} values/states, lookahead {1}", n, report haveLookahead lookaheadToken); +#endif + + lhsPos.[0] <- Position.Empty; + lhsPos.[1] <- Position.Empty; + for i = 0 to n - 1 do + if valueStack.IsEmpty then failwith "empty symbol stack"; + let topVal = valueStack.Peep() + valueStack.Pop(); + stateStack.Pop(); + ruleValues.[(n-i)-1] <- topVal.value; + ruleStartPoss.[(n-i)-1] <- topVal.startPos; + ruleEndPoss.[(n-i)-1] <- topVal.endPos; + if lhsPos.[1] = Position.Empty then lhsPos.[1] <- topVal.endPos; + if not (topVal.startPos = Position.Empty) then lhsPos.[0] <- topVal.startPos + done; + + try + // Printf.printf "reduce %d\n" prod; + let redResult = reduction parseState + valueStack.Push(ValueInfo(redResult, lhsPos.[0], lhsPos.[1])); + let currState = stateStack.Peep() + let newGotoState = gotoTable.Read(int tables.productionToNonTerminalTable.[prod], currState) + stateStack.Push(newGotoState) +#if __DEBUG + if Flags.debug then Console.WriteLine(" goto state {0}", newGotoState) +#endif + with + | Accept res -> + finished <- true; + valueStack.Push(ValueInfo(res, lhsPos.[0], lhsPos.[1])) + | RecoverableParseError -> +#if __DEBUG + if Flags.debug then Console.WriteLine("RecoverableParseErrorException...\n"); +#endif + popStackUntilErrorShifted(None); + // User code raised a Parse_error. Don't report errors again until three tokens have been shifted + errorSuppressionCountDown <- 3 + elif kind = errorFlag then ( +#if __DEBUG + if Flags.debug then Console.Write("ErrorFlag... "); +#endif + // Silently discard inputs and don't report errors + // until three tokens in a row have been shifted +#if __DEBUG + if Flags.debug then printfn "error on token '%A' " (if haveLookahead then Some(lookaheadToken) else None); +#endif + if errorSuppressionCountDown > 0 then + // If we're in the end-of-file count down then we're very keen to 'Accept'. + // We can only do this by repeatedly popping the stack until we can shift both an 'error' token + // and an EOF token. + if inEofCountDown && eofCountDown < 10 then +#if __DEBUG + if Flags.debug then printfn "poppin stack, lokking to shift both 'error' and that token, during end-of-file error recovery" ; +#endif + popStackUntilErrorShifted(if haveLookahead then Some(lookaheadToken) else None); + + // If we don't haveLookahead then the end-of-file count down is over and we have no further options. + if not haveLookahead then + failwith "parse error: unexpected end of file" + +#if __DEBUG + if Flags.debug then printfn "discarding token '%A' during error suppression" (if haveLookahead then Some(lookaheadToken) else None); +#endif + // Discard the token + haveLookahead <- false + // Try again to shift three tokens + errorSuppressionCountDown <- 3 + else ( + + let currentToken = if haveLookahead then Some(lookaheadToken) else None + let actions,defaultAction = actionTable.ReadAll(state) + let explicit = Set.ofList [ for (tag,_action) in actions -> tag ] + + let shiftableTokens = + [ for (tag,action) in actions do + if (actionKind action) = shiftFlag then + yield tag + if actionKind defaultAction = shiftFlag then + for tag in 0 .. tables.numTerminals-1 do + if not (explicit.Contains(tag)) then + yield tag ] in + + let stateStack = stateStack.Top(12) in + let reducibleProductions = + [ for state in stateStack do + yield stateToProdIdxsTable.ReadAll(state) ] + + let reduceTokens = + [ for (tag,action) in actions do + if actionKind(action) = reduceFlag then + yield tag + if actionKind(defaultAction) = reduceFlag then + for tag in 0 .. tables.numTerminals-1 do + if not (explicit.Contains(tag)) then + yield tag ] in + //let activeRules = stateStack |> List.iter (fun state -> + let errorContext = new ParseErrorContext<'tok>(stateStack,parseState, reduceTokens,currentToken,reducibleProductions, shiftableTokens, "syntax error") + tables.parseError(errorContext); + popStackUntilErrorShifted(None); + errorSuppressionCountDown <- 3; +#if __DEBUG + if Flags.debug then System.Console.WriteLine("generated syntax error and shifted error token, haveLookahead = {0}\n", haveLookahead); +#endif + ) + ) elif kind = acceptFlag then + finished <- true +#if __DEBUG + else + if Flags.debug then System.Console.WriteLine("ALARM!!! drop through case in parser"); +#endif + done; + // OK, we're done - read off the overall generated value + valueStack.Peep().value + +#if INTERNALIZED_FSLEXYACC_RUNTIME +type internal Tables<'tok> with +#else +type Tables<'tok> with +#endif + member tables.Interpret (lexer,lexbuf,initialState) = + Implementation.interpret tables lexer lexbuf initialState + +#if INTERNALIZED_FSLEXYACC_RUNTIME +module internal ParseHelpers = +#else +module ParseHelpers = +#endif + let parse_error (_s:string) = () + let parse_error_rich = (None : (ParseErrorContext<_> -> unit) option) diff --git a/src/buildtools/fslex/Parsing.fsi b/src/buildtools/fslex/Parsing.fsi new file mode 100644 index 0000000000..2fef45975a --- /dev/null +++ b/src/buildtools/fslex/Parsing.fsi @@ -0,0 +1,130 @@ +//========================================================================== +// (c) Microsoft Corporation 2005-2009. +//========================================================================= + +#if INTERNALIZED_FSLEXYACC_RUNTIME +namespace Internal.Utilities.Text.Parsing +open Internal.Utilities +open Internal.Utilities.Text.Lexing +#else +namespace Microsoft.FSharp.Text.Parsing +open Microsoft.FSharp.Text.Lexing +#endif + +open System.Collections.Generic + +#if INTERNALIZED_FSLEXYACC_RUNTIME +type internal IParseState = +#else +/// The information accessible via the parseState value within parser actions. +type IParseState = +#endif + /// Get the start and end position for the terminal or non-terminal at a given index matched by the production + abstract InputRange: index:int -> Position * Position + /// Get the end position for the terminal or non-terminal at a given index matched by the production + abstract InputEndPosition: int -> Position + /// Get the start position for the terminal or non-terminal at a given index matched by the production + abstract InputStartPosition: int -> Position + /// Get the full range of positions matched by the production + abstract ResultRange: Position * Position + /// Get the value produced by the terminal or non-terminal at the given position + abstract GetInput : int -> obj + /// Get the store of local values associated with this parser + // Dynamically typed, non-lexically scoped local store + abstract ParserLocalStore : IDictionary + /// Raise an error in this parse context + abstract RaiseError<'b> : unit -> 'b + + +[] +#if INTERNALIZED_FSLEXYACC_RUNTIME +type internal ParseErrorContext<'tok> = +#else +/// The context provided when a parse error occurs +type ParseErrorContext<'tok> = +#endif + /// The stack of state indexes active at the parse error + member StateStack : int list + /// The state active at the parse error + member ParseState : IParseState + /// The tokens that would cause a reduction at the parse error + member ReduceTokens: int list + /// The stack of productions that would be reduced at the parse error + member ReducibleProductions : int list list + /// The token that caused the parse error + member CurrentToken : 'tok option + /// The token that would cause a shift at the parse error + member ShiftTokens : int list + /// The message associated with the parse error + member Message : string + +/// Tables generated by fsyacc +#if INTERNALIZED_FSLEXYACC_RUNTIME +type internal Tables<'tok> = +#else +/// The type of the tables contained in a file produced by the fsyacc.exe parser generator. +type Tables<'tok> = +#endif + { /// The reduction table + reductions: (IParseState -> obj) array ; + /// The token number indicating the end of input + endOfInputTag: int; + /// A function to compute the tag of a token + tagOfToken: 'tok -> int; + /// A function to compute the data carried by a token + dataOfToken: 'tok -> obj; + /// The sparse action table elements + actionTableElements: uint16[]; + /// The sparse action table row offsets + actionTableRowOffsets: uint16[]; + /// The number of symbols for each reduction + reductionSymbolCounts: uint16[]; + /// The immediate action table + immediateActions: uint16[]; + /// The sparse goto table + gotos: uint16[]; + /// The sparse goto table row offsets + sparseGotoTableRowOffsets: uint16[]; + /// The sparse table for the productions active for each state + stateToProdIdxsTableElements: uint16[]; + /// The sparse table offsets for the productions active for each state + stateToProdIdxsTableRowOffsets: uint16[]; + /// This table is logically part of the Goto table + productionToNonTerminalTable: uint16[]; + /// This function is used to hold the user specified "parse_error" or "parse_error_rich" functions + parseError: ParseErrorContext<'tok> -> unit; + /// The total number of terminals + numTerminals: int; + /// The tag of the error terminal + tagOfErrorTerminal: int } + + /// 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 + +#if INTERNALIZED_FSLEXYACC_RUNTIME +exception internal Accept of obj +exception internal RecoverableParseError +#else +/// Indicates an accept action has occured +exception Accept of obj +/// Indicates a parse error has occured and parse recovery is in progress +exception RecoverableParseError +#endif + +#if __DEBUG +module internal Flags = + val mutable debug : bool +#endif + +#if INTERNALIZED_FSLEXYACC_RUNTIME +module internal ParseHelpers = +#else +/// Helpers used by generated parsers. +module ParseHelpers = +#endif + /// The default implementation of the parse_error_rich function + val parse_error_rich: (ParseErrorContext<'tok> -> unit) option + /// The default implementation of the parse_error function + val parse_error: string -> unit + diff --git a/src/buildtools/fslex/fslex.fs b/src/buildtools/fslex/fslex.fs new file mode 100644 index 0000000000..d2f1af826b --- /dev/null +++ b/src/buildtools/fslex/fslex.fs @@ -0,0 +1,224 @@ +// (c) Microsoft Corporation 2005-2009. + +module internal FsLexYacc.FsLex.Driver + +open FsLexYacc.FsLex +open FsLexYacc.FsLex.AST +open FsLexYacc.FsLex.Parser +open Printf +open Internal.Utilities +open Internal.Utilities.Text.Lexing +open System +open System.Collections.Generic +open System.IO + +//------------------------------------------------------------------ +// This code is duplicated from Microsoft.FSharp.Compiler.UnicodeLexing + +type Lexbuf = LexBuffer + +/// Standard utility to create a Unicode LexBuffer +/// +/// One small annoyance is that LexBuffers and not IDisposable. This means +/// we can't just return the LexBuffer object, since the file it wraps wouldn't +/// get closed when we're finished with the LexBuffer. Hence we return the stream, +/// the reader and the LexBuffer. The caller should dispose the first two when done. +let UnicodeFileAsLexbuf (filename,codePage : int option) : FileStream * StreamReader * Lexbuf = + // Use the .NET functionality to auto-detect the unicode encoding + // It also presents the bytes read to the lexer in UTF8 decoded form + let stream = new FileStream(filename,FileMode.Open,FileAccess.Read,FileShare.Read) + let reader = + match codePage with + | None -> new StreamReader(stream,true) + | Some n -> new StreamReader(stream,System.Text.Encoding.GetEncoding(n)) + let lexbuf = LexBuffer.FromFunction(reader.Read) + lexbuf.EndPos <- Position.FirstLine(filename); + stream, reader, lexbuf + +//------------------------------------------------------------------ +// This is the program proper + +let input = ref None +let out = ref None +let inputCodePage = ref None +let light = ref None + +let mutable lexlib = "Microsoft.FSharp.Text.Lexing" + +let usage = + [ ArgInfo ("-o", ArgType.String (fun s -> out := Some s), "Name the output file."); + ArgInfo ("--codepage", ArgType.Int (fun i -> inputCodePage := Some i), "Assume input lexer specification file is encoded with the given codepage."); + ArgInfo ("--light", ArgType.Unit (fun () -> light := Some true), "(ignored)"); + ArgInfo ("--light-off", ArgType.Unit (fun () -> light := Some false), "Add #light \"off\" to the top of the generated file"); + ArgInfo ("--lexlib", ArgType.String (fun s -> lexlib <- s), "Specify the namespace for the implementation of the lexer table interpreter (default Microsoft.FSharp.Text.Lexing)"); + ArgInfo ("--unicode", ArgType.Set unicode, "Produce a lexer for use with 16-bit unicode characters."); + ] + +let _ = ArgParser.Parse(usage, (fun x -> match !input with Some _ -> failwith "more than one input given" | None -> input := Some x), "fslex ") + +let outputInt (os: TextWriter) (n:int) = os.Write(string n) + +let outputCodedUInt16 (os: #TextWriter) (n:int) = + os.Write n; + os.Write "us; "; + +let sentinel = 255 * 256 + 255 + +let lineCount = ref 0 +let cfprintfn (os: #TextWriter) fmt = Printf.kfprintf (fun () -> incr lineCount; os.WriteLine()) os fmt + +[] +let main(args: string[]) = + try + let filename = (match !input with Some x -> x | None -> failwith "no input given") + let domain = if !unicode then "Unicode" else "Ascii" + let spec = + let stream,reader,lexbuf = UnicodeFileAsLexbuf(filename, !inputCodePage) + use stream = stream + use reader = reader + try + Parser.spec Lexer.token lexbuf + with e -> + eprintf "%s(%d,%d): error: %s" filename lexbuf.StartPos.Line lexbuf.StartPos.Column + (match e with + | Failure s -> s + | _ -> e.Message); + exit 1 + printfn "compiling to dfas (can take a while...)"; + let perRuleData, dfaNodes = AST.Compile spec + let dfaNodes = dfaNodes |> List.sortBy (fun n -> n.Id) + + printfn "%d states" dfaNodes.Length; + printfn "writing output"; + + let output = + match !out with + | Some x -> x + | _ -> + Path.Combine (Path.GetDirectoryName filename,Path.GetFileNameWithoutExtension(filename)) + ".fs" + use os = System.IO.File.CreateText output + + if (!light = Some(false)) || (!light = None && (Path.HasExtension(output) && Path.GetExtension(output) = ".ml")) then + cfprintfn os "#light \"off\""; + + let printLinesIfCodeDefined (code,pos:Position) = + if pos <> Position.Empty // If bottom code is unspecified, then position is empty. + then + cfprintfn os "# %d \"%s\"" pos.Line pos.FileName; + cfprintfn os "%s" code; + + printLinesIfCodeDefined spec.TopCode + let code = fst spec.TopCode + lineCount := !lineCount + code.Replace("\r","").Split([| '\n' |]).Length; + cfprintfn os "# %d \"%s\"" !lineCount output; + + cfprintfn os "let trans : uint16[] array = "; + cfprintfn os " [| "; + if !unicode then + let specificUnicodeChars = GetSpecificUnicodeChars() + // This emits a (numLowUnicodeChars+NumUnicodeCategories+(2*#specificUnicodeChars)+1) * #states array of encoded UInt16 values + + // Each row for the Unicode table has format + // 128 entries for ASCII characters + // A variable number of 2*UInt16 entries for SpecificUnicodeChars + // 30 entries, one for each UnicodeCategory + // 1 entry for EOF + // + // Each entry is an encoded UInt16 value indicating the next state to transition to for this input. + // + // For the SpecificUnicodeChars the entries are char/next-state pairs. + for state in dfaNodes do + cfprintfn os " (* State %d *)" state.Id; + fprintf os " [| "; + let trans = + let dict = new Dictionary<_,_>() + state.Transitions |> List.iter dict.Add + dict + let emit n = + if trans.ContainsKey(n) then + outputCodedUInt16 os trans.[n].Id + else + outputCodedUInt16 os sentinel + for i = 0 to numLowUnicodeChars-1 do + let c = char i + emit (EncodeChar c); + for c in specificUnicodeChars do + outputCodedUInt16 os (int c); + emit (EncodeChar c); + for i = 0 to NumUnicodeCategories-1 do + emit (EncodeUnicodeCategoryIndex i); + emit Eof; + cfprintfn os "|];" + done; + + else + // Each row for the ASCII table has format + // 256 entries for ASCII characters + // 1 entry for EOF + // + // Each entry is an encoded UInt16 value indicating the next state to transition to for this input. + + // This emits a (256+1) * #states array of encoded UInt16 values + for state in dfaNodes do + cfprintfn os " (* State %d *)" state.Id; + fprintf os " [|"; + let trans = + let dict = new Dictionary<_,_>() + state.Transitions |> List.iter dict.Add + dict + let emit n = + if trans.ContainsKey(n) then + outputCodedUInt16 os trans.[n].Id + else + outputCodedUInt16 os sentinel + for i = 0 to 255 do + let c = char i + emit (EncodeChar c); + emit Eof; + cfprintfn os "|];" + done; + + cfprintfn os " |] "; + + fprintf os "let actions : uint16[] = [|"; + for state in dfaNodes do + if state.Accepted.Length > 0 then + outputCodedUInt16 os (snd state.Accepted.Head) + else + outputCodedUInt16 os sentinel + done; + cfprintfn os "|]"; + cfprintfn os "let _fslex_tables = %s.%sTables.Create(trans,actions)" lexlib domain; + + cfprintfn os "let rec _fslex_dummy () = _fslex_dummy() "; + + // These actions push the additional start state and come first, because they are then typically inlined into later + // rules. This means more tailcalls are taken as direct branches, increasing efficiency and + // improving stack usage on platforms that do not take tailcalls. + for ((startNode, actions),(ident,args,_)) in List.zip perRuleData spec.Rules do + cfprintfn os "(* Rule %s *)" ident; + cfprintfn os "and %s %s (lexbuf : %s.LexBuffer<_>) = _fslex_%s %s %d lexbuf" ident (String.Join(" ",Array.ofList args)) lexlib ident (String.Join(" ",Array.ofList args)) startNode.Id; + for ((startNode, actions),(ident,args,_)) in List.zip perRuleData spec.Rules do + cfprintfn os "(* Rule %s *)" ident; + cfprintfn os "and _fslex_%s %s _fslex_state lexbuf =" ident (String.Join(" ",Array.ofList args)); + cfprintfn os " match _fslex_tables.Interpret(_fslex_state,lexbuf) with" ; + actions |> Seq.iteri (fun i (code,pos) -> + cfprintfn os " | %d -> ( " i; + cfprintfn os "# %d \"%s\"" pos.Line pos.FileName; + let lines = code.Split([| '\r'; '\n' |], StringSplitOptions.RemoveEmptyEntries) + for line in lines do + cfprintfn os " %s" line; + cfprintfn os "# %d \"%s\"" !lineCount output; + cfprintfn os " )") + cfprintfn os " | _ -> failwith \"%s\"" ident + + + cfprintfn os ""; + + printLinesIfCodeDefined spec.BottomCode + cfprintfn os "# 3000000 \"%s\"" output; + 0 + + with e -> + eprintf "FSLEX: error FSL000: %s" (match e with Failure s -> s | e -> e.ToString()); + exit 1 diff --git a/src/buildtools/fslex/fslex.fsproj b/src/buildtools/fslex/fslex.fsproj new file mode 100644 index 0000000000..9e21a860d8 --- /dev/null +++ b/src/buildtools/fslex/fslex.fsproj @@ -0,0 +1,22 @@ + + + + Exe + netcoreapp2.0 + INTERNALIZED_FSLEXYACC_RUNTIME;$(DefineConstant) + + + + + + + + + + + + + + + + diff --git a/src/buildtools/fslex/fslexast.fs b/src/buildtools/fslex/fslexast.fs new file mode 100644 index 0000000000..db9727cb97 --- /dev/null +++ b/src/buildtools/fslex/fslexast.fs @@ -0,0 +1,409 @@ +(* (c) Microsoft Corporation 2005-2008. *) + +module internal FsLexYacc.FsLex.AST + +open System.Collections.Generic +open Microsoft.FSharp.Text +open Microsoft.FSharp.Collections +open Internal.Utilities +open Internal.Utilities.Text.Lexing + +let (|KeyValue|) (kvp:KeyValuePair<_,_>) = kvp.Key,kvp.Value + +type Ident = string +type Code = string * Position + +type Alphabet = uint32 + +let Eof : Alphabet = 0xFFFFFFFEu +let Epsilon : Alphabet = 0xFFFFFFFFu + + +let unicode = ref false + +let unicodeCategories = + dict + [| "Pe", System.Globalization.UnicodeCategory.ClosePunctuation; // (Pe) + "Pc", System.Globalization.UnicodeCategory.ConnectorPunctuation; // (Pc) + "Cc", System.Globalization.UnicodeCategory.Control; // (Cc) + "Sc", System.Globalization.UnicodeCategory.CurrencySymbol; // (Sc) + "Pd", System.Globalization.UnicodeCategory.DashPunctuation; // (Pd) + "Nd", System.Globalization.UnicodeCategory.DecimalDigitNumber; // (Nd) + "Me", System.Globalization.UnicodeCategory.EnclosingMark; // (Me) + "Pf", System.Globalization.UnicodeCategory.FinalQuotePunctuation; // (Pf) + "Cf", enum 15; //System.Globalization.UnicodeCategory.Format; // (Cf) + "Pi", System.Globalization.UnicodeCategory.InitialQuotePunctuation; // (Pi) + "Nl", System.Globalization.UnicodeCategory.LetterNumber; // (Nl) + "Zl", System.Globalization.UnicodeCategory.LineSeparator; // (Zl) + "Ll", System.Globalization.UnicodeCategory.LowercaseLetter; // (Ll) + "Sm", System.Globalization.UnicodeCategory.MathSymbol; // (Sm) + "Lm", System.Globalization.UnicodeCategory.ModifierLetter; // (Lm) + "Sk", System.Globalization.UnicodeCategory.ModifierSymbol; // (Sk) + "Mn", System.Globalization.UnicodeCategory.NonSpacingMark; // (Mn) + "Ps", System.Globalization.UnicodeCategory.OpenPunctuation; // (Ps) + "Lo", System.Globalization.UnicodeCategory.OtherLetter; // (Lo) + "Cn", System.Globalization.UnicodeCategory.OtherNotAssigned; // (Cn) + "No", System.Globalization.UnicodeCategory.OtherNumber; // (No) + "Po", System.Globalization.UnicodeCategory.OtherPunctuation; // (Po) + "So", System.Globalization.UnicodeCategory.OtherSymbol; // (So) + "Zp", System.Globalization.UnicodeCategory.ParagraphSeparator; // (Zp) + "Co", System.Globalization.UnicodeCategory.PrivateUse; // (Co) + "Zs", System.Globalization.UnicodeCategory.SpaceSeparator; // (Zs) + "Mc", System.Globalization.UnicodeCategory.SpacingCombiningMark; // (Mc) + "Cs", System.Globalization.UnicodeCategory.Surrogate; // (Cs) + "Lt", System.Globalization.UnicodeCategory.TitlecaseLetter; // (Lt) + "Lu", System.Globalization.UnicodeCategory.UppercaseLetter; // (Lu) + |] + +let NumUnicodeCategories = unicodeCategories.Count +let _ = assert (NumUnicodeCategories = 30) // see table interpreter +let encodedUnicodeCategoryBase = 0xFFFFFF00u +let EncodeUnicodeCategoryIndex(idx:int) = encodedUnicodeCategoryBase + uint32 idx +let EncodeUnicodeCategory(s:string) = + if not (!unicode) then + failwith "unicode category classes may only be used if --unicode is specified"; + if unicodeCategories.ContainsKey(s) then + EncodeUnicodeCategoryIndex (int32 unicodeCategories.[s]) + else + failwithf "invalid Unicode category: '%s'" s + +let IsUnicodeCategory(x:Alphabet) = (encodedUnicodeCategoryBase <= x) && (x < encodedUnicodeCategoryBase + uint32 NumUnicodeCategories) +let UnicodeCategoryIndex(x:Alphabet) = (x - encodedUnicodeCategoryBase) + +let numLowUnicodeChars = 128 +let _ = assert (numLowUnicodeChars = 128) // see table interpreter +let specificUnicodeChars = new Dictionary<_,_>() +let specificUnicodeCharsDecode = new Dictionary<_,_>() +let EncodeChar(c:char) = + let x = System.Convert.ToUInt32 c + if !unicode then + if x < uint32 numLowUnicodeChars then x + else + if not(specificUnicodeChars.ContainsKey(c)) then + let idx = uint32 numLowUnicodeChars + uint32 specificUnicodeChars.Count + specificUnicodeChars.[c] <- idx + specificUnicodeCharsDecode.[idx] <- c + specificUnicodeChars.[c] + else + if x >= 256u then failwithf "the Unicode character '%c' may not be used unless --unicode is specified" c; + x +let DecodeChar(x:Alphabet) = + if !unicode then + if x < uint32 numLowUnicodeChars then System.Convert.ToChar x + else specificUnicodeCharsDecode.[x] + else + if x >= 256u then failwithf "the Unicode character '%x' may not be used unless --unicode is specified" x; + System.Convert.ToChar x + + + +let NumSpecificUnicodeChars() = specificUnicodeChars.Count +let GetSpecificUnicodeChars() = + specificUnicodeChars + |> Seq.sortBy (fun (KeyValue(k,v)) -> v) + |> Seq.map (fun (KeyValue(k,v)) -> k) + +let GetSingleCharAlphabet() = + if !unicode + then Set.ofList [ for c in 0..numLowUnicodeChars-1 do yield (char c) + for c in GetSpecificUnicodeChars() do yield c ] + else Set.ofList [ for x in 0..255 -> (char x) ] + +let GetAlphabet() = + if !unicode + then Set.ofList [ for c in GetSingleCharAlphabet() do yield EncodeChar c + for uc in 0 .. NumUnicodeCategories-1 do yield EncodeUnicodeCategoryIndex uc ] + else Set.ofList [ for c in GetSingleCharAlphabet() do yield EncodeChar c ] + + +//let DecodeAlphabet (x:Alphabet) = System.Convert.ToChar(x) + +(* +for i in 0 .. 65535 do + let c = char i + if System.Char.GetUnicodeCategory c = System.Globalization.UnicodeCategory.PrivateUse then + printfn "i = %x" i +*) + +type Spec = + { TopCode: Code; + Macros: (Ident * Regexp) list; + Rules: (Ident * Ident list * Clause list) list; + BottomCode: Code } +and Clause = Regexp * Code +and Regexp = + | Alt of Regexp list + | Seq of Regexp list + | Inp of Input + | Star of Regexp + | Macro of Ident +and Input = + | Alphabet of Alphabet + | UnicodeCategory of string + | Any + | NotCharSet of Set + +type NodeId = int + +type NfaNode = + { Id: NodeId; + Name: string; + Transitions: Dictionary; + Accepted: (int * int) list } + +type DfaNode = + { Id: int; + Name: string; + mutable Transitions: (Alphabet * DfaNode) list; + Accepted: (int * int) list } + +type MultiMap<'a,'b> = Dictionary<'a,'b list> +let LookupMultiMap (trDict:MultiMap<_,_>) a = + if trDict.ContainsKey(a) then trDict.[a] else [] + +let AddToMultiMap (trDict:MultiMap<_,_>) a b = + let prev = LookupMultiMap trDict a + trDict.[a] <- b::prev + +type NfaNodeMap() = + let map = new Dictionary(100) + member x.Item with get(nid) = map.[nid] + member x.Count = map.Count + + member x.NewNfaNode(trs,ac) = + let nodeId = map.Count+1 // ID zero is reserved + let trDict = new Dictionary<_,_>(List.length trs) + for (a,b) in trs do + AddToMultiMap trDict a b + + let node : NfaNode = {Id=nodeId; Name=string nodeId; Transitions=trDict; Accepted=ac} + map.[nodeId] <-node; + node + +let LexerStateToNfa (macros: Map) (clauses: Clause list) = + + /// Table allocating node ids + let nfaNodeMap = new NfaNodeMap() + + /// Compile a regular expression into the NFA + let rec CompileRegexp re dest = + match re with + | Alt res -> + let trs = res |> List.map (fun re -> (Epsilon,CompileRegexp re dest)) + nfaNodeMap.NewNfaNode(trs,[]) + | Seq res -> + List.foldBack (CompileRegexp) res dest + | Inp (Alphabet c) -> + nfaNodeMap.NewNfaNode([(c, dest)],[]) + + | Star re -> + let nfaNode = nfaNodeMap.NewNfaNode([(Epsilon, dest)],[]) + let sre = CompileRegexp re nfaNode + AddToMultiMap nfaNode.Transitions Epsilon sre + nfaNodeMap.NewNfaNode([(Epsilon,sre); (Epsilon,dest)],[]) + | Macro m -> + if not (macros.ContainsKey(m)) then failwith ("The macro "+m+" is not defined"); + CompileRegexp (macros.[m]) dest + + // These cases unwind the difficult cases in the syntax that rely on knowing the + // entire alphabet. + // + // Note we've delayed the expension of these until we've worked out all the 'special' Unicode characters + // mentioned in the entire lexer spec, i.e. we wait until GetAlphabet returns a reliable and stable answer. + | Inp (UnicodeCategory uc) -> + let re = Alt([ yield Inp(Alphabet(EncodeUnicodeCategory uc)) + // Also include any specific characters in this category + for c in GetSingleCharAlphabet() do + if System.Char.GetUnicodeCategory(c) = unicodeCategories.[uc] then + yield Inp(Alphabet(EncodeChar(c))) ]) + CompileRegexp re dest + + | Inp Any -> + let re = Alt([ for n in GetAlphabet() do yield Inp(Alphabet(n)) ]) + CompileRegexp re dest + + | Inp (NotCharSet chars) -> + let re = Alt [ // Include any characters from those in the alphabet besides those that are not immediately excluded + for c in GetSingleCharAlphabet() do + let ec = EncodeChar c + if not (chars.Contains(ec)) then + yield Inp(Alphabet(ec)) + + // Include all unicode categories + // That is, negations _only_ exclude precisely the given set of characters. You can't + // exclude whole classes of characters as yet + if !unicode then + let ucs = chars |> Set.map(DecodeChar >> System.Char.GetUnicodeCategory) + for KeyValue(nm,uc) in unicodeCategories do + //if ucs.Contains(uc) then + // do printfn "warning: the unicode category '\\%s' ('%s') is automatically excluded by this character set negation. Consider adding this to the negation." nm (uc.ToString()) + // yield! [] + //else + yield Inp(Alphabet(EncodeUnicodeCategory nm)) + ] + CompileRegexp re dest + + let actions = new System.Collections.Generic.List<_>() + + /// Compile an acceptance of a regular expression into the NFA + let sTrans macros nodeId (regexp,code) = + let actionId = actions.Count + actions.Add(code) + let sAccept = nfaNodeMap.NewNfaNode([],[(nodeId,actionId)]) + CompileRegexp regexp sAccept + + let trs = clauses |> List.mapi (fun n x -> (Epsilon,sTrans macros n x)) + let nfaStartNode = nfaNodeMap.NewNfaNode(trs,[]) + nfaStartNode,(actions |> Seq.readonly), nfaNodeMap + +// TODO: consider a better representation here. +type internal NfaNodeIdSetBuilder = HashSet + +type internal NfaNodeIdSet(nodes: NfaNodeIdSetBuilder) = + // BEWARE: the next line is performance critical + let s = nodes |> Seq.toArray |> (fun arr -> Array.sortInPlaceWith compare arr; arr) // 19 + + // These are all surprisingly slower: + //let s = nodes |> Seq.toArray |> Array.sort + //let s = nodes |> Seq.toArray |> Array.sortWith compare // 76 + //let s = nodes |> Seq.toArray |> (fun arr -> Array.sortInPlace arr; arr) // 76 + + member x.Representation = s + member x.Elements = s + member x.Fold f z = Array.fold f z s + interface System.IComparable with + member x.CompareTo(y:obj) = + let y = (y :?> NfaNodeIdSet) + let xr = x.Representation + let yr = y.Representation + let c = compare xr.Length yr.Length + if c <> 0 then c else + let n = yr.Length + let rec go i = + if i >= n then 0 else + let c = compare xr.[i] yr.[i] + if c <> 0 then c else + go (i+1) + go 0 + + override x.Equals(y:obj) = + match y with + | :? NfaNodeIdSet as y -> + let xr = x.Representation + let yr = y.Representation + let n = yr.Length + xr.Length = n && + (let rec go i = (i < n) && xr.[i] = yr.[i] && go (i+1) + go 0) + | _ -> false + + override x.GetHashCode() = hash s + + member x.IsEmpty = (s.Length = 0) + member x.Iterate f = s |> Array.iter f + +type NodeSetSet = Set + +let newDfaNodeId = + let i = ref 0 + fun () -> let res = !i in incr i; res + +let NfaToDfa (nfaNodeMap:NfaNodeMap) nfaStartNode = + let numNfaNodes = nfaNodeMap.Count + let rec EClosure1 (acc:NfaNodeIdSetBuilder) (n:NfaNode) = + if not (acc.Contains(n.Id)) then + acc.Add(n.Id) |> ignore; + if n.Transitions.ContainsKey(Epsilon) then + match n.Transitions.[Epsilon] with + | [] -> () // this Clause is an optimization - the list is normally empty + | tr -> + //printfn "n.Id = %A, #Epsilon = %d" n.Id tr.Length + tr |> List.iter (EClosure1 acc) + + let EClosure (moves:list) = + let acc = new NfaNodeIdSetBuilder(HashIdentity.Structural) + for i in moves do + EClosure1 acc nfaNodeMap.[i]; + new NfaNodeIdSet(acc) + + // Compute all the immediate one-step moves for a set of NFA states, as a dictionary + // mapping inputs to destination lists + let ComputeMoves (nset:NfaNodeIdSet) = + let moves = new MultiMap<_,_>() + nset.Iterate(fun nodeId -> + for (KeyValue(inp,dests)) in nfaNodeMap.[nodeId].Transitions do + if inp <> Epsilon then + match dests with + | [] -> () // this Clause is an optimization - the list is normally empty + | tr -> tr |> List.iter(fun dest -> AddToMultiMap moves inp dest.Id)) + moves + + let acc = new NfaNodeIdSetBuilder(HashIdentity.Structural) + EClosure1 acc nfaStartNode; + let nfaSet0 = new NfaNodeIdSet(acc) + + let dfaNodes = ref (Map.empty) + + let GetDfaNode nfaSet = + if (!dfaNodes).ContainsKey(nfaSet) then + (!dfaNodes).[nfaSet] + else + let dfaNode = + { Id= newDfaNodeId(); + Name = nfaSet.Fold (fun s nid -> nfaNodeMap.[nid].Name+"-"+s) ""; + Transitions=[]; + Accepted= nfaSet.Elements + |> Seq.map (fun nid -> nfaNodeMap.[nid].Accepted) + |> List.concat } + //Printf.printfn "id = %d" dfaNode.Id; + + dfaNodes := (!dfaNodes).Add(nfaSet,dfaNode); + dfaNode + + let workList = ref [nfaSet0] + let doneSet = ref Set.empty + + //let count = ref 0 + let rec Loop () = + match !workList with + | [] -> () + | nfaSet ::t -> + workList := t; + if (!doneSet).Contains(nfaSet) then + Loop () + else + let moves = ComputeMoves nfaSet + for (KeyValue(inp,movesForInput)) in moves do + assert (inp <> Epsilon); + let moveSet = EClosure movesForInput; + if not moveSet.IsEmpty then + //incr count + let dfaNode = GetDfaNode nfaSet + dfaNode.Transitions <- (inp, GetDfaNode moveSet) :: dfaNode.Transitions; + (* Printf.printf "%d (%s) : %s --> %d (%s)\n" dfaNode.Id dfaNode.Name (match inp with EncodeChar c -> String.make 1 c | LEof -> "eof") moveSetDfaNode.Id moveSetDfaNode.Name;*) + workList := moveSet :: !workList; + + doneSet := (!doneSet).Add(nfaSet); + + + Loop() + Loop(); + //Printf.printfn "count = %d" !count; + let ruleStartNode = GetDfaNode nfaSet0 + let ruleNodes = + (!dfaNodes) + |> Seq.map (fun kvp -> kvp.Value) + |> Seq.toList + |> List.sortBy (fun s -> s.Id) + ruleStartNode,ruleNodes + +let Compile spec = + List.foldBack + (fun (name,args,clauses) (perRuleData,dfaNodes) -> + let nfa, actions, nfaNodeMap = LexerStateToNfa (Map.ofList spec.Macros) clauses + let ruleStartNode, ruleNodes = NfaToDfa nfaNodeMap nfa + //Printf.printfn "name = %s, ruleStartNode = %O" name ruleStartNode.Id; + (ruleStartNode,actions) :: perRuleData, ruleNodes @ dfaNodes) + spec.Rules + ([],[]) + diff --git a/src/buildtools/fslex/fslexlex.fs b/src/buildtools/fslex/fslexlex.fs new file mode 100644 index 0000000000..b29bd10f84 --- /dev/null +++ b/src/buildtools/fslex/fslexlex.fs @@ -0,0 +1,735 @@ +# 1 "fslexlex.fsl" + +(* (c) Microsoft Corporation 2005-2008. *) + +module internal FsLexYacc.FsLex.Lexer + +open FsLexYacc.FsLex.AST +open FsLexYacc.FsLex.Parser +open Internal.Utilities +open Internal.Utilities.Text.Lexing +open System.Text + +let escape c = + match c with + | '\\' -> '\\' + | '\'' -> '\'' + | 'n' -> '\n' + | 't' -> '\t' + | 'b' -> '\b' + | 'r' -> '\r' + | c -> c + +let lexeme (lexbuf : LexBuffer) = new System.String(lexbuf.Lexeme) +let newline (lexbuf:LexBuffer<_>) = lexbuf.EndPos <- lexbuf.EndPos.NextLine + +let unexpected_char lexbuf = + failwith ("Unexpected character '"+(lexeme lexbuf)+"'") + +let digit d = + if d >= '0' && d <= '9' then int32 d - int32 '0' + else failwith "digit" + +let hexdigit d = + if d >= '0' && d <= '9' then digit d + else if d >= 'a' && d <= 'f' then int32 d - int32 'a' + 10 + else if d >= 'A' && d <= 'F' then int32 d - int32 'A' + 10 + else failwithf "bad hexdigit: %c" d + +let trigraph c1 c2 c3 = + char (digit c1 * 100 + digit c2 * 10 + digit c3) + +let hexgraph c1 c2 = + char (hexdigit c1 * 16 + hexdigit c2) + +let unicodegraph_short (s:string) = + if s.Length <> 4 then failwith "unicodegraph"; + char(hexdigit s.[0] * 4096 + hexdigit s.[1] * 256 + hexdigit s.[2] * 16 + hexdigit s.[3]) + +let unicodegraph_long (s:string) = + if s.Length <> 8 then failwith "unicodegraph_long"; + let high = hexdigit s.[0] * 4096 + hexdigit s.[1] * 256 + hexdigit s.[2] * 16 + hexdigit s.[3] in + let low = hexdigit s.[4] * 4096 + hexdigit s.[5] * 256 + hexdigit s.[6] * 16 + hexdigit s.[7] in + if high = 0 then None, char low + else + (* A surrogate pair - see http://www.unicode.org/unicode/uni2book/ch03.pdf, section 3.7 *) + Some (char(0xD800 + ((high * 0x10000 + low - 0x10000) / 0x400))), + char(0xDF30 + ((high * 0x10000 + low - 0x10000) % 0x400)) + + +# 60 "fslexlex.fs" +let trans : uint16[] array = + [| + (* State 0 *) + [| 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 4us; 8us; 8us; 5us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 2us; 8us; 8us; 8us; 8us; 1us; 3us; 9us; 6us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 7us; |]; + (* State 1 *) + [| 14us; 14us; 14us; 14us; 14us; 14us; 14us; 14us; 14us; 14us; 14us; 14us; 14us; 14us; 14us; 14us; 14us; 14us; 14us; 14us; 14us; 14us; 14us; 14us; 14us; 14us; 14us; 14us; 14us; 14us; 14us; 14us; 14us; 14us; 14us; 14us; 14us; 14us; 14us; 14us; 14us; 14us; 14us; 14us; 14us; 14us; 14us; 14us; 14us; 14us; 14us; 14us; 14us; 14us; 14us; 14us; 14us; 14us; 14us; 14us; 14us; 14us; 14us; 14us; 14us; 14us; 14us; 14us; 14us; 14us; 14us; 14us; 14us; 14us; 14us; 14us; 14us; 14us; 14us; 14us; 14us; 14us; 14us; 14us; 14us; 14us; 14us; 14us; 14us; 14us; 14us; 14us; 15us; 14us; 14us; 14us; 14us; 14us; 14us; 14us; 14us; 14us; 14us; 14us; 14us; 14us; 14us; 14us; 14us; 14us; 14us; 14us; 14us; 14us; 14us; 14us; 14us; 14us; 14us; 14us; 14us; 14us; 14us; 14us; 14us; 14us; 14us; 14us; 14us; 14us; 14us; 14us; 14us; 14us; 14us; 14us; 14us; 14us; 14us; 14us; 14us; 14us; 14us; 14us; 14us; 14us; 14us; 14us; 14us; 14us; 14us; 14us; 14us; 14us; 14us; 14us; 14us; 14us; 65535us; |]; + (* State 2 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 3 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 13us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 4 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 5 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 12us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 6 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 11us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 7 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 8 *) + [| 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 65535us; 10us; 10us; 65535us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 65535us; 10us; 10us; 10us; 10us; 65535us; 65535us; 65535us; 65535us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 65535us; |]; + (* State 9 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 10 *) + [| 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 65535us; 10us; 10us; 65535us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 65535us; 10us; 10us; 10us; 10us; 65535us; 65535us; 65535us; 65535us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 10us; 65535us; |]; + (* State 11 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 12 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 13 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 14 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 16us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 15 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 14us; 65535us; 65535us; 65535us; 65535us; 14us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 14us; 65535us; 65535us; 65535us; 65535us; 65535us; 14us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 14us; 65535us; 65535us; 65535us; 14us; 65535us; 14us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 16 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 17 *) + [| 24us; 24us; 24us; 24us; 24us; 24us; 24us; 24us; 24us; 22us; 20us; 24us; 24us; 21us; 24us; 24us; 24us; 24us; 24us; 24us; 24us; 24us; 24us; 24us; 24us; 24us; 24us; 24us; 24us; 24us; 24us; 24us; 22us; 24us; 19us; 24us; 24us; 24us; 24us; 24us; 24us; 24us; 24us; 24us; 24us; 24us; 24us; 24us; 22us; 22us; 22us; 22us; 22us; 22us; 22us; 22us; 22us; 22us; 24us; 24us; 24us; 24us; 24us; 24us; 24us; 22us; 22us; 22us; 22us; 22us; 22us; 22us; 22us; 22us; 22us; 22us; 22us; 22us; 22us; 22us; 22us; 22us; 22us; 22us; 22us; 22us; 22us; 22us; 22us; 22us; 22us; 24us; 18us; 24us; 24us; 24us; 24us; 22us; 22us; 22us; 22us; 22us; 22us; 22us; 22us; 22us; 22us; 22us; 22us; 22us; 22us; 22us; 22us; 22us; 22us; 22us; 22us; 22us; 22us; 22us; 22us; 22us; 22us; 24us; 24us; 24us; 24us; 24us; 24us; 24us; 24us; 24us; 24us; 24us; 24us; 24us; 24us; 24us; 24us; 24us; 24us; 24us; 24us; 24us; 24us; 24us; 24us; 24us; 24us; 24us; 24us; 24us; 24us; 24us; 24us; 24us; 24us; 24us; 23us; |]; + (* State 18 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 27us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 27us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 19 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 20 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 21 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 26us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 22 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 25us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 25us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 23 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 24 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 25 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 25us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 25us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 25us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 26 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 27 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 28 *) + [| 38us; 38us; 38us; 38us; 38us; 38us; 38us; 38us; 38us; 35us; 33us; 38us; 38us; 34us; 38us; 38us; 38us; 38us; 38us; 38us; 38us; 38us; 38us; 38us; 38us; 38us; 38us; 38us; 38us; 38us; 38us; 38us; 35us; 38us; 32us; 38us; 38us; 38us; 38us; 38us; 38us; 38us; 38us; 38us; 38us; 38us; 38us; 36us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 38us; 38us; 38us; 38us; 38us; 38us; 38us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 38us; 31us; 38us; 38us; 38us; 38us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 30us; 38us; 29us; 38us; 38us; 38us; 38us; 38us; 38us; 38us; 38us; 38us; 38us; 38us; 38us; 38us; 38us; 38us; 38us; 38us; 38us; 38us; 38us; 38us; 38us; 38us; 38us; 38us; 38us; 38us; 38us; 38us; 38us; 38us; 38us; 37us; |]; + (* State 29 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 30 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 31 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 43us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 43us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 32 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 33 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 34 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 42us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 35 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 41us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 41us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 41us; 41us; 41us; 41us; 41us; 41us; 41us; 41us; 41us; 41us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 41us; 41us; 41us; 41us; 41us; 41us; 41us; 41us; 41us; 41us; 41us; 41us; 41us; 41us; 41us; 41us; 41us; 41us; 41us; 41us; 41us; 41us; 41us; 41us; 41us; 41us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 41us; 41us; 41us; 41us; 41us; 41us; 41us; 41us; 41us; 41us; 41us; 41us; 41us; 41us; 41us; 41us; 41us; 41us; 41us; 41us; 41us; 41us; 41us; 41us; 41us; 41us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 36 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 39us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 37 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 38 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 39 *) + [| 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 65535us; 40us; 40us; 65535us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 65535us; |]; + (* State 40 *) + [| 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 65535us; 40us; 40us; 65535us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 40us; 65535us; |]; + (* State 41 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 41us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 41us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 41us; 41us; 41us; 41us; 41us; 41us; 41us; 41us; 41us; 41us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 41us; 41us; 41us; 41us; 41us; 41us; 41us; 41us; 41us; 41us; 41us; 41us; 41us; 41us; 41us; 41us; 41us; 41us; 41us; 41us; 41us; 41us; 41us; 41us; 41us; 41us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 41us; 41us; 41us; 41us; 41us; 41us; 41us; 41us; 41us; 41us; 41us; 41us; 41us; 41us; 41us; 41us; 41us; 41us; 41us; 41us; 41us; 41us; 41us; 41us; 41us; 41us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 42 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 43 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 44 *) + [| 51us; 51us; 51us; 51us; 51us; 51us; 51us; 51us; 51us; 49us; 47us; 51us; 51us; 48us; 51us; 51us; 51us; 51us; 51us; 51us; 51us; 51us; 51us; 51us; 51us; 51us; 51us; 51us; 51us; 51us; 51us; 51us; 49us; 51us; 46us; 51us; 51us; 51us; 51us; 51us; 51us; 51us; 51us; 51us; 51us; 51us; 51us; 51us; 49us; 49us; 49us; 49us; 49us; 49us; 49us; 49us; 49us; 49us; 51us; 51us; 51us; 51us; 51us; 51us; 51us; 49us; 49us; 49us; 49us; 49us; 49us; 49us; 49us; 49us; 49us; 49us; 49us; 49us; 49us; 49us; 49us; 49us; 49us; 49us; 49us; 49us; 49us; 49us; 49us; 49us; 49us; 51us; 45us; 51us; 51us; 51us; 51us; 49us; 49us; 49us; 49us; 49us; 49us; 49us; 49us; 49us; 49us; 49us; 49us; 49us; 49us; 49us; 49us; 49us; 49us; 49us; 49us; 49us; 49us; 49us; 49us; 49us; 49us; 51us; 51us; 51us; 51us; 51us; 51us; 51us; 51us; 51us; 51us; 51us; 51us; 51us; 51us; 51us; 51us; 51us; 51us; 51us; 51us; 51us; 51us; 51us; 51us; 51us; 51us; 51us; 51us; 51us; 51us; 51us; 51us; 51us; 51us; 51us; 50us; |]; + (* State 45 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 54us; 65535us; 65535us; 55us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 56us; 65535us; 65535us; 65535us; 65535us; 56us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 56us; 65535us; 65535us; 65535us; 65535us; 65535us; 56us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 56us; 65535us; 65535us; 65535us; 56us; 65535us; 56us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 46 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 47 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 48 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 53us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 49 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 52us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 52us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 52us; 52us; 52us; 52us; 52us; 52us; 52us; 52us; 52us; 52us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 52us; 52us; 52us; 52us; 52us; 52us; 52us; 52us; 52us; 52us; 52us; 52us; 52us; 52us; 52us; 52us; 52us; 52us; 52us; 52us; 52us; 52us; 52us; 52us; 52us; 52us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 52us; 52us; 52us; 52us; 52us; 52us; 52us; 52us; 52us; 52us; 52us; 52us; 52us; 52us; 52us; 52us; 52us; 52us; 52us; 52us; 52us; 52us; 52us; 52us; 52us; 52us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 50 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 51 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 52 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 52us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 52us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 52us; 52us; 52us; 52us; 52us; 52us; 52us; 52us; 52us; 52us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 52us; 52us; 52us; 52us; 52us; 52us; 52us; 52us; 52us; 52us; 52us; 52us; 52us; 52us; 52us; 52us; 52us; 52us; 52us; 52us; 52us; 52us; 52us; 52us; 52us; 52us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 52us; 52us; 52us; 52us; 52us; 52us; 52us; 52us; 52us; 52us; 52us; 52us; 52us; 52us; 52us; 52us; 52us; 52us; 52us; 52us; 52us; 52us; 52us; 52us; 52us; 52us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 53 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 54 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 55 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 54us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 56 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 57 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 58us; 58us; 58us; 58us; 58us; 58us; 58us; 58us; 58us; 58us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 58 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 59us; 59us; 59us; 59us; 59us; 59us; 59us; 59us; 59us; 59us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 59 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 60 *) + [| 87us; 87us; 87us; 87us; 87us; 87us; 87us; 87us; 87us; 69us; 70us; 87us; 87us; 71us; 87us; 87us; 87us; 87us; 87us; 87us; 87us; 87us; 87us; 87us; 87us; 87us; 87us; 87us; 87us; 87us; 87us; 87us; 69us; 87us; 68us; 87us; 87us; 87us; 87us; 66us; 81us; 82us; 76us; 75us; 87us; 85us; 74us; 86us; 87us; 87us; 87us; 87us; 87us; 87us; 87us; 87us; 87us; 87us; 87us; 87us; 87us; 78us; 87us; 77us; 87us; 72us; 72us; 72us; 72us; 72us; 72us; 72us; 72us; 72us; 72us; 72us; 72us; 72us; 72us; 72us; 72us; 72us; 72us; 72us; 72us; 72us; 72us; 72us; 72us; 72us; 72us; 79us; 87us; 80us; 84us; 83us; 87us; 65us; 72us; 72us; 72us; 63us; 72us; 72us; 72us; 72us; 72us; 72us; 64us; 72us; 72us; 72us; 62us; 72us; 61us; 72us; 72us; 72us; 72us; 72us; 72us; 72us; 72us; 67us; 73us; 87us; 87us; 87us; 87us; 87us; 87us; 87us; 87us; 87us; 87us; 87us; 87us; 87us; 87us; 87us; 87us; 87us; 87us; 87us; 87us; 87us; 87us; 87us; 87us; 87us; 87us; 87us; 87us; 87us; 87us; 87us; 87us; 87us; 88us; |]; + (* State 61 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 92us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 65535us; 65535us; 65535us; 65535us; 92us; 65535us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 136us; 92us; 92us; 92us; 92us; 92us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 62 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 92us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 65535us; 65535us; 65535us; 65535us; 92us; 65535us; 132us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 63 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 92us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 65535us; 65535us; 65535us; 65535us; 92us; 65535us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 130us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 64 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 92us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 65535us; 65535us; 65535us; 65535us; 92us; 65535us; 92us; 92us; 92us; 92us; 128us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 65 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 92us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 65535us; 65535us; 65535us; 65535us; 92us; 65535us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 126us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 66 *) + [| 95us; 95us; 95us; 95us; 95us; 95us; 95us; 95us; 95us; 95us; 95us; 95us; 95us; 95us; 95us; 95us; 95us; 95us; 95us; 95us; 95us; 95us; 95us; 95us; 95us; 95us; 95us; 95us; 95us; 95us; 95us; 95us; 95us; 95us; 95us; 95us; 95us; 95us; 95us; 95us; 95us; 95us; 95us; 95us; 95us; 95us; 95us; 95us; 95us; 95us; 95us; 95us; 95us; 95us; 95us; 95us; 95us; 95us; 95us; 95us; 95us; 95us; 95us; 95us; 95us; 95us; 95us; 95us; 95us; 95us; 95us; 95us; 95us; 95us; 95us; 95us; 95us; 95us; 95us; 95us; 95us; 95us; 95us; 95us; 95us; 95us; 95us; 95us; 95us; 95us; 95us; 95us; 96us; 95us; 95us; 95us; 95us; 95us; 95us; 95us; 95us; 95us; 95us; 95us; 95us; 95us; 95us; 95us; 95us; 95us; 95us; 95us; 95us; 95us; 95us; 95us; 95us; 95us; 95us; 95us; 95us; 95us; 95us; 95us; 95us; 95us; 95us; 95us; 95us; 95us; 95us; 95us; 95us; 95us; 95us; 95us; 95us; 95us; 95us; 95us; 95us; 95us; 95us; 95us; 95us; 95us; 95us; 95us; 95us; 95us; 95us; 95us; 95us; 95us; 95us; 95us; 95us; 95us; 65535us; |]; + (* State 67 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 68 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 69 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 94us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 94us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 70 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 71 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 93us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 72 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 92us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 65535us; 65535us; 65535us; 65535us; 92us; 65535us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 73 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 74 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 75 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 76 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 77 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 78 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 79 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 80 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 81 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 91us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 82 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 83 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 84 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 85 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 86 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 89us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 87 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 88 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 89 *) + [| 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 65535us; 90us; 90us; 65535us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 65535us; |]; + (* State 90 *) + [| 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 65535us; 90us; 90us; 65535us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 90us; 65535us; |]; + (* State 91 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 92 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 92us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 65535us; 65535us; 65535us; 65535us; 92us; 65535us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 93 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 94 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 94us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 94us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 95 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 125us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 96 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 95us; 65535us; 65535us; 65535us; 65535us; 95us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 97us; 97us; 97us; 97us; 97us; 97us; 97us; 97us; 97us; 97us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 101us; 101us; 101us; 101us; 101us; 101us; 101us; 101us; 101us; 101us; 101us; 101us; 101us; 101us; 101us; 101us; 101us; 101us; 101us; 101us; 100us; 101us; 101us; 101us; 101us; 101us; 65535us; 95us; 65535us; 65535us; 65535us; 65535us; 65535us; 95us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 95us; 65535us; 65535us; 65535us; 95us; 65535us; 95us; 99us; 65535us; 65535us; 98us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 97 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 122us; 122us; 122us; 122us; 122us; 122us; 122us; 122us; 122us; 122us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 98 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 119us; 119us; 119us; 119us; 119us; 119us; 119us; 119us; 119us; 119us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 119us; 119us; 119us; 119us; 119us; 119us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 119us; 119us; 119us; 119us; 119us; 119us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 99 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 114us; 114us; 114us; 114us; 114us; 114us; 114us; 114us; 114us; 114us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 114us; 114us; 114us; 114us; 114us; 114us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 114us; 114us; 114us; 114us; 114us; 114us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 100 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 104us; 104us; 104us; 104us; 104us; 104us; 104us; 104us; 104us; 104us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 104us; 104us; 104us; 104us; 104us; 104us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 105us; 105us; 105us; 105us; 105us; 105us; 102us; 102us; 102us; 102us; 102us; 102us; 102us; 102us; 102us; 102us; 102us; 102us; 102us; 102us; 102us; 102us; 102us; 102us; 102us; 102us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 101 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 102us; 102us; 102us; 102us; 102us; 102us; 102us; 102us; 102us; 102us; 102us; 102us; 102us; 102us; 102us; 102us; 102us; 102us; 102us; 102us; 102us; 102us; 102us; 102us; 102us; 102us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 102 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 103us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 103 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 104 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 106us; 106us; 106us; 106us; 106us; 106us; 106us; 106us; 106us; 106us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 106us; 106us; 106us; 106us; 106us; 106us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 106us; 106us; 106us; 106us; 106us; 106us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 105 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 103us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 106us; 106us; 106us; 106us; 106us; 106us; 106us; 106us; 106us; 106us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 106us; 106us; 106us; 106us; 106us; 106us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 106us; 106us; 106us; 106us; 106us; 106us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 106 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 107us; 107us; 107us; 107us; 107us; 107us; 107us; 107us; 107us; 107us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 107us; 107us; 107us; 107us; 107us; 107us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 107us; 107us; 107us; 107us; 107us; 107us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 107 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 108us; 108us; 108us; 108us; 108us; 108us; 108us; 108us; 108us; 108us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 108us; 108us; 108us; 108us; 108us; 108us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 108us; 108us; 108us; 108us; 108us; 108us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 108 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 109us; 109us; 109us; 109us; 109us; 109us; 109us; 109us; 109us; 109us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 109us; 109us; 109us; 109us; 109us; 109us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 109us; 109us; 109us; 109us; 109us; 109us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 109 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 110us; 110us; 110us; 110us; 110us; 110us; 110us; 110us; 110us; 110us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 110us; 110us; 110us; 110us; 110us; 110us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 110us; 110us; 110us; 110us; 110us; 110us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 110 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 111us; 111us; 111us; 111us; 111us; 111us; 111us; 111us; 111us; 111us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 111us; 111us; 111us; 111us; 111us; 111us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 111us; 111us; 111us; 111us; 111us; 111us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 111 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 112us; 112us; 112us; 112us; 112us; 112us; 112us; 112us; 112us; 112us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 112us; 112us; 112us; 112us; 112us; 112us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 112us; 112us; 112us; 112us; 112us; 112us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 112 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 113us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 113 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 114 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 115us; 115us; 115us; 115us; 115us; 115us; 115us; 115us; 115us; 115us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 115us; 115us; 115us; 115us; 115us; 115us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 115us; 115us; 115us; 115us; 115us; 115us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 115 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 116us; 116us; 116us; 116us; 116us; 116us; 116us; 116us; 116us; 116us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 116us; 116us; 116us; 116us; 116us; 116us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 116us; 116us; 116us; 116us; 116us; 116us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 116 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 117us; 117us; 117us; 117us; 117us; 117us; 117us; 117us; 117us; 117us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 117us; 117us; 117us; 117us; 117us; 117us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 117us; 117us; 117us; 117us; 117us; 117us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 117 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 118us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 118 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 119 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 120us; 120us; 120us; 120us; 120us; 120us; 120us; 120us; 120us; 120us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 120us; 120us; 120us; 120us; 120us; 120us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 120us; 120us; 120us; 120us; 120us; 120us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 120 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 121us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 121 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 122 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 123us; 123us; 123us; 123us; 123us; 123us; 123us; 123us; 123us; 123us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 123 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 124us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 124 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 125 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 126 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 92us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 65535us; 65535us; 65535us; 65535us; 92us; 65535us; 92us; 92us; 92us; 127us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 127 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 92us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 65535us; 65535us; 65535us; 65535us; 92us; 65535us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 128 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 92us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 65535us; 65535us; 65535us; 65535us; 92us; 65535us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 129us; 92us; 92us; 92us; 92us; 92us; 92us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 129 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 92us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 65535us; 65535us; 65535us; 65535us; 92us; 65535us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 130 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 92us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 65535us; 65535us; 65535us; 65535us; 92us; 65535us; 92us; 92us; 92us; 92us; 92us; 131us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 131 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 92us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 65535us; 65535us; 65535us; 65535us; 92us; 65535us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 132 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 92us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 65535us; 65535us; 65535us; 65535us; 92us; 65535us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 133us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 133 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 92us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 65535us; 65535us; 65535us; 65535us; 92us; 65535us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 134us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 134 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 92us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 65535us; 65535us; 65535us; 65535us; 92us; 65535us; 92us; 92us; 92us; 92us; 135us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 135 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 92us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 65535us; 65535us; 65535us; 65535us; 92us; 65535us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 136 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 92us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 65535us; 65535us; 65535us; 65535us; 92us; 65535us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 137us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 137 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 92us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 65535us; 65535us; 65535us; 65535us; 92us; 65535us; 92us; 92us; 92us; 92us; 138us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 138 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 92us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 65535us; 65535us; 65535us; 65535us; 92us; 65535us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 92us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + |] +let actions : uint16[] = [|65535us; 7us; 1us; 7us; 3us; 7us; 7us; 5us; 6us; 7us; 6us; 4us; 3us; 2us; 65535us; 65535us; 0us; 65535us; 5us; 1us; 2us; 5us; 3us; 4us; 5us; 3us; 2us; 0us; 65535us; 0us; 1us; 8us; 3us; 4us; 8us; 5us; 8us; 7us; 8us; 6us; 6us; 5us; 4us; 2us; 65535us; 7us; 3us; 4us; 7us; 5us; 6us; 7us; 5us; 4us; 0us; 65535us; 1us; 65535us; 65535us; 2us; 65535us; 15us; 15us; 15us; 15us; 15us; 31us; 11us; 12us; 13us; 14us; 31us; 15us; 16us; 17us; 18us; 19us; 20us; 21us; 22us; 23us; 24us; 25us; 26us; 27us; 28us; 31us; 31us; 32us; 30us; 30us; 29us; 15us; 14us; 13us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 10us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 9us; 65535us; 65535us; 65535us; 65535us; 8us; 65535us; 65535us; 7us; 65535us; 65535us; 6us; 5us; 15us; 4us; 15us; 3us; 15us; 2us; 15us; 15us; 15us; 1us; 15us; 15us; 0us; |] +let _fslex_tables = Internal.Utilities.Text.Lexing.UnicodeTables.Create(trans,actions) +let rec _fslex_dummy () = _fslex_dummy() +(* Rule token *) +and token (lexbuf : Internal.Utilities.Text.Lexing.LexBuffer<_>) = _fslex_token 60 lexbuf +(* Rule string *) +and string p buff (lexbuf : Internal.Utilities.Text.Lexing.LexBuffer<_>) = _fslex_string p buff 44 lexbuf +(* Rule code *) +and code p buff (lexbuf : Internal.Utilities.Text.Lexing.LexBuffer<_>) = _fslex_code p buff 28 lexbuf +(* Rule codestring *) +and codestring buff (lexbuf : Internal.Utilities.Text.Lexing.LexBuffer<_>) = _fslex_codestring buff 17 lexbuf +(* Rule comment *) +and comment p (lexbuf : Internal.Utilities.Text.Lexing.LexBuffer<_>) = _fslex_comment p 0 lexbuf +(* Rule token *) +and _fslex_token _fslex_state lexbuf = + match _fslex_tables.Interpret(_fslex_state,lexbuf) with + | 0 -> ( +# 76 "fslexlex.fsl" + RULE +# 361 "fslexlex.fs" + ) + | 1 -> ( +# 77 "fslexlex.fsl" + PARSE +# 366 "fslexlex.fs" + ) + | 2 -> ( +# 78 "fslexlex.fsl" + EOF +# 371 "fslexlex.fs" + ) + | 3 -> ( +# 79 "fslexlex.fsl" + LET +# 376 "fslexlex.fs" + ) + | 4 -> ( +# 80 "fslexlex.fsl" + AND +# 381 "fslexlex.fs" + ) + | 5 -> ( +# 82 "fslexlex.fsl" + let s = lexeme lexbuf in + CHAR (if s.[1] = '\\' then escape s.[2] else s.[1]) +# 387 "fslexlex.fs" + ) + | 6 -> ( +# 86 "fslexlex.fsl" + let s = lexeme lexbuf in + CHAR (trigraph s.[2] s.[3] s.[4]) +# 393 "fslexlex.fs" + ) + | 7 -> ( +# 90 "fslexlex.fsl" + let s = lexeme lexbuf in + CHAR (hexgraph s.[3] s.[4]) +# 399 "fslexlex.fs" + ) + | 8 -> ( +# 94 "fslexlex.fsl" + let s = lexeme lexbuf in + CHAR (unicodegraph_short s.[3..6]) +# 405 "fslexlex.fs" + ) + | 9 -> ( +# 98 "fslexlex.fsl" + let s = lexeme lexbuf in + match (unicodegraph_long s.[3..10]) with + | None, c -> CHAR(c) + | Some _ , _ -> failwith "Unicode characters needing surrogate pairs are not yet supported by this tool" +# 413 "fslexlex.fs" + ) + | 10 -> ( +# 104 "fslexlex.fsl" + let s = (lexeme lexbuf).[2..3] in + UNICODE_CATEGORY (s) +# 419 "fslexlex.fs" + ) + | 11 -> ( +# 107 "fslexlex.fsl" + let p = lexbuf.StartPos in + let buff = (new StringBuilder 100) in + // adjust the first line to get even indentation for all lines w.r.t. the left hand margin + buff.Append (String.replicate (lexbuf.StartPos.Column+1) " ") |> ignore; + code p buff lexbuf +# 428 "fslexlex.fs" + ) + | 12 -> ( +# 113 "fslexlex.fsl" + string lexbuf.StartPos (new StringBuilder 100) lexbuf +# 433 "fslexlex.fs" + ) + | 13 -> ( +# 115 "fslexlex.fsl" + token lexbuf +# 438 "fslexlex.fs" + ) + | 14 -> ( +# 116 "fslexlex.fsl" + newline lexbuf; token lexbuf +# 443 "fslexlex.fs" + ) + | 15 -> ( +# 117 "fslexlex.fsl" + IDENT (lexeme lexbuf) +# 448 "fslexlex.fs" + ) + | 16 -> ( +# 118 "fslexlex.fsl" + BAR +# 453 "fslexlex.fs" + ) + | 17 -> ( +# 119 "fslexlex.fsl" + DOT +# 458 "fslexlex.fs" + ) + | 18 -> ( +# 120 "fslexlex.fsl" + PLUS +# 463 "fslexlex.fs" + ) + | 19 -> ( +# 121 "fslexlex.fsl" + STAR +# 468 "fslexlex.fs" + ) + | 20 -> ( +# 122 "fslexlex.fsl" + QMARK +# 473 "fslexlex.fs" + ) + | 21 -> ( +# 123 "fslexlex.fsl" + EQUALS +# 478 "fslexlex.fs" + ) + | 22 -> ( +# 124 "fslexlex.fsl" + LBRACK +# 483 "fslexlex.fs" + ) + | 23 -> ( +# 125 "fslexlex.fsl" + RBRACK +# 488 "fslexlex.fs" + ) + | 24 -> ( +# 126 "fslexlex.fsl" + LPAREN +# 493 "fslexlex.fs" + ) + | 25 -> ( +# 127 "fslexlex.fsl" + RPAREN +# 498 "fslexlex.fs" + ) + | 26 -> ( +# 128 "fslexlex.fsl" + UNDERSCORE +# 503 "fslexlex.fs" + ) + | 27 -> ( +# 129 "fslexlex.fsl" + HAT +# 508 "fslexlex.fs" + ) + | 28 -> ( +# 130 "fslexlex.fsl" + DASH +# 513 "fslexlex.fs" + ) + | 29 -> ( +# 131 "fslexlex.fsl" + ignore(comment lexbuf.StartPos lexbuf); token lexbuf +# 518 "fslexlex.fs" + ) + | 30 -> ( +# 132 "fslexlex.fsl" + token lexbuf +# 523 "fslexlex.fs" + ) + | 31 -> ( +# 133 "fslexlex.fsl" + unexpected_char lexbuf +# 528 "fslexlex.fs" + ) + | 32 -> ( +# 134 "fslexlex.fsl" + EOF +# 533 "fslexlex.fs" + ) + | _ -> failwith "token" +(* Rule string *) +and _fslex_string p buff _fslex_state lexbuf = + match _fslex_tables.Interpret(_fslex_state,lexbuf) with + | 0 -> ( +# 136 "fslexlex.fsl" + newline lexbuf; string p buff lexbuf +# 542 "fslexlex.fs" + ) + | 1 -> ( +# 138 "fslexlex.fsl" + let _ = buff.Append (escape (lexeme lexbuf).[1]) in + string p buff lexbuf +# 548 "fslexlex.fs" + ) + | 2 -> ( +# 141 "fslexlex.fsl" + let s = lexeme lexbuf in + let _ = buff.Append (trigraph s.[1] s.[2] s.[3]) in + string p buff lexbuf +# 555 "fslexlex.fs" + ) + | 3 -> ( +# 144 "fslexlex.fsl" + STRING (buff.ToString()) +# 560 "fslexlex.fs" + ) + | 4 -> ( +# 145 "fslexlex.fsl" + newline lexbuf; + let _ = buff.Append System.Environment.NewLine in + string p buff lexbuf +# 567 "fslexlex.fs" + ) + | 5 -> ( +# 149 "fslexlex.fsl" + let _ = buff.Append (lexeme lexbuf) in + string p buff lexbuf +# 573 "fslexlex.fs" + ) + | 6 -> ( +# 151 "fslexlex.fsl" + failwith (Printf.sprintf "end of file in string started at (%d,%d)" p.pos_lnum (p.pos_cnum - p.pos_bol)) +# 578 "fslexlex.fs" + ) + | 7 -> ( +# 152 "fslexlex.fsl" + let _ = buff.Append (lexeme lexbuf).[0] in + string p buff lexbuf +# 584 "fslexlex.fs" + ) + | _ -> failwith "string" +(* Rule code *) +and _fslex_code p buff _fslex_state lexbuf = + match _fslex_tables.Interpret(_fslex_state,lexbuf) with + | 0 -> ( +# 155 "fslexlex.fsl" + CODE (buff.ToString(), p) +# 593 "fslexlex.fs" + ) + | 1 -> ( +# 156 "fslexlex.fsl" + let _ = buff.Append (lexeme lexbuf) in + ignore(code p buff lexbuf); + let _ = buff.Append "}" in + code p buff lexbuf +# 601 "fslexlex.fs" + ) + | 2 -> ( +# 161 "fslexlex.fsl" + let _ = buff.Append (lexeme lexbuf) in + code p buff lexbuf +# 607 "fslexlex.fs" + ) + | 3 -> ( +# 163 "fslexlex.fsl" + let _ = buff.Append (lexeme lexbuf) in + ignore(codestring buff lexbuf); + code p buff lexbuf +# 614 "fslexlex.fs" + ) + | 4 -> ( +# 166 "fslexlex.fsl" + newline lexbuf; + let _ = buff.Append System.Environment.NewLine in + code p buff lexbuf +# 621 "fslexlex.fs" + ) + | 5 -> ( +# 170 "fslexlex.fsl" + let _ = buff.Append (lexeme lexbuf) in + code p buff lexbuf +# 627 "fslexlex.fs" + ) + | 6 -> ( +# 173 "fslexlex.fsl" + let _ = buff.Append (lexeme lexbuf) in + code p buff lexbuf +# 633 "fslexlex.fs" + ) + | 7 -> ( +# 175 "fslexlex.fsl" + EOF +# 638 "fslexlex.fs" + ) + | 8 -> ( +# 176 "fslexlex.fsl" + let _ = buff.Append (lexeme lexbuf).[0] in + code p buff lexbuf +# 644 "fslexlex.fs" + ) + | _ -> failwith "code" +(* Rule codestring *) +and _fslex_codestring buff _fslex_state lexbuf = + match _fslex_tables.Interpret(_fslex_state,lexbuf) with + | 0 -> ( +# 181 "fslexlex.fsl" + let _ = buff.Append (lexeme lexbuf) in + codestring buff lexbuf +# 654 "fslexlex.fs" + ) + | 1 -> ( +# 183 "fslexlex.fsl" + let _ = buff.Append (lexeme lexbuf) in + buff.ToString() +# 660 "fslexlex.fs" + ) + | 2 -> ( +# 185 "fslexlex.fsl" + newline lexbuf; + let _ = buff.Append System.Environment.NewLine in + codestring buff lexbuf +# 667 "fslexlex.fs" + ) + | 3 -> ( +# 189 "fslexlex.fsl" + let _ = buff.Append (lexeme lexbuf) in + codestring buff lexbuf +# 673 "fslexlex.fs" + ) + | 4 -> ( +# 191 "fslexlex.fsl" + failwith "unterminated string in code" +# 678 "fslexlex.fs" + ) + | 5 -> ( +# 192 "fslexlex.fsl" + let _ = buff.Append (lexeme lexbuf).[0] in + codestring buff lexbuf +# 684 "fslexlex.fs" + ) + | _ -> failwith "codestring" +(* Rule comment *) +and _fslex_comment p _fslex_state lexbuf = + match _fslex_tables.Interpret(_fslex_state,lexbuf) with + | 0 -> ( +# 196 "fslexlex.fsl" + comment p lexbuf +# 693 "fslexlex.fs" + ) + | 1 -> ( +# 197 "fslexlex.fsl" + ignore(try string lexbuf.StartPos (new StringBuilder 100) lexbuf + with Failure s -> failwith (s + "\n" + Printf.sprintf "error while processing string nested in comment started at (%d,%d)" p.pos_lnum (p.pos_cnum - p.pos_bol))); + comment p lexbuf +# 700 "fslexlex.fs" + ) + | 2 -> ( +# 200 "fslexlex.fsl" + ignore(try comment p lexbuf with Failure s -> failwith (s + "\n" + Printf.sprintf "error while processing nested comment started at (%d,%d)" p.pos_lnum (p.pos_cnum - p.pos_bol))); + comment p lexbuf +# 706 "fslexlex.fs" + ) + | 3 -> ( +# 202 "fslexlex.fsl" + newline lexbuf; comment p lexbuf +# 711 "fslexlex.fs" + ) + | 4 -> ( +# 203 "fslexlex.fsl" + () +# 716 "fslexlex.fs" + ) + | 5 -> ( +# 204 "fslexlex.fsl" + failwith (Printf.sprintf "end of file in comment started at (%d,%d)" p.pos_lnum (p.pos_cnum - p.pos_bol)) +# 721 "fslexlex.fs" + ) + | 6 -> ( +# 205 "fslexlex.fsl" + comment p lexbuf +# 726 "fslexlex.fs" + ) + | 7 -> ( +# 206 "fslexlex.fsl" + comment p lexbuf +# 731 "fslexlex.fs" + ) + | _ -> failwith "comment" + +# 3000000 "fslexlex.fs" diff --git a/src/buildtools/fslex/fslexpars.fs b/src/buildtools/fslex/fslexpars.fs new file mode 100644 index 0000000000..87268dcb7f --- /dev/null +++ b/src/buildtools/fslex/fslexpars.fs @@ -0,0 +1,651 @@ +// Implementation file for parser generated by fsyacc +module internal FsLexYacc.FsLex.Parser +#nowarn "64";; // turn off warnings that type variables used in production annotations are instantiated to concrete type +open Internal.Utilities.Text.Lexing +open Internal.Utilities.Text.Parsing.ParseHelpers +# 1 "fslexpars.fsy" + +(* (c) Microsoft Corporation 2005-2008. *) + +open FsLexYacc.FsLex +open FsLexYacc.FsLex.AST + + +# 14 "fslexpars.fs" +// This type is the type of tokens accepted by the parser +type token = + | EOF + | BAR + | DOT + | PLUS + | STAR + | QMARK + | EQUALS + | UNDERSCORE + | LBRACK + | RBRACK + | HAT + | DASH + | RULE + | PARSE + | LET + | AND + | LPAREN + | RPAREN + | UNICODE_CATEGORY of (string) + | CHAR of (char) + | CODE of (AST.Code) + | STRING of (string) + | IDENT of (string) +// This type is used to give symbolic names to token indexes, useful for error messages +type tokenId = + | TOKEN_EOF + | TOKEN_BAR + | TOKEN_DOT + | TOKEN_PLUS + | TOKEN_STAR + | TOKEN_QMARK + | TOKEN_EQUALS + | TOKEN_UNDERSCORE + | TOKEN_LBRACK + | TOKEN_RBRACK + | TOKEN_HAT + | TOKEN_DASH + | TOKEN_RULE + | TOKEN_PARSE + | TOKEN_LET + | TOKEN_AND + | TOKEN_LPAREN + | TOKEN_RPAREN + | TOKEN_UNICODE_CATEGORY + | TOKEN_CHAR + | TOKEN_CODE + | TOKEN_STRING + | TOKEN_IDENT + | TOKEN_end_of_input + | TOKEN_error +// This type is used to give symbolic names to token indexes, useful for error messages +type nonTerminalId = + | NONTERM__startspec + | NONTERM_spec + | NONTERM_codeopt + | NONTERM_Macros + | NONTERM_macro + | NONTERM_Rules + | NONTERM_rule + | NONTERM_args + | NONTERM_optbar + | NONTERM_clauses + | NONTERM_clause + | NONTERM_regexp + | NONTERM_charset + +// This function maps tokens to integer indexes +let tagOfToken (t:token) = + match t with + | EOF -> 0 + | BAR -> 1 + | DOT -> 2 + | PLUS -> 3 + | STAR -> 4 + | QMARK -> 5 + | EQUALS -> 6 + | UNDERSCORE -> 7 + | LBRACK -> 8 + | RBRACK -> 9 + | HAT -> 10 + | DASH -> 11 + | RULE -> 12 + | PARSE -> 13 + | LET -> 14 + | AND -> 15 + | LPAREN -> 16 + | RPAREN -> 17 + | UNICODE_CATEGORY _ -> 18 + | CHAR _ -> 19 + | CODE _ -> 20 + | STRING _ -> 21 + | IDENT _ -> 22 + +// This function maps integer indexes to symbolic token ids +let tokenTagToTokenId (tokenIdx:int) = + match tokenIdx with + | 0 -> TOKEN_EOF + | 1 -> TOKEN_BAR + | 2 -> TOKEN_DOT + | 3 -> TOKEN_PLUS + | 4 -> TOKEN_STAR + | 5 -> TOKEN_QMARK + | 6 -> TOKEN_EQUALS + | 7 -> TOKEN_UNDERSCORE + | 8 -> TOKEN_LBRACK + | 9 -> TOKEN_RBRACK + | 10 -> TOKEN_HAT + | 11 -> TOKEN_DASH + | 12 -> TOKEN_RULE + | 13 -> TOKEN_PARSE + | 14 -> TOKEN_LET + | 15 -> TOKEN_AND + | 16 -> TOKEN_LPAREN + | 17 -> TOKEN_RPAREN + | 18 -> TOKEN_UNICODE_CATEGORY + | 19 -> TOKEN_CHAR + | 20 -> TOKEN_CODE + | 21 -> TOKEN_STRING + | 22 -> TOKEN_IDENT + | 25 -> TOKEN_end_of_input + | 23 -> TOKEN_error + | _ -> failwith "tokenTagToTokenId: bad token" + +/// This function maps production indexes returned in syntax errors to strings representing the non terminal that would be produced by that production +let prodIdxToNonTerminal (prodIdx:int) = + match prodIdx with + | 0 -> NONTERM__startspec + | 1 -> NONTERM_spec + | 2 -> NONTERM_codeopt + | 3 -> NONTERM_codeopt + | 4 -> NONTERM_Macros + | 5 -> NONTERM_Macros + | 6 -> NONTERM_macro + | 7 -> NONTERM_Rules + | 8 -> NONTERM_Rules + | 9 -> NONTERM_rule + | 10 -> NONTERM_args + | 11 -> NONTERM_args + | 12 -> NONTERM_optbar + | 13 -> NONTERM_optbar + | 14 -> NONTERM_clauses + | 15 -> NONTERM_clauses + | 16 -> NONTERM_clause + | 17 -> NONTERM_regexp + | 18 -> NONTERM_regexp + | 19 -> NONTERM_regexp + | 20 -> NONTERM_regexp + | 21 -> NONTERM_regexp + | 22 -> NONTERM_regexp + | 23 -> NONTERM_regexp + | 24 -> NONTERM_regexp + | 25 -> NONTERM_regexp + | 26 -> NONTERM_regexp + | 27 -> NONTERM_regexp + | 28 -> NONTERM_regexp + | 29 -> NONTERM_regexp + | 30 -> NONTERM_regexp + | 31 -> NONTERM_charset + | 32 -> NONTERM_charset + | 33 -> NONTERM_charset + | _ -> failwith "prodIdxToNonTerminal: bad production index" + +let _fsyacc_endOfInputTag = 25 +let _fsyacc_tagOfErrorTerminal = 23 + +// This function gets the name of a token as a string +let token_to_string (t:token) = + match t with + | EOF -> "EOF" + | BAR -> "BAR" + | DOT -> "DOT" + | PLUS -> "PLUS" + | STAR -> "STAR" + | QMARK -> "QMARK" + | EQUALS -> "EQUALS" + | UNDERSCORE -> "UNDERSCORE" + | LBRACK -> "LBRACK" + | RBRACK -> "RBRACK" + | HAT -> "HAT" + | DASH -> "DASH" + | RULE -> "RULE" + | PARSE -> "PARSE" + | LET -> "LET" + | AND -> "AND" + | LPAREN -> "LPAREN" + | RPAREN -> "RPAREN" + | UNICODE_CATEGORY _ -> "UNICODE_CATEGORY" + | CHAR _ -> "CHAR" + | CODE _ -> "CODE" + | STRING _ -> "STRING" + | IDENT _ -> "IDENT" + +// This function gets the data carried by a token as an object +let _fsyacc_dataOfToken (t:token) = + match t with + | EOF -> (null : System.Object) + | BAR -> (null : System.Object) + | DOT -> (null : System.Object) + | PLUS -> (null : System.Object) + | STAR -> (null : System.Object) + | QMARK -> (null : System.Object) + | EQUALS -> (null : System.Object) + | UNDERSCORE -> (null : System.Object) + | LBRACK -> (null : System.Object) + | RBRACK -> (null : System.Object) + | HAT -> (null : System.Object) + | DASH -> (null : System.Object) + | RULE -> (null : System.Object) + | PARSE -> (null : System.Object) + | LET -> (null : System.Object) + | AND -> (null : System.Object) + | LPAREN -> (null : System.Object) + | RPAREN -> (null : System.Object) + | UNICODE_CATEGORY _fsyacc_x -> Microsoft.FSharp.Core.Operators.box _fsyacc_x + | CHAR _fsyacc_x -> Microsoft.FSharp.Core.Operators.box _fsyacc_x + | CODE _fsyacc_x -> Microsoft.FSharp.Core.Operators.box _fsyacc_x + | STRING _fsyacc_x -> Microsoft.FSharp.Core.Operators.box _fsyacc_x + | IDENT _fsyacc_x -> Microsoft.FSharp.Core.Operators.box _fsyacc_x +let _fsyacc_gotos = [| 0us; 65535us; 1us; 65535us; 0us; 1us; 2us; 65535us; 0us; 2us; 5us; 6us; 2us; 65535us; 2us; 3us; 8us; 9us; 2us; 65535us; 2us; 8us; 8us; 8us; 2us; 65535us; 4us; 5us; 15us; 16us; 2us; 65535us; 4us; 14us; 15us; 14us; 2us; 65535us; 17us; 18us; 23us; 24us; 1us; 65535us; 20us; 21us; 2us; 65535us; 21us; 22us; 27us; 28us; 2us; 65535us; 21us; 26us; 27us; 26us; 10us; 65535us; 12us; 13us; 13us; 37us; 21us; 29us; 27us; 29us; 29us; 37us; 37us; 37us; 38us; 37us; 39us; 37us; 43us; 38us; 44us; 39us; 5us; 65535us; 46us; 47us; 47us; 55us; 49us; 50us; 50us; 55us; 55us; 55us; |] +let _fsyacc_sparseGotoTableRowOffsets = [|0us; 1us; 3us; 6us; 9us; 12us; 15us; 18us; 21us; 23us; 26us; 29us; 40us; |] +let _fsyacc_stateToProdIdxsTableElements = [| 1us; 0us; 1us; 0us; 1us; 1us; 1us; 1us; 1us; 1us; 1us; 1us; 1us; 1us; 1us; 2us; 1us; 5us; 1us; 5us; 1us; 6us; 1us; 6us; 1us; 6us; 6us; 6us; 23us; 24us; 25us; 26us; 27us; 2us; 7us; 8us; 1us; 7us; 1us; 7us; 1us; 9us; 1us; 9us; 1us; 9us; 1us; 9us; 1us; 9us; 1us; 9us; 1us; 11us; 1us; 11us; 1us; 13us; 2us; 14us; 15us; 1us; 14us; 1us; 14us; 6us; 16us; 23us; 24us; 25us; 26us; 27us; 1us; 16us; 1us; 17us; 1us; 18us; 1us; 19us; 1us; 20us; 1us; 21us; 1us; 22us; 6us; 23us; 23us; 24us; 25us; 26us; 27us; 6us; 23us; 24us; 25us; 26us; 27us; 27us; 6us; 23us; 24us; 25us; 26us; 27us; 28us; 1us; 24us; 1us; 25us; 1us; 26us; 1us; 27us; 1us; 28us; 1us; 28us; 2us; 29us; 30us; 2us; 29us; 33us; 1us; 29us; 1us; 30us; 2us; 30us; 33us; 1us; 30us; 2us; 31us; 32us; 1us; 32us; 1us; 32us; 2us; 33us; 33us; |] +let _fsyacc_stateToProdIdxsTableRowOffsets = [|0us; 2us; 4us; 6us; 8us; 10us; 12us; 14us; 16us; 18us; 20us; 22us; 24us; 26us; 33us; 36us; 38us; 40us; 42us; 44us; 46us; 48us; 50us; 52us; 54us; 56us; 58us; 61us; 63us; 65us; 72us; 74us; 76us; 78us; 80us; 82us; 84us; 86us; 93us; 100us; 107us; 109us; 111us; 113us; 115us; 117us; 119us; 122us; 125us; 127us; 129us; 132us; 134us; 137us; 139us; 141us; |] +let _fsyacc_action_rows = 56 +let _fsyacc_actionTableElements = [|1us; 16387us; 20us; 7us; 0us; 49152us; 1us; 16388us; 14us; 10us; 1us; 32768us; 12us; 4us; 1us; 32768us; 22us; 17us; 1us; 16387us; 20us; 7us; 0us; 16385us; 0us; 16386us; 1us; 16388us; 14us; 10us; 0us; 16389us; 1us; 32768us; 22us; 11us; 1us; 32768us; 6us; 12us; 8us; 32768us; 0us; 33us; 7us; 34us; 8us; 46us; 16us; 44us; 18us; 32us; 19us; 31us; 21us; 35us; 22us; 36us; 12us; 16390us; 0us; 33us; 1us; 43us; 3us; 40us; 4us; 41us; 5us; 42us; 7us; 34us; 8us; 46us; 16us; 44us; 18us; 32us; 19us; 31us; 21us; 35us; 22us; 36us; 1us; 16392us; 15us; 15us; 1us; 32768us; 22us; 17us; 0us; 16391us; 1us; 16394us; 22us; 23us; 1us; 32768us; 6us; 19us; 1us; 32768us; 13us; 20us; 1us; 16396us; 1us; 25us; 8us; 32768us; 0us; 33us; 7us; 34us; 8us; 46us; 16us; 44us; 18us; 32us; 19us; 31us; 21us; 35us; 22us; 36us; 0us; 16393us; 1us; 16394us; 22us; 23us; 0us; 16395us; 0us; 16397us; 1us; 16399us; 1us; 27us; 8us; 32768us; 0us; 33us; 7us; 34us; 8us; 46us; 16us; 44us; 18us; 32us; 19us; 31us; 21us; 35us; 22us; 36us; 0us; 16398us; 13us; 32768us; 0us; 33us; 1us; 43us; 3us; 40us; 4us; 41us; 5us; 42us; 7us; 34us; 8us; 46us; 16us; 44us; 18us; 32us; 19us; 31us; 20us; 30us; 21us; 35us; 22us; 36us; 0us; 16400us; 0us; 16401us; 0us; 16402us; 0us; 16403us; 0us; 16404us; 0us; 16405us; 0us; 16406us; 11us; 16407us; 0us; 33us; 3us; 40us; 4us; 41us; 5us; 42us; 7us; 34us; 8us; 46us; 16us; 44us; 18us; 32us; 19us; 31us; 21us; 35us; 22us; 36us; 11us; 16411us; 0us; 33us; 3us; 40us; 4us; 41us; 5us; 42us; 7us; 34us; 8us; 46us; 16us; 44us; 18us; 32us; 19us; 31us; 21us; 35us; 22us; 36us; 13us; 32768us; 0us; 33us; 1us; 43us; 3us; 40us; 4us; 41us; 5us; 42us; 7us; 34us; 8us; 46us; 16us; 44us; 17us; 45us; 18us; 32us; 19us; 31us; 21us; 35us; 22us; 36us; 0us; 16408us; 0us; 16409us; 0us; 16410us; 8us; 32768us; 0us; 33us; 7us; 34us; 8us; 46us; 16us; 44us; 18us; 32us; 19us; 31us; 21us; 35us; 22us; 36us; 8us; 32768us; 0us; 33us; 7us; 34us; 8us; 46us; 16us; 44us; 18us; 32us; 19us; 31us; 21us; 35us; 22us; 36us; 0us; 16412us; 2us; 32768us; 10us; 49us; 19us; 52us; 2us; 32768us; 9us; 48us; 19us; 52us; 0us; 16413us; 1us; 32768us; 19us; 52us; 2us; 32768us; 9us; 51us; 19us; 52us; 0us; 16414us; 1us; 16415us; 11us; 53us; 1us; 32768us; 19us; 54us; 0us; 16416us; 1us; 16417us; 19us; 52us; |] +let _fsyacc_actionTableRowOffsets = [|0us; 2us; 3us; 5us; 7us; 9us; 11us; 12us; 13us; 15us; 16us; 18us; 20us; 29us; 42us; 44us; 46us; 47us; 49us; 51us; 53us; 55us; 64us; 65us; 67us; 68us; 69us; 71us; 80us; 81us; 95us; 96us; 97us; 98us; 99us; 100us; 101us; 102us; 114us; 126us; 140us; 141us; 142us; 143us; 152us; 161us; 162us; 165us; 168us; 169us; 171us; 174us; 175us; 177us; 179us; 180us; |] +let _fsyacc_reductionSymbolCounts = [|1us; 5us; 1us; 0us; 0us; 2us; 4us; 3us; 1us; 6us; 0us; 2us; 0us; 1us; 3us; 1us; 2us; 1us; 1us; 1us; 1us; 1us; 1us; 2us; 2us; 2us; 2us; 3us; 3us; 3us; 4us; 1us; 3us; 2us; |] +let _fsyacc_productionToNonTerminalTable = [|0us; 1us; 2us; 2us; 3us; 3us; 4us; 5us; 5us; 6us; 7us; 7us; 8us; 8us; 9us; 9us; 10us; 11us; 11us; 11us; 11us; 11us; 11us; 11us; 11us; 11us; 11us; 11us; 11us; 11us; 11us; 12us; 12us; 12us; |] +let _fsyacc_immediateActions = [|65535us; 49152us; 65535us; 65535us; 65535us; 65535us; 16385us; 16386us; 65535us; 16389us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 16391us; 65535us; 65535us; 65535us; 65535us; 65535us; 16393us; 65535us; 16395us; 16397us; 65535us; 65535us; 16398us; 65535us; 16400us; 16401us; 16402us; 16403us; 16404us; 16405us; 16406us; 65535us; 65535us; 65535us; 16408us; 16409us; 16410us; 65535us; 65535us; 16412us; 65535us; 65535us; 16413us; 65535us; 65535us; 16414us; 65535us; 65535us; 16416us; 65535us; |] +let _fsyacc_reductions () = [| +# 246 "fslexpars.fs" + (fun (parseState : Internal.Utilities.Text.Parsing.IParseState) -> + let _1 = (let data = parseState.GetInput(1) in (Microsoft.FSharp.Core.Operators.unbox data : AST.Spec)) in + Microsoft.FSharp.Core.Operators.box + ( + ( + raise (Internal.Utilities.Text.Parsing.Accept(Microsoft.FSharp.Core.Operators.box _1)) + ) + : '_startspec)); +# 255 "fslexpars.fs" + (fun (parseState : Internal.Utilities.Text.Parsing.IParseState) -> + let _1 = (let data = parseState.GetInput(1) in (Microsoft.FSharp.Core.Operators.unbox data : 'codeopt)) in + let _2 = (let data = parseState.GetInput(2) in (Microsoft.FSharp.Core.Operators.unbox data : 'Macros)) in + let _4 = (let data = parseState.GetInput(4) in (Microsoft.FSharp.Core.Operators.unbox data : 'Rules)) in + let _5 = (let data = parseState.GetInput(5) in (Microsoft.FSharp.Core.Operators.unbox data : 'codeopt)) in + Microsoft.FSharp.Core.Operators.box + ( + ( +# 24 "fslexpars.fsy" + { TopCode=_1;Macros=_2;Rules=_4;BottomCode=_5 } + ) +# 24 "fslexpars.fsy" + : AST.Spec)); +# 269 "fslexpars.fs" + (fun (parseState : Internal.Utilities.Text.Parsing.IParseState) -> + let _1 = (let data = parseState.GetInput(1) in (Microsoft.FSharp.Core.Operators.unbox data : AST.Code)) in + Microsoft.FSharp.Core.Operators.box + ( + ( +# 25 "fslexpars.fsy" + _1 + ) +# 25 "fslexpars.fsy" + : 'codeopt)); +# 280 "fslexpars.fs" + (fun (parseState : Internal.Utilities.Text.Parsing.IParseState) -> + Microsoft.FSharp.Core.Operators.box + ( + ( +# 25 "fslexpars.fsy" + "", (parseState.ResultRange |> fst) + ) +# 25 "fslexpars.fsy" + : 'codeopt)); +# 290 "fslexpars.fs" + (fun (parseState : Internal.Utilities.Text.Parsing.IParseState) -> + Microsoft.FSharp.Core.Operators.box + ( + ( +# 26 "fslexpars.fsy" + [] + ) +# 26 "fslexpars.fsy" + : 'Macros)); +# 300 "fslexpars.fs" + (fun (parseState : Internal.Utilities.Text.Parsing.IParseState) -> + let _1 = (let data = parseState.GetInput(1) in (Microsoft.FSharp.Core.Operators.unbox data : 'macro)) in + let _2 = (let data = parseState.GetInput(2) in (Microsoft.FSharp.Core.Operators.unbox data : 'Macros)) in + Microsoft.FSharp.Core.Operators.box + ( + ( +# 26 "fslexpars.fsy" + _1 :: _2 + ) +# 26 "fslexpars.fsy" + : 'Macros)); +# 312 "fslexpars.fs" + (fun (parseState : Internal.Utilities.Text.Parsing.IParseState) -> + let _2 = (let data = parseState.GetInput(2) in (Microsoft.FSharp.Core.Operators.unbox data : string)) in + let _4 = (let data = parseState.GetInput(4) in (Microsoft.FSharp.Core.Operators.unbox data : 'regexp)) in + Microsoft.FSharp.Core.Operators.box + ( + ( +# 27 "fslexpars.fsy" + (_2, _4) + ) +# 27 "fslexpars.fsy" + : 'macro)); +# 324 "fslexpars.fs" + (fun (parseState : Internal.Utilities.Text.Parsing.IParseState) -> + let _1 = (let data = parseState.GetInput(1) in (Microsoft.FSharp.Core.Operators.unbox data : 'rule)) in + let _3 = (let data = parseState.GetInput(3) in (Microsoft.FSharp.Core.Operators.unbox data : 'Rules)) in + Microsoft.FSharp.Core.Operators.box + ( + ( +# 28 "fslexpars.fsy" + _1 :: _3 + ) +# 28 "fslexpars.fsy" + : 'Rules)); +# 336 "fslexpars.fs" + (fun (parseState : Internal.Utilities.Text.Parsing.IParseState) -> + let _1 = (let data = parseState.GetInput(1) in (Microsoft.FSharp.Core.Operators.unbox data : 'rule)) in + Microsoft.FSharp.Core.Operators.box + ( + ( +# 28 "fslexpars.fsy" + [_1] + ) +# 28 "fslexpars.fsy" + : 'Rules)); +# 347 "fslexpars.fs" + (fun (parseState : Internal.Utilities.Text.Parsing.IParseState) -> + let _1 = (let data = parseState.GetInput(1) in (Microsoft.FSharp.Core.Operators.unbox data : string)) in + let _2 = (let data = parseState.GetInput(2) in (Microsoft.FSharp.Core.Operators.unbox data : 'args)) in + let _5 = (let data = parseState.GetInput(5) in (Microsoft.FSharp.Core.Operators.unbox data : 'optbar)) in + let _6 = (let data = parseState.GetInput(6) in (Microsoft.FSharp.Core.Operators.unbox data : 'clauses)) in + Microsoft.FSharp.Core.Operators.box + ( + ( +# 29 "fslexpars.fsy" + (_1,_2,_6) + ) +# 29 "fslexpars.fsy" + : 'rule)); +# 361 "fslexpars.fs" + (fun (parseState : Internal.Utilities.Text.Parsing.IParseState) -> + Microsoft.FSharp.Core.Operators.box + ( + ( +# 30 "fslexpars.fsy" + [] + ) +# 30 "fslexpars.fsy" + : 'args)); +# 371 "fslexpars.fs" + (fun (parseState : Internal.Utilities.Text.Parsing.IParseState) -> + let _1 = (let data = parseState.GetInput(1) in (Microsoft.FSharp.Core.Operators.unbox data : string)) in + let _2 = (let data = parseState.GetInput(2) in (Microsoft.FSharp.Core.Operators.unbox data : 'args)) in + Microsoft.FSharp.Core.Operators.box + ( + ( +# 30 "fslexpars.fsy" + _1 :: _2 + ) +# 30 "fslexpars.fsy" + : 'args)); +# 383 "fslexpars.fs" + (fun (parseState : Internal.Utilities.Text.Parsing.IParseState) -> + Microsoft.FSharp.Core.Operators.box + ( + ( +# 31 "fslexpars.fsy" + + ) +# 31 "fslexpars.fsy" + : 'optbar)); +# 393 "fslexpars.fs" + (fun (parseState : Internal.Utilities.Text.Parsing.IParseState) -> + Microsoft.FSharp.Core.Operators.box + ( + ( +# 31 "fslexpars.fsy" + + ) +# 31 "fslexpars.fsy" + : 'optbar)); +# 403 "fslexpars.fs" + (fun (parseState : Internal.Utilities.Text.Parsing.IParseState) -> + let _1 = (let data = parseState.GetInput(1) in (Microsoft.FSharp.Core.Operators.unbox data : 'clause)) in + let _3 = (let data = parseState.GetInput(3) in (Microsoft.FSharp.Core.Operators.unbox data : 'clauses)) in + Microsoft.FSharp.Core.Operators.box + ( + ( +# 32 "fslexpars.fsy" + _1 :: _3 + ) +# 32 "fslexpars.fsy" + : 'clauses)); +# 415 "fslexpars.fs" + (fun (parseState : Internal.Utilities.Text.Parsing.IParseState) -> + let _1 = (let data = parseState.GetInput(1) in (Microsoft.FSharp.Core.Operators.unbox data : 'clause)) in + Microsoft.FSharp.Core.Operators.box + ( + ( +# 32 "fslexpars.fsy" + [_1] + ) +# 32 "fslexpars.fsy" + : 'clauses)); +# 426 "fslexpars.fs" + (fun (parseState : Internal.Utilities.Text.Parsing.IParseState) -> + let _1 = (let data = parseState.GetInput(1) in (Microsoft.FSharp.Core.Operators.unbox data : 'regexp)) in + let _2 = (let data = parseState.GetInput(2) in (Microsoft.FSharp.Core.Operators.unbox data : AST.Code)) in + Microsoft.FSharp.Core.Operators.box + ( + ( +# 33 "fslexpars.fsy" + _1, _2 + ) +# 33 "fslexpars.fsy" + : 'clause)); +# 438 "fslexpars.fs" + (fun (parseState : Internal.Utilities.Text.Parsing.IParseState) -> + let _1 = (let data = parseState.GetInput(1) in (Microsoft.FSharp.Core.Operators.unbox data : char)) in + Microsoft.FSharp.Core.Operators.box + ( + ( +# 35 "fslexpars.fsy" + Inp(Alphabet(EncodeChar _1)) + ) +# 35 "fslexpars.fsy" + : 'regexp)); +# 449 "fslexpars.fs" + (fun (parseState : Internal.Utilities.Text.Parsing.IParseState) -> + let _1 = (let data = parseState.GetInput(1) in (Microsoft.FSharp.Core.Operators.unbox data : string)) in + Microsoft.FSharp.Core.Operators.box + ( + ( +# 36 "fslexpars.fsy" + Inp(UnicodeCategory _1) + ) +# 36 "fslexpars.fsy" + : 'regexp)); +# 460 "fslexpars.fs" + (fun (parseState : Internal.Utilities.Text.Parsing.IParseState) -> + Microsoft.FSharp.Core.Operators.box + ( + ( +# 37 "fslexpars.fsy" + Inp(Alphabet(Eof)) + ) +# 37 "fslexpars.fsy" + : 'regexp)); +# 470 "fslexpars.fs" + (fun (parseState : Internal.Utilities.Text.Parsing.IParseState) -> + Microsoft.FSharp.Core.Operators.box + ( + ( +# 38 "fslexpars.fsy" + Inp Any + ) +# 38 "fslexpars.fsy" + : 'regexp)); +# 480 "fslexpars.fs" + (fun (parseState : Internal.Utilities.Text.Parsing.IParseState) -> + let _1 = (let data = parseState.GetInput(1) in (Microsoft.FSharp.Core.Operators.unbox data : string)) in + Microsoft.FSharp.Core.Operators.box + ( + ( +# 39 "fslexpars.fsy" + Seq([ for n in 0 .. _1.Length - 1 -> Inp(Alphabet(EncodeChar _1.[n]))]) + ) +# 39 "fslexpars.fsy" + : 'regexp)); +# 491 "fslexpars.fs" + (fun (parseState : Internal.Utilities.Text.Parsing.IParseState) -> + let _1 = (let data = parseState.GetInput(1) in (Microsoft.FSharp.Core.Operators.unbox data : string)) in + Microsoft.FSharp.Core.Operators.box + ( + ( +# 40 "fslexpars.fsy" + Macro(_1) + ) +# 40 "fslexpars.fsy" + : 'regexp)); +# 502 "fslexpars.fs" + (fun (parseState : Internal.Utilities.Text.Parsing.IParseState) -> + let _1 = (let data = parseState.GetInput(1) in (Microsoft.FSharp.Core.Operators.unbox data : 'regexp)) in + let _2 = (let data = parseState.GetInput(2) in (Microsoft.FSharp.Core.Operators.unbox data : 'regexp)) in + Microsoft.FSharp.Core.Operators.box + ( + ( +# 41 "fslexpars.fsy" + Seq[_1;_2] + ) +# 41 "fslexpars.fsy" + : 'regexp)); +# 514 "fslexpars.fs" + (fun (parseState : Internal.Utilities.Text.Parsing.IParseState) -> + let _1 = (let data = parseState.GetInput(1) in (Microsoft.FSharp.Core.Operators.unbox data : 'regexp)) in + Microsoft.FSharp.Core.Operators.box + ( + ( +# 42 "fslexpars.fsy" + Seq[_1;Star _1] + ) +# 42 "fslexpars.fsy" + : 'regexp)); +# 525 "fslexpars.fs" + (fun (parseState : Internal.Utilities.Text.Parsing.IParseState) -> + let _1 = (let data = parseState.GetInput(1) in (Microsoft.FSharp.Core.Operators.unbox data : 'regexp)) in + Microsoft.FSharp.Core.Operators.box + ( + ( +# 43 "fslexpars.fsy" + Star _1 + ) +# 43 "fslexpars.fsy" + : 'regexp)); +# 536 "fslexpars.fs" + (fun (parseState : Internal.Utilities.Text.Parsing.IParseState) -> + let _1 = (let data = parseState.GetInput(1) in (Microsoft.FSharp.Core.Operators.unbox data : 'regexp)) in + Microsoft.FSharp.Core.Operators.box + ( + ( +# 44 "fslexpars.fsy" + Alt[Seq[];_1] + ) +# 44 "fslexpars.fsy" + : 'regexp)); +# 547 "fslexpars.fs" + (fun (parseState : Internal.Utilities.Text.Parsing.IParseState) -> + let _1 = (let data = parseState.GetInput(1) in (Microsoft.FSharp.Core.Operators.unbox data : 'regexp)) in + let _3 = (let data = parseState.GetInput(3) in (Microsoft.FSharp.Core.Operators.unbox data : 'regexp)) in + Microsoft.FSharp.Core.Operators.box + ( + ( +# 45 "fslexpars.fsy" + Alt[_1;_3] + ) +# 45 "fslexpars.fsy" + : 'regexp)); +# 559 "fslexpars.fs" + (fun (parseState : Internal.Utilities.Text.Parsing.IParseState) -> + let _2 = (let data = parseState.GetInput(2) in (Microsoft.FSharp.Core.Operators.unbox data : 'regexp)) in + Microsoft.FSharp.Core.Operators.box + ( + ( +# 46 "fslexpars.fsy" + _2 + ) +# 46 "fslexpars.fsy" + : 'regexp)); +# 570 "fslexpars.fs" + (fun (parseState : Internal.Utilities.Text.Parsing.IParseState) -> + let _2 = (let data = parseState.GetInput(2) in (Microsoft.FSharp.Core.Operators.unbox data : 'charset)) in + Microsoft.FSharp.Core.Operators.box + ( + ( +# 47 "fslexpars.fsy" + Alt [ for c in _2 -> Inp(Alphabet(c)) ] + ) +# 47 "fslexpars.fsy" + : 'regexp)); +# 581 "fslexpars.fs" + (fun (parseState : Internal.Utilities.Text.Parsing.IParseState) -> + let _3 = (let data = parseState.GetInput(3) in (Microsoft.FSharp.Core.Operators.unbox data : 'charset)) in + Microsoft.FSharp.Core.Operators.box + ( + ( +# 48 "fslexpars.fsy" + Inp(NotCharSet(_3)) + ) +# 48 "fslexpars.fsy" + : 'regexp)); +# 592 "fslexpars.fs" + (fun (parseState : Internal.Utilities.Text.Parsing.IParseState) -> + let _1 = (let data = parseState.GetInput(1) in (Microsoft.FSharp.Core.Operators.unbox data : char)) in + Microsoft.FSharp.Core.Operators.box + ( + ( +# 51 "fslexpars.fsy" + Set.singleton(EncodeChar _1) + ) +# 51 "fslexpars.fsy" + : 'charset)); +# 603 "fslexpars.fs" + (fun (parseState : Internal.Utilities.Text.Parsing.IParseState) -> + let _1 = (let data = parseState.GetInput(1) in (Microsoft.FSharp.Core.Operators.unbox data : char)) in + let _3 = (let data = parseState.GetInput(3) in (Microsoft.FSharp.Core.Operators.unbox data : char)) in + Microsoft.FSharp.Core.Operators.box + ( + ( +# 52 "fslexpars.fsy" + Set.ofSeq [ for c in _1 .. _3 -> EncodeChar c ] + ) +# 52 "fslexpars.fsy" + : 'charset)); +# 615 "fslexpars.fs" + (fun (parseState : Internal.Utilities.Text.Parsing.IParseState) -> + let _1 = (let data = parseState.GetInput(1) in (Microsoft.FSharp.Core.Operators.unbox data : 'charset)) in + let _2 = (let data = parseState.GetInput(2) in (Microsoft.FSharp.Core.Operators.unbox data : 'charset)) in + Microsoft.FSharp.Core.Operators.box + ( + ( +# 53 "fslexpars.fsy" + Set.union _1 _2 + ) +# 53 "fslexpars.fsy" + : 'charset)); +|] +# 628 "fslexpars.fs" +let tables () : Internal.Utilities.Text.Parsing.Tables<_> = + { reductions= _fsyacc_reductions (); + endOfInputTag = _fsyacc_endOfInputTag; + tagOfToken = tagOfToken; + dataOfToken = _fsyacc_dataOfToken; + actionTableElements = _fsyacc_actionTableElements; + actionTableRowOffsets = _fsyacc_actionTableRowOffsets; + stateToProdIdxsTableElements = _fsyacc_stateToProdIdxsTableElements; + stateToProdIdxsTableRowOffsets = _fsyacc_stateToProdIdxsTableRowOffsets; + reductionSymbolCounts = _fsyacc_reductionSymbolCounts; + immediateActions = _fsyacc_immediateActions; + gotos = _fsyacc_gotos; + sparseGotoTableRowOffsets = _fsyacc_sparseGotoTableRowOffsets; + tagOfErrorTerminal = _fsyacc_tagOfErrorTerminal; + parseError = (fun (ctxt:Internal.Utilities.Text.Parsing.ParseErrorContext<_>) -> + match parse_error_rich with + | Some f -> f ctxt + | None -> parse_error ctxt.Message); + numTerminals = 26; + productionToNonTerminalTable = _fsyacc_productionToNonTerminalTable } +let engine lexer lexbuf startState = (tables ()).Interpret(lexer, lexbuf, startState) +let spec lexer lexbuf : AST.Spec = + Microsoft.FSharp.Core.Operators.unbox ((tables ()).Interpret(lexer, lexbuf, 0)) diff --git a/src/buildtools/fsyacc/App.config b/src/buildtools/fsyacc/App.config new file mode 100644 index 0000000000..e1b09eda9f --- /dev/null +++ b/src/buildtools/fsyacc/App.config @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/buildtools/fsyacc/Arg.fs b/src/buildtools/fsyacc/Arg.fs new file mode 100644 index 0000000000..a1f63bd963 --- /dev/null +++ b/src/buildtools/fsyacc/Arg.fs @@ -0,0 +1,133 @@ +// (c) Microsoft Corporation 2005-2009. + +#if INTERNALIZED_FSLEXYACC_RUNTIME +namespace Internal.Utilities +#else +namespace Microsoft.FSharp.Text +#endif + + +type ArgType = + | ClearArg of bool ref + | FloatArg of (float -> unit) + | IntArg of (int -> unit) + | RestArg of (string -> unit) + | SetArg of bool ref + | StringArg of (string -> unit) + | UnitArg of (unit -> unit) + static member Clear r = ClearArg r + static member Float r = FloatArg r + static member Int r = IntArg r + static member Rest r = RestArg r + static member Set r = SetArg r + static member String r = StringArg r + static member Unit r = UnitArg r + + +type ArgInfo (name,action,help) = + member x.Name = name + member x.ArgType = action + member x.HelpText = help + +exception Bad of string +exception HelpText of string + +[] +type ArgParser() = + static let getUsage specs u = + let sbuf = new System.Text.StringBuilder 100 + let pstring (s:string) = sbuf.Append s |> ignore + let pendline s = pstring s; pstring "\n" + pendline u; + List.iter (fun (arg:ArgInfo) -> + match arg.Name, arg.ArgType, arg.HelpText with + | (s, (UnitArg _ | SetArg _ | ClearArg _), helpText) -> pstring "\t"; pstring s; pstring ": "; pendline helpText + | (s, StringArg _, helpText) -> pstring "\t"; pstring s; pstring " : "; pendline helpText + | (s, IntArg _, helpText) -> pstring "\t"; pstring s; pstring " : "; pendline helpText + | (s, FloatArg _, helpText) -> pstring "\t"; pstring s; pstring " : "; pendline helpText + | (s, RestArg _, helpText) -> pstring "\t"; pstring s; pstring " ...: "; pendline helpText) + specs; + pstring "\t"; pstring "--help"; pstring ": "; pendline "display this list of options"; + pstring "\t"; pstring "-help"; pstring ": "; pendline "display this list of options"; + sbuf.ToString() + + + static member ParsePartial(cursor,argv,argSpecs:seq,?other,?usageText) = + let other = defaultArg other (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) + while !cursor < nargs do + let arg = argv.[!cursor] + let rec findMatchingArg args = + match args with + | ((s, action) :: _) when s = arg -> + let getSecondArg () = + if !cursor + 1 >= nargs then + raise(Bad("option "+s+" needs an argument.\n"+getUsage argSpecs usageText)); + argv.[!cursor+1] + + match action with + | UnitArg f -> + f (); + incr cursor + | SetArg f -> + f := true; + incr cursor + | ClearArg f -> + f := false; + incr cursor + | StringArg f-> + let arg2 = getSecondArg() + f arg2; + cursor := !cursor + 2 + | IntArg f -> + let arg2 = getSecondArg () + let arg2 = try int32 arg2 with _ -> raise(Bad(getUsage argSpecs usageText)) in + f arg2; + cursor := !cursor + 2; + | FloatArg f -> + let arg2 = getSecondArg() + let arg2 = try float arg2 with _ -> raise(Bad(getUsage argSpecs usageText)) in + f arg2; + cursor := !cursor + 2; + | RestArg f -> + incr cursor; + while !cursor < nargs do + f (argv.[!cursor]); + incr cursor; + + | (_ :: more) -> findMatchingArg more + | [] -> + if arg = "-help" || arg = "--help" || arg = "/help" || arg = "/help" || arg = "/?" then + raise (HelpText (getUsage argSpecs 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)) + else + other arg; + incr cursor + findMatchingArg specs + + static member Usage (specs,?usage) = + let usage = defaultArg usage "" + System.Console.Error.WriteLine (getUsage (Seq.toList specs) usage) + + #if FX_NO_COMMAND_LINE_ARGS + #else + static member Parse (specs,?other,?usageText) = + let current = ref 0 + let argv = System.Environment.GetCommandLineArgs() + try ArgParser.ParsePartial (current, argv, specs, ?other=other, ?usageText=usageText) + with + | Bad h + | HelpText h -> + System.Console.Error.WriteLine h; + System.Console.Error.Flush(); + System.Environment.Exit(1); + | e -> + reraise() + #endif diff --git a/src/buildtools/fsyacc/Arg.fsi b/src/buildtools/fsyacc/Arg.fsi new file mode 100644 index 0000000000..367f69f959 --- /dev/null +++ b/src/buildtools/fsyacc/Arg.fsi @@ -0,0 +1,50 @@ +// (c) Microsoft Corporation 2005-2009. + +/// A simple command-line argument processor. +#if INTERNALIZED_FSLEXYACC_RUNTIME +namespace Internal.Utilities +#else +namespace Microsoft.FSharp.Text +#endif + +/// The spec value describes the action of the argument, +/// and whether it expects a following parameter. +[] +type ArgType = + static member Clear : bool ref -> ArgType + static member Float : (float -> unit) -> ArgType + static member Int : (int -> unit) -> ArgType + static member Rest : (string -> unit) -> ArgType + static member Set : bool ref -> ArgType + static member String : (string -> unit) -> ArgType + static member Unit : (unit -> unit) -> ArgType + +type ArgInfo = + new : name:string * action:ArgType * help:string -> ArgInfo + /// Return the name of the argument + member Name : string + /// Return the argument type and action of the argument + member ArgType : ArgType + /// Return the usage help associated with the argument + member HelpText : string + +[] +type ArgParser = + #if FX_NO_COMMAND_LINE_ARGS + #else + + /// Parse some of the arguments given by 'argv', starting at the given position + [] + static member ParsePartial: cursor: int ref * argv: string[] * arguments:seq * ?otherArgs: (string -> unit) * ?usageText:string -> unit + + /// Parse the arguments given by System.Environment.GetEnvironmentVariables() + /// according to the argument processing specifications "specs". + /// Args begin with "-". Non-arguments are passed to "f" in + /// order. "use" is printed as part of the usage line if an error occurs. + + static member Parse: arguments:seq * ?otherArgs: (string -> unit) * ?usageText:string -> unit + #endif + + /// Prints the help for each argument. + static member Usage : arguments:seq * ?usage:string -> unit + diff --git a/src/buildtools/fsyacc/Lexing.fs b/src/buildtools/fsyacc/Lexing.fs new file mode 100644 index 0000000000..8337717d6f --- /dev/null +++ b/src/buildtools/fsyacc/Lexing.fs @@ -0,0 +1,423 @@ +// (c) Microsoft Corporation 2005-2009. + +#nowarn "47" // recursive initialization of LexBuffer + + +#if INTERNALIZED_FSLEXYACC_RUNTIME +namespace Internal.Utilities.Text.Lexing + +#else +namespace Microsoft.FSharp.Text.Lexing +#endif + + open System.Collections.Generic + + // REVIEW: This type showed up on a parsing-intensive performance measurement. Consider whether it can be a struct-record later when we have this feature. -jomo +#if INTERNALIZED_FSLEXYACC_RUNTIME + type internal Position = +#else + type Position = +#endif + { pos_fname : string; + pos_lnum : int; +#if INTERNALIZED_FSLEXYACC_RUNTIME + pos_orig_lnum : int; +#endif + pos_bol : int; + pos_cnum : int; } + member x.FileName = x.pos_fname + member x.Line = x.pos_lnum +#if INTERNALIZED_FSLEXYACC_RUNTIME + member x.OriginalLine = x.pos_orig_lnum +#endif + member x.Char = x.pos_cnum + member x.AbsoluteOffset = x.pos_cnum + member x.StartOfLine = x.pos_bol + member x.StartOfLineAbsoluteOffset = x.pos_bol + member x.Column = x.pos_cnum - x.pos_bol + member pos.NextLine = + { pos with +#if INTERNALIZED_FSLEXYACC_RUNTIME + pos_orig_lnum = pos.OriginalLine + 1; +#endif + pos_lnum = pos.Line+1; + pos_bol = pos.AbsoluteOffset } + member pos.EndOfToken(n) = {pos with pos_cnum=pos.pos_cnum + n } + member pos.AsNewLinePos() = pos.NextLine + member pos.ShiftColumnBy(by) = {pos with pos_cnum = pos.pos_cnum + by} + static member Empty = + { pos_fname=""; + pos_lnum= 0; +#if INTERNALIZED_FSLEXYACC_RUNTIME + pos_orig_lnum = 0; +#endif + pos_bol= 0; + pos_cnum=0 } + static member FirstLine(filename) = + { pos_fname=filename; +#if INTERNALIZED_FSLEXYACC_RUNTIME + pos_orig_lnum = 1; +#endif + pos_lnum= 1; + pos_bol= 0; + pos_cnum=0 } + +#if INTERNALIZED_FSLEXYACC_RUNTIME + type internal LexBufferFiller<'char> = +#else + type LexBufferFiller<'char> = +#endif + { fillSync : (LexBuffer<'char> -> unit) option + fillAsync : (LexBuffer<'char> -> Async) option } + + and [] +#if INTERNALIZED_FSLEXYACC_RUNTIME + internal LexBuffer<'char>(filler: LexBufferFiller<'char>) as this = +#else + LexBuffer<'char>(filler: LexBufferFiller<'char>) as this = +#endif + let context = new Dictionary(1) in + let extendBufferSync = (fun () -> match filler.fillSync with Some refill -> refill this | None -> invalidOp "attempt to read synchronously from an asynchronous lex buffer") + let extendBufferAsync = (fun () -> match filler.fillAsync with Some refill -> refill this | None -> invalidOp "attempt to read asynchronously from a synchronous lex buffer") + let mutable buffer=[||]; + /// number of valid charactes beyond bufferScanStart + let mutable bufferMaxScanLength=0; + /// count into the buffer when scanning + let mutable bufferScanStart=0; + /// number of characters scanned so far + let mutable bufferScanLength=0; + /// length of the scan at the last accepting state + let mutable lexemeLength=0; + /// action related to the last accepting state + let mutable bufferAcceptAction=0; + let mutable eof = false; + let mutable startPos = Position.Empty ; + let mutable endPos = Position.Empty + + // Throw away all the input besides the lexeme + + let discardInput () = + let keep = Array.sub buffer bufferScanStart bufferScanLength + let nkeep = keep.Length + Array.blit keep 0 buffer 0 nkeep; + bufferScanStart <- 0; + bufferMaxScanLength <- nkeep + + + member lexbuf.EndOfScan () : int = + // Printf.eprintf "endOfScan, lexBuffer.lexemeLength = %d\n" lexBuffer.lexemeLength; + if bufferAcceptAction < 0 then + failwith "unrecognized input" + + // Printf.printf "endOfScan %d state %d on unconsumed input '%c' (%d)\n" a s (Char.chr inp) inp; + // Printf.eprintf "accept, lexeme = %s\n" (lexeme lexBuffer); + lexbuf.StartPos <- endPos; + lexbuf.EndPos <- endPos.EndOfToken(lexbuf.LexemeLength); + bufferAcceptAction + + member lexbuf.StartPos + with get() = startPos + and set(b) = startPos <- b + + member lexbuf.EndPos + with get() = endPos + and set(b) = endPos <- b + + member lexbuf.Lexeme = Array.sub buffer bufferScanStart lexemeLength + member lexbuf.LexemeChar(n) = buffer.[n+bufferScanStart] + + member lexbuf.BufferLocalStore = (context :> IDictionary<_,_>) + member lexbuf.LexemeLength with get() : int = lexemeLength and set v = lexemeLength <- v + member internal lexbuf.Buffer with get() : 'char[] = buffer and set v = buffer <- v + member internal lexbuf.BufferMaxScanLength with get() = bufferMaxScanLength and set v = bufferMaxScanLength <- v + member internal lexbuf.BufferScanLength with get() = bufferScanLength and set v = bufferScanLength <- v + member internal lexbuf.BufferScanStart with get() : int = bufferScanStart and set v = bufferScanStart <- v + member internal lexbuf.BufferAcceptAction with get() = bufferAcceptAction and set v = bufferAcceptAction <- v + member internal lexbuf.RefillBuffer = extendBufferSync + member internal lexbuf.AsyncRefillBuffer = extendBufferAsync + + static member LexemeString(lexbuf:LexBuffer) = + new System.String(lexbuf.Buffer,lexbuf.BufferScanStart,lexbuf.LexemeLength) + + member lexbuf.IsPastEndOfStream + with get() = eof + and set(b) = eof <- b + + member lexbuf.DiscardInput() = discardInput () + + member x.BufferScanPos = bufferScanStart + bufferScanLength + + member lexbuf.EnsureBufferSize n = + if lexbuf.BufferScanPos + n >= buffer.Length then + let repl = Array.zeroCreate (lexbuf.BufferScanPos + n) + Array.blit buffer bufferScanStart repl bufferScanStart bufferScanLength; + buffer <- repl + + static member FromReadFunctions (syncRead : ('char[] * int * int -> int) option, asyncRead : ('char[] * int * int -> Async) option) : LexBuffer<'char> = + let extension= Array.zeroCreate 4096 + let fillers = + { fillSync = + match syncRead with + | None -> None + | Some read -> + Some (fun lexBuffer -> + let n = read(extension,0,extension.Length) + lexBuffer.EnsureBufferSize n; + Array.blit extension 0 lexBuffer.Buffer lexBuffer.BufferScanPos n; + lexBuffer.BufferMaxScanLength <- lexBuffer.BufferScanLength + n); + fillAsync = + match asyncRead with + | None -> None + | Some read -> + Some (fun lexBuffer -> + async { + let! n = read(extension,0,extension.Length) + lexBuffer.EnsureBufferSize n; + Array.blit extension 0 lexBuffer.Buffer lexBuffer.BufferScanPos n; + lexBuffer.BufferMaxScanLength <- lexBuffer.BufferScanLength + n }) } + new LexBuffer<_>(fillers) + + // A full type signature is required on this method because it is used at more specific types within its own scope + static member FromFunction (f : 'char[] * int * int -> int) : LexBuffer<'char> = LexBuffer<_>.FromReadFunctions(Some(f),None) + static member FromAsyncFunction (f : 'char[] * int * int -> Async) : LexBuffer<'char> = LexBuffer<_>.FromReadFunctions(None,Some(f)) + + static member FromCharFunction f : LexBuffer = + LexBuffer.FromFunction(fun (buff,start,len) -> + let buff2 = Array.zeroCreate len + let n = f buff2 len + Array.blit buff2 0 buff start len + n) + static member FromByteFunction f : LexBuffer = + LexBuffer.FromFunction(fun (buff,start,len) -> + let buff2 = Array.zeroCreate len + let n = f buff2 len + Array.blit buff2 0 buff start len + n) + + // A full type signature is required on this method because it is used at more specific types within its own scope + static member FromArray (s: 'char[]) : LexBuffer<'char> = + let lexBuffer = + new LexBuffer<_> + { fillSync = Some (fun _ -> ()); + fillAsync = Some (fun _ -> async { return () }) } + let buffer = Array.copy s + lexBuffer.Buffer <- buffer; + lexBuffer.BufferMaxScanLength <- buffer.Length; + lexBuffer + + static member FromBytes (arr) = LexBuffer.FromArray(arr) + static member FromChars (arr) = LexBuffer.FromArray(arr) + static member FromString (s:string) = LexBuffer.FromChars (s.ToCharArray()) + + static member FromTextReader (tr:System.IO.TextReader) : LexBuffer = + LexBuffer.FromFunction(tr.Read) + + static member FromBinaryReader (br:System.IO.BinaryReader) : LexBuffer = + LexBuffer.FromFunction(br.Read) + + static member FromStream (stream:System.IO.Stream) : LexBuffer = + LexBuffer.FromReadFunctions(Some(stream.Read),Some(fun (buf,offset,len) -> stream.AsyncRead(buf,offset=offset,count=len))) + + module GenericImplFragments = + let startInterpret(lexBuffer:LexBuffer<_>)= + lexBuffer.BufferScanStart <- lexBuffer.BufferScanStart + lexBuffer.LexemeLength; + lexBuffer.BufferMaxScanLength <- lexBuffer.BufferMaxScanLength - lexBuffer.LexemeLength; + lexBuffer.BufferScanLength <- 0; + lexBuffer.LexemeLength <- 0; + lexBuffer.BufferAcceptAction <- -1; + + let afterRefill (trans: uint16[] array,sentinel,lexBuffer:LexBuffer<_>,scanUntilSentinel,endOfScan,state,eofPos) = + // end of file occurs if we couldn't extend the buffer + if lexBuffer.BufferScanLength = lexBuffer.BufferMaxScanLength then + let snew = int trans.[state].[eofPos] // == EOF + if snew = sentinel then + endOfScan() + else + if lexBuffer.IsPastEndOfStream then failwith "End of file on lexing stream"; + lexBuffer.IsPastEndOfStream <- true; + // Printf.printf "state %d --> %d on eof\n" state snew; + scanUntilSentinel(lexBuffer,snew) + else + scanUntilSentinel(lexBuffer, state) + + let onAccept (lexBuffer:LexBuffer<_>,a) = + lexBuffer.LexemeLength <- lexBuffer.BufferScanLength; + lexBuffer.BufferAcceptAction <- a; + + open GenericImplFragments + + [] +#if INTERNALIZED_FSLEXYACC_RUNTIME + type internal AsciiTables(trans: uint16[] array, accept: uint16[]) = +#else + type AsciiTables(trans: uint16[] array, accept: uint16[]) = +#endif + let rec scanUntilSentinel(lexBuffer, state) = + let sentinel = 255 * 256 + 255 + // Return an endOfScan after consuming the input + let a = int accept.[state] + if a <> sentinel then + onAccept (lexBuffer,a) + + if lexBuffer.BufferScanLength = lexBuffer.BufferMaxScanLength then + lexBuffer.DiscardInput(); + lexBuffer.RefillBuffer (); + // end of file occurs if we couldn't extend the buffer + afterRefill (trans,sentinel,lexBuffer,scanUntilSentinel,lexBuffer.EndOfScan,state,256 (* == EOF *) ) + else + // read a character - end the scan if there are no further transitions + let inp = int(lexBuffer.Buffer.[lexBuffer.BufferScanPos]) + let snew = int trans.[state].[inp] + if snew = sentinel then + lexBuffer.EndOfScan() + else + lexBuffer.BufferScanLength <- lexBuffer.BufferScanLength + 1; + // Printf.printf "state %d --> %d on '%c' (%d)\n" state snew (Char.chr inp) inp; + scanUntilSentinel(lexBuffer, snew) + + /// Interpret tables for an ascii lexer generated by fslex. + member tables.Interpret(initialState,lexBuffer : LexBuffer) = + startInterpret(lexBuffer) + scanUntilSentinel(lexBuffer, initialState) + + /// Interpret tables for an ascii lexer generated by fslex. + member tables.AsyncInterpret(initialState,lexBuffer : LexBuffer) = + + let rec scanUntilSentinel(lexBuffer,state) : Async = + async { + let sentinel = 255 * 256 + 255 + // Return an endOfScan after consuming the input + let a = int accept.[state] + if a <> sentinel then + onAccept (lexBuffer,a) + + if lexBuffer.BufferScanLength = lexBuffer.BufferMaxScanLength then + lexBuffer.DiscardInput(); + do! lexBuffer.AsyncRefillBuffer (); + // end of file occurs if we couldn't extend the buffer + return! afterRefill (trans,sentinel,lexBuffer,scanUntilSentinel,endOfScan,state,256 (* == EOF *) ) + else + // read a character - end the scan if there are no further transitions + let inp = int(lexBuffer.Buffer.[lexBuffer.BufferScanPos]) + let snew = int trans.[state].[inp] + if snew = sentinel then + return! endOfScan() + else + lexBuffer.BufferScanLength <- lexBuffer.BufferScanLength + 1; + return! scanUntilSentinel(lexBuffer,snew) + } + and endOfScan() = + async { return lexBuffer.EndOfScan() } + startInterpret(lexBuffer) + scanUntilSentinel(lexBuffer, initialState) + + + static member Create(trans,accept) = new AsciiTables(trans,accept) + + [] +#if INTERNALIZED_FSLEXYACC_RUNTIME + type internal UnicodeTables(trans: uint16[] array, accept: uint16[]) = +#else + type UnicodeTables(trans: uint16[] array, accept: uint16[]) = +#endif + let sentinel = 255 * 256 + 255 + let numUnicodeCategories = 30 + let numLowUnicodeChars = 128 + let numSpecificUnicodeChars = (trans.[0].Length - 1 - numLowUnicodeChars - numUnicodeCategories)/2 + let lookupUnicodeCharacters (state,inp) = + let inpAsInt = int inp + // Is it a fast ASCII character? + if inpAsInt < numLowUnicodeChars then + int trans.[state].[inpAsInt] + else + // Search for a specific unicode character + let baseForSpecificUnicodeChars = numLowUnicodeChars + let rec loop i = + if i >= numSpecificUnicodeChars then + // OK, if we failed then read the 'others' entry in the alphabet, + // which covers all Unicode characters not covered in other + // ways + let baseForUnicodeCategories = numLowUnicodeChars+numSpecificUnicodeChars*2 + let unicodeCategory = System.Globalization.CharUnicodeInfo.GetUnicodeCategory(inp) + //System.Console.WriteLine("inp = {0}, unicodeCategory = {1}", [| box inp; box unicodeCategory |]); + int trans.[state].[baseForUnicodeCategories + int32 unicodeCategory] + else + // This is the specific unicode character + let c = char (int trans.[state].[baseForSpecificUnicodeChars+i*2]) + //System.Console.WriteLine("c = {0}, inp = {1}, i = {2}", [| box c; box inp; box i |]); + // OK, have we found the entry for a specific unicode character? + if c = inp + then int trans.[state].[baseForSpecificUnicodeChars+i*2+1] + else loop(i+1) + + loop 0 + let eofPos = numLowUnicodeChars + 2*numSpecificUnicodeChars + numUnicodeCategories + + let rec scanUntilSentinel(lexBuffer,state) = + // Return an endOfScan after consuming the input + let a = int accept.[state] + if a <> sentinel then + onAccept(lexBuffer,a) + + if lexBuffer.BufferScanLength = lexBuffer.BufferMaxScanLength then + lexBuffer.DiscardInput(); + lexBuffer.RefillBuffer (); + // end of file occurs if we couldn't extend the buffer + afterRefill (trans,sentinel,lexBuffer,scanUntilSentinel,lexBuffer.EndOfScan,state,eofPos) + else + // read a character - end the scan if there are no further transitions + let inp = lexBuffer.Buffer.[lexBuffer.BufferScanPos] + + // Find the new state + let snew = lookupUnicodeCharacters (state,inp) + + if snew = sentinel then + lexBuffer.EndOfScan() + else + lexBuffer.BufferScanLength <- lexBuffer.BufferScanLength + 1; + // Printf.printf "state %d --> %d on '%c' (%d)\n" s snew (char inp) inp; + scanUntilSentinel(lexBuffer,snew) + + // Each row for the Unicode table has format + // 128 entries for ASCII characters + // A variable number of 2*UInt16 entries for SpecificUnicodeChars + // 30 entries, one for each UnicodeCategory + // 1 entry for EOF + + member tables.Interpret(initialState,lexBuffer : LexBuffer) = + startInterpret(lexBuffer) + scanUntilSentinel(lexBuffer, initialState) + + member tables.AsyncInterpret(initialState,lexBuffer : LexBuffer) = + + let rec scanUntilSentinel(lexBuffer, state) = + async { + // Return an endOfScan after consuming the input + let a = int accept.[state] + if a <> sentinel then + onAccept(lexBuffer,a) + + if lexBuffer.BufferScanLength = lexBuffer.BufferMaxScanLength then + lexBuffer.DiscardInput(); + lexBuffer.RefillBuffer (); + // end of file occurs if we couldn't extend the buffer + return! afterRefill (trans,sentinel,lexBuffer,scanUntilSentinel,endOfScan,state,eofPos) + else + // read a character - end the scan if there are no further transitions + let inp = lexBuffer.Buffer.[lexBuffer.BufferScanPos] + + // Find the new state + let snew = lookupUnicodeCharacters (state,inp) + + if snew = sentinel then + return! endOfScan() + else + lexBuffer.BufferScanLength <- lexBuffer.BufferScanLength + 1; + return! scanUntilSentinel(lexBuffer, snew) + } + and endOfScan() = + async { return lexBuffer.EndOfScan() } + startInterpret(lexBuffer) + scanUntilSentinel(lexBuffer, initialState) + + static member Create(trans,accept) = new UnicodeTables(trans,accept) diff --git a/src/buildtools/fsyacc/Lexing.fsi b/src/buildtools/fsyacc/Lexing.fsi new file mode 100644 index 0000000000..e31ad411aa --- /dev/null +++ b/src/buildtools/fsyacc/Lexing.fsi @@ -0,0 +1,151 @@ +//========================================================================== +// LexBuffers are for use with automatically generated lexical analyzers, +// in particular those produced by 'fslex'. +// +// (c) Microsoft Corporation 2005-2008. +//=========================================================================== + +#if INTERNALIZED_FSLEXYACC_RUNTIME +namespace Internal.Utilities.Text.Lexing +#else +namespace Microsoft.FSharp.Text.Lexing +#endif + +open System.Collections.Generic + +/// Position information stored for lexing tokens +// +// Note: this is an OCaml compat record type. +#if INTERNALIZED_FSLEXYACC_RUNTIME +type internal Position = +#else +type Position = +#endif + { /// The file name for the position + pos_fname: string; + /// The line number for the position + pos_lnum: int; +#if INTERNALIZED_FSLEXYACC_RUNTIME + /// The line number for the position in the original source file + pos_orig_lnum : int; +#endif + /// The absolute offset of the beginning of the line + pos_bol: int; + /// The absolute offset of the column for the position + pos_cnum: int; } + /// The file name associated with the input stream. + member FileName : string + /// The line number in the input stream, assuming fresh positions have been updated + /// using AsNewLinePos() and by modifying the EndPos property of the LexBuffer. + member Line : int +#if INTERNALIZED_FSLEXYACC_RUNTIME + /// The line number for the position in the input stream, assuming fresh positions have been updated + /// using AsNewLinePos() + member OriginalLine : int +#endif + [] + member Char : int + /// The character number in the input stream + member AbsoluteOffset : int + /// Return absolute offset of the start of the line marked by the position + member StartOfLineAbsoluteOffset : int + /// Return the column number marked by the position, i.e. the difference between the AbsoluteOffset and the StartOfLineAbsoluteOffset + member Column : int + // Given a position just beyond the end of a line, return a position at the start of the next line + member NextLine : Position + + /// Given a position at the start of a token of length n, return a position just beyond the end of the token + member EndOfToken: n:int -> Position + /// Gives a position shifted by specified number of characters + member ShiftColumnBy: by:int -> Position + + [] + member AsNewLinePos : unit -> Position + + /// Get an arbitrary position, with the empty string as filename, and + static member Empty : Position + + /// Get a position corresponding to the first line (line number 1) in a given file + static member FirstLine : filename:string -> Position + +[] +#if INTERNALIZED_FSLEXYACC_RUNTIME +type internal LexBuffer<'char> = +#else +/// Input buffers consumed by lexers generated by fslex.exe +type LexBuffer<'char> = +#endif + /// The start position for the lexeme + member StartPos: Position with get,set + /// The end position for the lexeme + member EndPos: Position with get,set + /// The matched string + member Lexeme: 'char array + + /// Fast helper to turn the matched characters into a string, avoiding an intermediate array + static member LexemeString : LexBuffer -> string + + /// The length of the matched string + member LexemeLength: int + /// Fetch a particular character in the matched string + member LexemeChar: int -> 'char + + /// Dynamically typed, non-lexically scoped parameter table + member BufferLocalStore : IDictionary + + /// True if the refill of the buffer ever failed , or if explicitly set to true. + member IsPastEndOfStream: bool with get,set + /// Remove all input, though don't discard the current lexeme + member DiscardInput: unit -> unit + + /// Create a lex buffer suitable for byte lexing that reads characters from the given array + static member FromBytes: byte[] -> LexBuffer + /// Create a lex buffer suitable for Unicode lexing that reads characters from the given array + static member FromChars: char[] -> LexBuffer + /// Create a lex buffer suitable for Unicode lexing that reads characters from the given string + static member FromString: string -> LexBuffer + /// Create a lex buffer that reads character or byte inputs by using the given function + static member FromFunction: ('char[] * int * int -> int) -> LexBuffer<'char> + /// Create a lex buffer that asynchronously reads character or byte inputs by using the given function + static member FromAsyncFunction: ('char[] * int * int -> Async) -> LexBuffer<'char> + + + [.FromFunction instead")>] + static member FromCharFunction: (char[] -> int -> int) -> LexBuffer + [.FromFunction instead")>] + static member FromByteFunction: (byte[] -> int -> int) -> LexBuffer + + /// Create a lex buffer suitable for use with a Unicode lexer that reads character inputs from the given text reader + static member FromTextReader: System.IO.TextReader -> LexBuffer + /// Create a lex buffer suitable for use with ASCII byte lexing that reads byte inputs from the given binary reader + static member FromBinaryReader: System.IO.BinaryReader -> LexBuffer + + +/// The type of tables for an ascii lexer generated by fslex. +[] +#if INTERNALIZED_FSLEXYACC_RUNTIME +type internal AsciiTables = +#else +type AsciiTables = +#endif + static member Create : uint16[] array * uint16[] -> AsciiTables + /// Interpret tables for an ascii lexer generated by fslex. + member Interpret: initialState:int * LexBuffer -> int + /// Interpret tables for an ascii lexer generated by fslex, processing input asynchronously + member AsyncInterpret: initialState:int * LexBuffer -> Async + + +/// The type of tables for an unicode lexer generated by fslex. +[] +#if INTERNALIZED_FSLEXYACC_RUNTIME +type internal UnicodeTables = +#else +type UnicodeTables = +#endif + static member Create : uint16[] array * uint16[] -> UnicodeTables + /// Interpret tables for a unicode lexer generated by fslex. + member Interpret: initialState:int * LexBuffer -> int + + /// Interpret tables for a unicode lexer generated by fslex, processing input asynchronously + member AsyncInterpret: initialState:int * LexBuffer -> Async + diff --git a/src/buildtools/fsyacc/Parsing.fs b/src/buildtools/fsyacc/Parsing.fs new file mode 100644 index 0000000000..01dccfb610 --- /dev/null +++ b/src/buildtools/fsyacc/Parsing.fs @@ -0,0 +1,514 @@ +// (c) Microsoft Corporation 2005-2009. + +#if INTERNALIZED_FSLEXYACC_RUNTIME + +namespace Internal.Utilities.Text.Parsing +open Internal.Utilities +open Internal.Utilities.Text.Lexing + +#else +namespace Microsoft.FSharp.Text.Parsing +open Microsoft.FSharp.Text.Lexing +#endif + + + +open System +open System.Collections.Generic + +#if INTERNALIZED_FSLEXYACC_RUNTIME +type internal IParseState = +#else +type IParseState = +#endif + abstract InputRange: int -> Position * Position + abstract InputEndPosition: int -> Position + abstract InputStartPosition: int -> Position + abstract ResultRange: Position * Position + abstract GetInput: int -> obj + abstract ParserLocalStore : IDictionary + abstract RaiseError<'b> : unit -> 'b + +//------------------------------------------------------------------------- +// This context is passed to the error reporter when a syntax error occurs + +[] +#if INTERNALIZED_FSLEXYACC_RUNTIME +type internal ParseErrorContext<'tok> +#else +type ParseErrorContext<'tok> +#endif + (//lexbuf: LexBuffer<_>, + stateStack:int list, + parseState: IParseState, + reduceTokens: int list, + currentToken: 'tok option, + reducibleProductions: int list list, + shiftableTokens: int list , + message : string) = + //member x.LexBuffer = lexbuf + member x.StateStack = stateStack + member x.ReduceTokens = reduceTokens + member x.CurrentToken = currentToken + member x.ParseState = parseState + member x.ReducibleProductions = reducibleProductions + member x.ShiftTokens = shiftableTokens + member x.Message = message + + +//------------------------------------------------------------------------- +// This is the data structure emitted as code by FSYACC. + +#if INTERNALIZED_FSLEXYACC_RUNTIME +type internal Tables<'tok> = +#else +type Tables<'tok> = +#endif + { reductions: (IParseState -> obj) array; + endOfInputTag: int; + tagOfToken: 'tok -> int; + dataOfToken: 'tok -> obj; + actionTableElements: uint16[]; + actionTableRowOffsets: uint16[]; + reductionSymbolCounts: uint16[]; + immediateActions: uint16[]; + gotos: uint16[]; + sparseGotoTableRowOffsets: uint16[]; + stateToProdIdxsTableElements: uint16[]; + stateToProdIdxsTableRowOffsets: uint16[]; + productionToNonTerminalTable: uint16[]; + /// For fsyacc.exe, this entry is filled in by context from the generated parser file. If no 'parse_error' function + /// is defined by the user then ParseHelpers.parse_error is used by default (ParseHelpers is opened + /// at the top of the generated parser file) + parseError: ParseErrorContext<'tok> -> unit; + numTerminals: int; + tagOfErrorTerminal: int } + +//------------------------------------------------------------------------- +// An implementation of stacks. + +// This type is in System.dll so for the moment we can't use it in FSharp.Core.dll +//type Stack<'a> = System.Collections.Generic.Stack<'a> + +#if INTERNALIZED_FSLEXYACC_RUNTIME +type Stack<'a>(n) = +#else +type internal Stack<'a>(n) = +#endif + let mutable contents = Array.zeroCreate<'a>(n) + let mutable count = 0 + + member buf.Ensure newSize = + let oldSize = Array.length contents + if newSize > oldSize then + let old = contents + contents <- Array.zeroCreate (max newSize (oldSize * 2)); + Array.blit old 0 contents 0 count; + + member buf.Count = count + member buf.Pop() = count <- count - 1 + member buf.Peep() = contents.[count - 1] + member buf.Top(n) = [ for x in contents.[max 0 (count-n)..count - 1] -> x ] |> List.rev + member buf.Push(x) = + buf.Ensure(count + 1); + contents.[count] <- x; + count <- count + 1 + + member buf.IsEmpty = (count = 0) +#if __DEBUG + member buf.PrintStack() = + for i = 0 to (count - 1) do +#if FX_NO_CONSOLE + () +#else + System.Console.Write("{0}{1}",(contents.[i]),if i=count-1 then ":" else "-") +#endif +#endif +exception RecoverableParseError +exception Accept of obj + +#if __DEBUG +module Flags = + let mutable debug = false +#endif + +#if INTERNALIZED_FSLEXYACC_RUNTIME +module internal Implementation = +#else +module Implementation = +#endif + + // Definitions shared with fsyacc + let anyMarker = 0xffff + let shiftFlag = 0x0000 + let reduceFlag = 0x4000 + let errorFlag = 0x8000 + let acceptFlag = 0xc000 + let actionMask = 0xc000 + + let actionValue action = action &&& (~~~ actionMask) + let actionKind action = action &&& actionMask + + //------------------------------------------------------------------------- + // Read the tables written by FSYACC. + + type AssocTable(elemTab:uint16[], offsetTab:uint16[]) = + let cache = new Dictionary<_,_>(2000) + + member t.readAssoc (minElemNum,maxElemNum,defaultValueOfAssoc,keyToFind) = + // do a binary chop on the table + let elemNumber : int = (minElemNum+maxElemNum)/2 + if elemNumber = maxElemNum + then defaultValueOfAssoc + else + let x = int elemTab.[elemNumber*2] + if keyToFind = x then + int elemTab.[elemNumber*2+1] + elif keyToFind < x then t.readAssoc (minElemNum ,elemNumber,defaultValueOfAssoc,keyToFind) + else t.readAssoc (elemNumber+1,maxElemNum,defaultValueOfAssoc,keyToFind) + + member t.Read(rowNumber ,keyToFind) = + + // First check the sparse lookaside table + // Performance note: without this lookaside table the binary chop in readAssoc + // takes up around 10% of of parsing time + // for parsing intensive samples such as the bootstrapped F# compiler. + // + // Note: using a .NET Dictionary for this int -> int table looks like it could be sub-optimal. + // Some other better sparse lookup table may be better. + let mutable res = 0 + let cacheKey = (rowNumber <<< 16) ||| keyToFind + let ok = cache.TryGetValue(cacheKey, &res) + if ok then res + else + let headOfTable = int offsetTab.[rowNumber] + let firstElemNumber = headOfTable + 1 + let numberOfElementsInAssoc = int elemTab.[headOfTable*2] + let defaultValueOfAssoc = int elemTab.[headOfTable*2+1] + let res = t.readAssoc (firstElemNumber,(firstElemNumber+numberOfElementsInAssoc),defaultValueOfAssoc,keyToFind) + cache.[cacheKey] <- res + res + + // Read all entries in the association table + // Used during error recovery to find all valid entries in the table + member x.ReadAll(n) = + let headOfTable = int offsetTab.[n] + let firstElemNumber = headOfTable + 1 + let numberOfElementsInAssoc = int32 elemTab.[headOfTable*2] + let defaultValueOfAssoc = int elemTab.[headOfTable*2+1] + [ for i in firstElemNumber .. (firstElemNumber+numberOfElementsInAssoc-1) -> + (int elemTab.[i*2], int elemTab.[i*2+1]) ], defaultValueOfAssoc + + type IdxToIdxListTable(elemTab:uint16[], offsetTab:uint16[]) = + + // Read all entries in a row of the table + member x.ReadAll(n) = + let headOfTable = int offsetTab.[n] + let firstElemNumber = headOfTable + 1 + let numberOfElements = int32 elemTab.[headOfTable] + [ for i in firstElemNumber .. (firstElemNumber+numberOfElements-1) -> int elemTab.[i] ] + + //------------------------------------------------------------------------- + // interpret the tables emitted by FSYACC. + + [] + [] + type ValueInfo = + val value: obj + val startPos: Position + val endPos: Position + new(value,startPos,endPos) = { value=value; startPos=startPos;endPos=endPos } + + let interpret (tables: Tables<'tok>) lexer (lexbuf : LexBuffer<_>) initialState = + let localStore = new Dictionary() in + localStore.["LexBuffer"] <- lexbuf; +#if __DEBUG + if Flags.debug then System.Console.WriteLine("\nParser: interpret tables"); +#endif + let stateStack : Stack = new Stack<_>(100) + stateStack.Push(initialState); + let valueStack = new Stack(100) + let mutable haveLookahead = false + let mutable lookaheadToken = Unchecked.defaultof<'tok> + let mutable lookaheadEndPos = Unchecked.defaultof + let mutable lookaheadStartPos = Unchecked.defaultof + let mutable finished = false + // After an error occurs, we suppress errors until we've shifted three tokens in a row. + let mutable errorSuppressionCountDown = 0 + + // When we hit the end-of-file we don't fail straight away but rather keep permitting shift + // and reduce against the last token in the token stream 20 times or until we've accepted + // or exhausted the stack. This allows error recovery rules of the form + // input : realInput EOF | realInput error EOF | error EOF + // where consuming one EOF to trigger an error doesn't result in overall parse failure + // catastrophe and the loss of intermediate results. + // + let mutable inEofCountDown = false + let mutable eofCountDown = 20 // Number of EOFs to supply at the end for error recovery + // The 100 here means a maximum of 100 elements for each rule + let ruleStartPoss = (Array.zeroCreate 100 : Position array) + let ruleEndPoss = (Array.zeroCreate 100 : Position array) + let ruleValues = (Array.zeroCreate 100 : obj array) + let lhsPos = (Array.zeroCreate 2 : Position array) + let reductions = tables.reductions + let actionTable = new AssocTable(tables.actionTableElements, tables.actionTableRowOffsets) + let gotoTable = new AssocTable(tables.gotos, tables.sparseGotoTableRowOffsets) + let stateToProdIdxsTable = new IdxToIdxListTable(tables.stateToProdIdxsTableElements, tables.stateToProdIdxsTableRowOffsets) + + let parseState = + { new IParseState with + member p.InputRange(n) = ruleStartPoss.[n-1], ruleEndPoss.[n-1]; + member p.InputStartPosition(n) = ruleStartPoss.[n-1] + member p.InputEndPosition(n) = ruleEndPoss.[n-1]; + member p.GetInput(n) = ruleValues.[n-1]; + member p.ResultRange = (lhsPos.[0], lhsPos.[1]); + member p.ParserLocalStore = (localStore :> IDictionary<_,_>); + member p.RaiseError() = raise RecoverableParseError (* NOTE: this binding tests the fairly complex logic associated with an object expression implementing a generic abstract method *) + } + +#if __DEBUG + let report haveLookahead lookaheadToken = + if haveLookahead then sprintf "%A" lookaheadToken + else "[TBC]" +#endif + + // Pop the stack until we can shift the 'error' token. If 'tokenOpt' is given + // then keep popping until we can shift both the 'error' token and the token in 'tokenOpt'. + // This is used at end-of-file to make sure we can shift both the 'error' token and the 'EOF' token. + let rec popStackUntilErrorShifted(tokenOpt) = + // Keep popping the stack until the "error" terminal is shifted +#if __DEBUG + if Flags.debug then System.Console.WriteLine("popStackUntilErrorShifted"); +#endif + if stateStack.IsEmpty then +#if __DEBUG + if Flags.debug then + System.Console.WriteLine("state stack empty during error recovery - generating parse error"); +#endif + failwith "parse error"; + + let currState = stateStack.Peep() +#if __DEBUG + if Flags.debug then + System.Console.WriteLine("In state {0} during error recovery", currState); +#endif + + let action = actionTable.Read(currState, tables.tagOfErrorTerminal) + + if actionKind action = shiftFlag && + (match tokenOpt with + | None -> true + | Some(token) -> + let nextState = actionValue action + actionKind (actionTable.Read(nextState, tables.tagOfToken(token))) = shiftFlag) then + +#if __DEBUG + if Flags.debug then System.Console.WriteLine("shifting error, continuing with error recovery"); +#endif + let nextState = actionValue action + // The "error" non terminal needs position information, though it tends to be unreliable. + // Use the StartPos/EndPos from the lex buffer + valueStack.Push(ValueInfo(box (), lexbuf.StartPos, lexbuf.EndPos)); + stateStack.Push(nextState) + else + if valueStack.IsEmpty then + failwith "parse error"; +#if __DEBUG + if Flags.debug then + System.Console.WriteLine("popping stack during error recovery"); +#endif + valueStack.Pop(); + stateStack.Pop(); + popStackUntilErrorShifted(tokenOpt) + + while not finished do + if stateStack.IsEmpty then + finished <- true + else + let state = stateStack.Peep() +#if __DEBUG + if Flags.debug then (Console.Write("{0} value(state), state ",valueStack.Count); stateStack.PrintStack()) +#endif + let action = + let immediateAction = int tables.immediateActions.[state] + if not (immediateAction = anyMarker) then + // Action has been pre-determined, no need to lookahead + // Expecting it to be a Reduce action on a non-fakeStartNonTerminal ? + immediateAction + else + // Lookahead required to determine action + if not haveLookahead then + if lexbuf.IsPastEndOfStream then + // When the input runs out, keep supplying the last token for eofCountDown times + if eofCountDown>0 then + haveLookahead <- true + eofCountDown <- eofCountDown - 1 + inEofCountDown <- true + else + haveLookahead <- false + else + lookaheadToken <- lexer lexbuf + lookaheadStartPos <- lexbuf.StartPos + lookaheadEndPos <- lexbuf.EndPos + haveLookahead <- true; + + let tag = + if haveLookahead then tables.tagOfToken lookaheadToken + else tables.endOfInputTag + + // Printf.printf "state %d\n" state + actionTable.Read(state,tag) + + let kind = actionKind action + if kind = shiftFlag then ( + if errorSuppressionCountDown > 0 then + errorSuppressionCountDown <- errorSuppressionCountDown - 1; +#if __DEBUG + if Flags.debug then Console.WriteLine("shifting, reduced errorRecoverylevel to {0}\n", errorSuppressionCountDown); +#endif + let nextState = actionValue action + if not haveLookahead then failwith "shift on end of input!"; + let data = tables.dataOfToken lookaheadToken + valueStack.Push(ValueInfo(data, lookaheadStartPos, lookaheadEndPos)); + stateStack.Push(nextState); +#if __DEBUG + if Flags.debug then Console.WriteLine("shift/consume input {0}, shift to state {1}", report haveLookahead lookaheadToken, nextState); +#endif + haveLookahead <- false + + ) elif kind = reduceFlag then + let prod = actionValue action + let reduction = reductions.[prod] + let n = int tables.reductionSymbolCounts.[prod] + // pop the symbols, populate the values and populate the locations +#if __DEBUG + if Flags.debug then Console.Write("reduce popping {0} values/states, lookahead {1}", n, report haveLookahead lookaheadToken); +#endif + + lhsPos.[0] <- Position.Empty; + lhsPos.[1] <- Position.Empty; + for i = 0 to n - 1 do + if valueStack.IsEmpty then failwith "empty symbol stack"; + let topVal = valueStack.Peep() + valueStack.Pop(); + stateStack.Pop(); + ruleValues.[(n-i)-1] <- topVal.value; + ruleStartPoss.[(n-i)-1] <- topVal.startPos; + ruleEndPoss.[(n-i)-1] <- topVal.endPos; + if lhsPos.[1] = Position.Empty then lhsPos.[1] <- topVal.endPos; + if not (topVal.startPos = Position.Empty) then lhsPos.[0] <- topVal.startPos + done; + + try + // Printf.printf "reduce %d\n" prod; + let redResult = reduction parseState + valueStack.Push(ValueInfo(redResult, lhsPos.[0], lhsPos.[1])); + let currState = stateStack.Peep() + let newGotoState = gotoTable.Read(int tables.productionToNonTerminalTable.[prod], currState) + stateStack.Push(newGotoState) +#if __DEBUG + if Flags.debug then Console.WriteLine(" goto state {0}", newGotoState) +#endif + with + | Accept res -> + finished <- true; + valueStack.Push(ValueInfo(res, lhsPos.[0], lhsPos.[1])) + | RecoverableParseError -> +#if __DEBUG + if Flags.debug then Console.WriteLine("RecoverableParseErrorException...\n"); +#endif + popStackUntilErrorShifted(None); + // User code raised a Parse_error. Don't report errors again until three tokens have been shifted + errorSuppressionCountDown <- 3 + elif kind = errorFlag then ( +#if __DEBUG + if Flags.debug then Console.Write("ErrorFlag... "); +#endif + // Silently discard inputs and don't report errors + // until three tokens in a row have been shifted +#if __DEBUG + if Flags.debug then printfn "error on token '%A' " (if haveLookahead then Some(lookaheadToken) else None); +#endif + if errorSuppressionCountDown > 0 then + // If we're in the end-of-file count down then we're very keen to 'Accept'. + // We can only do this by repeatedly popping the stack until we can shift both an 'error' token + // and an EOF token. + if inEofCountDown && eofCountDown < 10 then +#if __DEBUG + if Flags.debug then printfn "poppin stack, lokking to shift both 'error' and that token, during end-of-file error recovery" ; +#endif + popStackUntilErrorShifted(if haveLookahead then Some(lookaheadToken) else None); + + // If we don't haveLookahead then the end-of-file count down is over and we have no further options. + if not haveLookahead then + failwith "parse error: unexpected end of file" + +#if __DEBUG + if Flags.debug then printfn "discarding token '%A' during error suppression" (if haveLookahead then Some(lookaheadToken) else None); +#endif + // Discard the token + haveLookahead <- false + // Try again to shift three tokens + errorSuppressionCountDown <- 3 + else ( + + let currentToken = if haveLookahead then Some(lookaheadToken) else None + let actions,defaultAction = actionTable.ReadAll(state) + let explicit = Set.ofList [ for (tag,_action) in actions -> tag ] + + let shiftableTokens = + [ for (tag,action) in actions do + if (actionKind action) = shiftFlag then + yield tag + if actionKind defaultAction = shiftFlag then + for tag in 0 .. tables.numTerminals-1 do + if not (explicit.Contains(tag)) then + yield tag ] in + + let stateStack = stateStack.Top(12) in + let reducibleProductions = + [ for state in stateStack do + yield stateToProdIdxsTable.ReadAll(state) ] + + let reduceTokens = + [ for (tag,action) in actions do + if actionKind(action) = reduceFlag then + yield tag + if actionKind(defaultAction) = reduceFlag then + for tag in 0 .. tables.numTerminals-1 do + if not (explicit.Contains(tag)) then + yield tag ] in + //let activeRules = stateStack |> List.iter (fun state -> + let errorContext = new ParseErrorContext<'tok>(stateStack,parseState, reduceTokens,currentToken,reducibleProductions, shiftableTokens, "syntax error") + tables.parseError(errorContext); + popStackUntilErrorShifted(None); + errorSuppressionCountDown <- 3; +#if __DEBUG + if Flags.debug then System.Console.WriteLine("generated syntax error and shifted error token, haveLookahead = {0}\n", haveLookahead); +#endif + ) + ) elif kind = acceptFlag then + finished <- true +#if __DEBUG + else + if Flags.debug then System.Console.WriteLine("ALARM!!! drop through case in parser"); +#endif + done; + // OK, we're done - read off the overall generated value + valueStack.Peep().value + +#if INTERNALIZED_FSLEXYACC_RUNTIME +type internal Tables<'tok> with +#else +type Tables<'tok> with +#endif + member tables.Interpret (lexer,lexbuf,initialState) = + Implementation.interpret tables lexer lexbuf initialState + +#if INTERNALIZED_FSLEXYACC_RUNTIME +module internal ParseHelpers = +#else +module ParseHelpers = +#endif + let parse_error (_s:string) = () + let parse_error_rich = (None : (ParseErrorContext<_> -> unit) option) diff --git a/src/buildtools/fsyacc/Parsing.fsi b/src/buildtools/fsyacc/Parsing.fsi new file mode 100644 index 0000000000..2fef45975a --- /dev/null +++ b/src/buildtools/fsyacc/Parsing.fsi @@ -0,0 +1,130 @@ +//========================================================================== +// (c) Microsoft Corporation 2005-2009. +//========================================================================= + +#if INTERNALIZED_FSLEXYACC_RUNTIME +namespace Internal.Utilities.Text.Parsing +open Internal.Utilities +open Internal.Utilities.Text.Lexing +#else +namespace Microsoft.FSharp.Text.Parsing +open Microsoft.FSharp.Text.Lexing +#endif + +open System.Collections.Generic + +#if INTERNALIZED_FSLEXYACC_RUNTIME +type internal IParseState = +#else +/// The information accessible via the parseState value within parser actions. +type IParseState = +#endif + /// Get the start and end position for the terminal or non-terminal at a given index matched by the production + abstract InputRange: index:int -> Position * Position + /// Get the end position for the terminal or non-terminal at a given index matched by the production + abstract InputEndPosition: int -> Position + /// Get the start position for the terminal or non-terminal at a given index matched by the production + abstract InputStartPosition: int -> Position + /// Get the full range of positions matched by the production + abstract ResultRange: Position * Position + /// Get the value produced by the terminal or non-terminal at the given position + abstract GetInput : int -> obj + /// Get the store of local values associated with this parser + // Dynamically typed, non-lexically scoped local store + abstract ParserLocalStore : IDictionary + /// Raise an error in this parse context + abstract RaiseError<'b> : unit -> 'b + + +[] +#if INTERNALIZED_FSLEXYACC_RUNTIME +type internal ParseErrorContext<'tok> = +#else +/// The context provided when a parse error occurs +type ParseErrorContext<'tok> = +#endif + /// The stack of state indexes active at the parse error + member StateStack : int list + /// The state active at the parse error + member ParseState : IParseState + /// The tokens that would cause a reduction at the parse error + member ReduceTokens: int list + /// The stack of productions that would be reduced at the parse error + member ReducibleProductions : int list list + /// The token that caused the parse error + member CurrentToken : 'tok option + /// The token that would cause a shift at the parse error + member ShiftTokens : int list + /// The message associated with the parse error + member Message : string + +/// Tables generated by fsyacc +#if INTERNALIZED_FSLEXYACC_RUNTIME +type internal Tables<'tok> = +#else +/// The type of the tables contained in a file produced by the fsyacc.exe parser generator. +type Tables<'tok> = +#endif + { /// The reduction table + reductions: (IParseState -> obj) array ; + /// The token number indicating the end of input + endOfInputTag: int; + /// A function to compute the tag of a token + tagOfToken: 'tok -> int; + /// A function to compute the data carried by a token + dataOfToken: 'tok -> obj; + /// The sparse action table elements + actionTableElements: uint16[]; + /// The sparse action table row offsets + actionTableRowOffsets: uint16[]; + /// The number of symbols for each reduction + reductionSymbolCounts: uint16[]; + /// The immediate action table + immediateActions: uint16[]; + /// The sparse goto table + gotos: uint16[]; + /// The sparse goto table row offsets + sparseGotoTableRowOffsets: uint16[]; + /// The sparse table for the productions active for each state + stateToProdIdxsTableElements: uint16[]; + /// The sparse table offsets for the productions active for each state + stateToProdIdxsTableRowOffsets: uint16[]; + /// This table is logically part of the Goto table + productionToNonTerminalTable: uint16[]; + /// This function is used to hold the user specified "parse_error" or "parse_error_rich" functions + parseError: ParseErrorContext<'tok> -> unit; + /// The total number of terminals + numTerminals: int; + /// The tag of the error terminal + tagOfErrorTerminal: int } + + /// 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 + +#if INTERNALIZED_FSLEXYACC_RUNTIME +exception internal Accept of obj +exception internal RecoverableParseError +#else +/// Indicates an accept action has occured +exception Accept of obj +/// Indicates a parse error has occured and parse recovery is in progress +exception RecoverableParseError +#endif + +#if __DEBUG +module internal Flags = + val mutable debug : bool +#endif + +#if INTERNALIZED_FSLEXYACC_RUNTIME +module internal ParseHelpers = +#else +/// Helpers used by generated parsers. +module ParseHelpers = +#endif + /// The default implementation of the parse_error_rich function + val parse_error_rich: (ParseErrorContext<'tok> -> unit) option + /// The default implementation of the parse_error function + val parse_error: string -> unit + diff --git a/src/buildtools/fsyacc/fsyacc.fs b/src/buildtools/fsyacc/fsyacc.fs new file mode 100644 index 0000000000..185ff33232 --- /dev/null +++ b/src/buildtools/fsyacc/fsyacc.fs @@ -0,0 +1,533 @@ +(* (c) Microsoft Corporation 2005-2008. *) + +module internal FsLexYacc.FsYacc.Driver + +open System.IO +open System.Collections.Generic +open Printf +open Internal.Utilities +open Internal.Utilities.Text.Lexing + +open FsLexYacc.FsYacc +open FsLexYacc.FsYacc.AST + +//------------------------------------------------------------------ +// This code is duplicated from Microsoft.FSharp.Compiler.UnicodeLexing + +type Lexbuf = LexBuffer + +/// Standard utility to create a Unicode LexBuffer +/// +/// One small annoyance is that LexBuffers and not IDisposable. This means +/// we can't just return the LexBuffer object, since the file it wraps wouldn't +/// get closed when we're finished with the LexBuffer. Hence we return the stream, +/// the reader and the LexBuffer. The caller should dispose the first two when done. +let UnicodeFileAsLexbuf (filename,codePage : int option) : FileStream * StreamReader * Lexbuf = + // Use the .NET functionality to auto-detect the unicode encoding + // It also uses Lexing.from_text_reader to present the bytes read to the lexer in UTF8 decoded form + let stream = new FileStream(filename,FileMode.Open,FileAccess.Read,FileShare.Read) + let reader = + match codePage with + | None -> new StreamReader(stream,true) + | Some n -> new StreamReader(stream,System.Text.Encoding.GetEncoding(n)) + let lexbuf = LexBuffer.FromFunction(reader.Read) + lexbuf.EndPos <- Position.FirstLine(filename); + stream, reader, lexbuf + +//------------------------------------------------------------------ +// This is the program proper + +let input = ref None +let modname= ref None +let internal_module = ref false +let opens= ref [] +let out = ref None +let tokenize = ref false +let compat = ref false +let log = ref false +let light = ref None +let inputCodePage = ref None +let mutable lexlib = "Microsoft.FSharp.Text.Lexing" +let mutable parslib = "Microsoft.FSharp.Text.Parsing" + +let usage = + [ ArgInfo("-o", ArgType.String (fun s -> out := Some s), "Name the output file."); + ArgInfo("-v", ArgType.Unit (fun () -> log := true), "Produce a listing file."); + ArgInfo("--module", ArgType.String (fun s -> modname := Some s), "Define the F# module name to host the generated parser."); + ArgInfo("--internal", ArgType.Unit (fun () -> internal_module := true), "Generate an internal module"); + ArgInfo("--open", ArgType.String (fun s -> opens := !opens @ [s]), "Add the given module to the list of those to open in both the generated signature and implementation."); + ArgInfo("--light", ArgType.Unit (fun () -> light := Some true), "(ignored)"); + ArgInfo("--light-off", ArgType.Unit (fun () -> light := Some false), "Add #light \"off\" to the top of the generated file"); + ArgInfo("--ml-compatibility", ArgType.Set compat, "Support the use of the global state from the 'Parsing' module in FSharp.PowerPack.dll."); + ArgInfo("--tokens", ArgType.Set tokenize, "Simply tokenize the specification file itself."); + ArgInfo("--lexlib", ArgType.String (fun s -> lexlib <- s), "Specify the namespace for the implementation of the lexer (default: Microsoft.FSharp.Text.Lexing)"); + ArgInfo("--parslib", ArgType.String (fun s -> parslib <- s), "Specify the namespace for the implementation of the parser table interpreter (default: Microsoft.FSharp.Text.Parsing)"); + ArgInfo("--codepage", ArgType.Int (fun i -> inputCodePage := Some i), "Assume input lexer specification file is encoded with the given codepage."); ] + +let _ = ArgParser.Parse(usage,(fun x -> match !input with Some _ -> failwith "more than one input given" | None -> input := Some x),"fsyacc ") + +let output_int (os: #TextWriter) (n:int) = os.Write(string n) + +let outputCodedUInt16 (os: #TextWriter) (n:int) = + os.Write n; + os.Write "us; "; + +let shiftFlag = 0x0000 +let reduceFlag = 0x4000 +let errorFlag = 0x8000 +let acceptFlag = 0xc000 +let actionMask = 0xc000 + +let anyMarker = 0xffff + +let actionCoding action = + match action with + | Accept -> acceptFlag + | Shift n -> shiftFlag ||| n + | Reduce n -> reduceFlag ||| n + | Error -> errorFlag + +let main() = + let filename = (match !input with Some x -> x | None -> failwith "no input given") in + let spec = + let stream,reader,lexbuf = UnicodeFileAsLexbuf(filename, !inputCodePage) + use stream = stream + use reader = reader + + try + if !tokenize then begin + while true do + printf "tokenize - getting one token"; + let t = Lexer.token lexbuf in + (*F# printf "tokenize - got %s" (Parser.token_to_string t); F#*) + if t = Parser.EOF then exit 0; + done; + end; + + Parser.spec Lexer.token lexbuf + with e -> + eprintf "%s(%d,%d): error: %s" filename lexbuf.StartPos.Line lexbuf.StartPos.Column e.Message; + exit 1 in + + let has_extension (s:string) = + (s.Length >= 1 && s.[s.Length - 1] = '.') + || Path.HasExtension(s) + + let chop_extension (s:string) = + if not (has_extension s) then invalidArg "s" "the file name does not have an extension" + Path.Combine (Path.GetDirectoryName s,Path.GetFileNameWithoutExtension(s)) + + let checkSuffix (x:string) (y:string) = x.EndsWith(y) + + let output = match !out with Some x -> x | _ -> chop_extension filename + (if checkSuffix filename ".mly" then ".ml" else ".fs") in + let outputi = match !out with Some x -> chop_extension x + (if checkSuffix x ".ml" then ".mli" else ".fsi") | _ -> chop_extension filename + (if checkSuffix filename ".mly" then ".mli" else ".fsi") in + let outputo = + if !log then Some (match !out with Some x -> chop_extension x + ".fsyacc.output" | _ -> chop_extension filename + ".fsyacc.output") + else None + + use os = (File.CreateText output :> TextWriter) + use osi = (File.CreateText outputi :> TextWriter) + + let lineCountOutput = ref 0 + let lineCountSignature = ref 0 + let cos = (os,lineCountOutput) + let cosi = (osi,lineCountSignature) + let cprintf (os:TextWriter,lineCount) fmt = Printf.fprintf os fmt + let cprintfn (os:TextWriter,lineCount) fmt = Printf.kfprintf (fun () -> incr lineCount; os.WriteLine()) os fmt + + let logf = + match outputo with + | None -> (fun f -> ()) + | Some filename -> + let oso = (File.CreateText filename :> TextWriter) + (fun f -> f oso) + + logf (fun oso -> fprintfn oso " Output file describing compiled parser placed in %s and %s" output outputi); + + printfn " building tables"; + let spec1 = ProcessParserSpecAst spec + let (prods,states, startStates,actionTable,immediateActionTable,gotoTable,endOfInputTerminalIdx,errorTerminalIdx,nonTerminals) = + CompilerLalrParserSpec logf spec1 + + let (code,pos) = spec.Header + printfn " %d states" states.Length; + printfn " %d nonterminals" gotoTable.[0].Length; + printfn " %d terminals" actionTable.[0].Length; + printfn " %d productions" prods.Length; + printfn " #rows in action table: %d" actionTable.Length; +(* + printfn "#unique rows in action table: %d" (List.length (Array.foldBack (fun row acc -> insert (Array.to_list row) acc) actionTable [])); + printfn "maximum #different actions per state: %d" (Array.foldBack (fun row acc ->max (List.length (List.foldBack insert (Array.to_list row) [])) acc) actionTable 0); + printfn "average #different actions per state: %d" ((Array.foldBack (fun row acc -> (List.length (List.foldBack insert (Array.to_list row) [])) + acc) actionTable 0) / (Array.length states)); +*) + + cprintfn cos "// Implementation file for parser generated by fsyacc"; + cprintfn cosi "// Signature file for parser generated by fsyacc"; + + if (!light = Some(false)) || (!light = None && checkSuffix output ".ml") then + cprintfn cos "#light \"off\""; + cprintfn cosi "#light \"off\""; + + match !modname with + | None -> () + | Some s -> + match !internal_module with + | true -> + cprintfn cos "module internal %s" s; + cprintfn cosi "module internal %s" s; + | false -> + cprintfn cos "module %s" s; + cprintfn cosi "module %s" s; + + cprintfn cos "#nowarn \"64\";; // turn off warnings that type variables used in production annotations are instantiated to concrete type"; + + for s in !opens do + cprintfn cos "open %s" s; + cprintfn cosi "open %s" s; + + cprintfn cos "open %s" lexlib; + cprintfn cos "open %s.ParseHelpers" parslib; + if !compat then + cprintfn cos "open Microsoft.FSharp.Compatibility.OCaml.Parsing"; + + cprintfn cos "# %d \"%s\"" pos.pos_lnum pos.pos_fname; + cprintfn cos "%s" code; + lineCountOutput := !lineCountOutput + code.Replace("\r","").Split([| '\n' |]).Length; + + cprintfn cos "# %d \"%s\"" !lineCountOutput output; + // Print the datatype for the tokens + cprintfn cos "// This type is the type of tokens accepted by the parser"; + for out in [cos;cosi] do + cprintfn out "type token = "; + for id,typ in spec.Tokens do + match typ with + | None -> cprintfn out " | %s" id + | Some ty -> cprintfn out " | %s of (%s)" id ty; + + // Print the datatype for the token names + cprintfn cos "// This type is used to give symbolic names to token indexes, useful for error messages"; + for out in [cos;cosi] do + cprintfn out "type tokenId = "; + for id,typ in spec.Tokens do + cprintfn out " | TOKEN_%s" id; + cprintfn out " | TOKEN_end_of_input"; + cprintfn out " | TOKEN_error"; + + cprintfn cos "// This type is used to give symbolic names to token indexes, useful for error messages"; + for out in [cos;cosi] do + cprintfn out "type nonTerminalId = "; + for nt in nonTerminals do + cprintfn out " | NONTERM_%s" nt; + + cprintfn cos ""; + cprintfn cos "// This function maps tokens to integer indexes"; + cprintfn cos "let tagOfToken (t:token) = "; + cprintfn cos " match t with"; + spec.Tokens |> List.iteri (fun i (id,typ) -> + cprintfn cos " | %s %s -> %d " id (match typ with Some _ -> "_" | None -> "") i); + cprintfn cosi "/// This function maps tokens to integer indexes"; + cprintfn cosi "val tagOfToken: token -> int"; + + cprintfn cos ""; + cprintfn cos "// This function maps integer indexes to symbolic token ids"; + cprintfn cos "let tokenTagToTokenId (tokenIdx:int) = "; + cprintfn cos " match tokenIdx with"; + spec.Tokens |> List.iteri (fun i (id,typ) -> + cprintfn cos " | %d -> TOKEN_%s " i id) + cprintfn cos " | %d -> TOKEN_end_of_input" endOfInputTerminalIdx; + cprintfn cos " | %d -> TOKEN_error" errorTerminalIdx; + cprintfn cos " | _ -> failwith \"tokenTagToTokenId: bad token\"" + + cprintfn cosi ""; + cprintfn cosi "/// This function maps integer indexes to symbolic token ids"; + cprintfn cosi "val tokenTagToTokenId: int -> tokenId"; + + cprintfn cos ""; + cprintfn cos "/// This function maps production indexes returned in syntax errors to strings representing the non terminal that would be produced by that production"; + cprintfn cos "let prodIdxToNonTerminal (prodIdx:int) = "; + cprintfn cos " match prodIdx with"; + prods |> Array.iteri (fun i (nt,ntIdx,syms,code) -> + cprintfn cos " | %d -> NONTERM_%s " i nt); + cprintfn cos " | _ -> failwith \"prodIdxToNonTerminal: bad production index\"" + + cprintfn cosi ""; + cprintfn cosi "/// This function maps production indexes returned in syntax errors to strings representing the non terminal that would be produced by that production"; + cprintfn cosi "val prodIdxToNonTerminal: int -> nonTerminalId"; + + cprintfn cos ""; + cprintfn cos "let _fsyacc_endOfInputTag = %d " endOfInputTerminalIdx; + cprintfn cos "let _fsyacc_tagOfErrorTerminal = %d" errorTerminalIdx; + cprintfn cos ""; + cprintfn cos "// This function gets the name of a token as a string"; + cprintfn cos "let token_to_string (t:token) = "; + cprintfn cos " match t with "; + spec.Tokens |> List.iteri (fun i (id,typ) -> + cprintfn cos " | %s %s -> \"%s\" " id (match typ with Some _ -> "_" | None -> "") id); + + cprintfn cosi ""; + cprintfn cosi "/// This function gets the name of a token as a string"; + cprintfn cosi "val token_to_string: token -> string"; + + cprintfn cos ""; + cprintfn cos "// This function gets the data carried by a token as an object"; + cprintfn cos "let _fsyacc_dataOfToken (t:token) = "; + cprintfn cos " match t with "; + + for (id,typ) in spec.Tokens do + cprintfn cos " | %s %s -> %s " + id + (match typ with Some _ -> "_fsyacc_x" | None -> "") + (match typ with Some _ -> "Microsoft.FSharp.Core.Operators.box _fsyacc_x" | None -> "(null : System.Object)") + + let tychar = "'cty" + + for (key,_) in spec.Types |> Seq.countBy fst |> Seq.filter (fun (_,n) -> n > 1) do + failwithf "%s is given multiple %%type declarations" key; + + for (key,_) in spec.Tokens |> Seq.countBy fst |> Seq.filter (fun (_,n) -> n > 1) do + failwithf "%s is given %%token declarations" key + + let types = Map.ofList spec.Types + let tokens = Map.ofList spec.Tokens + + let nStates = states.Length + begin + cprintf cos "let _fsyacc_gotos = [| " ; + let numGotoNonTerminals = gotoTable.[0].Length + let gotoIndexes = Array.create numGotoNonTerminals 0 + let gotoTableCurrIndex = ref 0 in + for j = 0 to numGotoNonTerminals-1 do + gotoIndexes.[j] <- !gotoTableCurrIndex; + + (* Count the number of entries in the association table. *) + let count = ref 0 in + for i = 0 to nStates - 1 do + let goto = gotoTable.[i].[j] + match goto with + | None -> () + | Some _ -> incr count + + (* Write the head of the table (i.e. the number of entries and the default value) *) + gotoTableCurrIndex := !gotoTableCurrIndex + 1; + outputCodedUInt16 os !count; + outputCodedUInt16 os anyMarker; + + (* Write the pairs of entries in incremental order by key *) + (* This lets us implement the lookup by a binary chop. *) + for i = 0 to nStates - 1 do + let goto = gotoTable.[i].[j] + match goto with + | None -> () + | Some n -> + gotoTableCurrIndex := !gotoTableCurrIndex + 1; + outputCodedUInt16 os i; + outputCodedUInt16 os n; + cprintfn cos "|]" ; + (* Output offsets into gotos table where the gotos for a particular nonterminal begin *) + cprintf cos "let _fsyacc_sparseGotoTableRowOffsets = [|" ; + for j = 0 to numGotoNonTerminals-1 do + outputCodedUInt16 os gotoIndexes.[j]; + cprintfn cos "|]" ; + end; + + begin + cprintf cos "let _fsyacc_stateToProdIdxsTableElements = [| " ; + let indexes = Array.create states.Length 0 + let currIndex = ref 0 + for j = 0 to states.Length - 1 do + let state = states.[j] + indexes.[j] <- !currIndex; + + (* Write the head of the table (i.e. the number of entries) *) + outputCodedUInt16 os state.Length; + currIndex := !currIndex + state.Length + 1; + + (* Write the pairs of entries in incremental order by key *) + (* This lets us implement the lookup by a binary chop. *) + for prodIdx in state do + outputCodedUInt16 os prodIdx; + cprintfn cos "|]" ; + (* Output offsets into gotos table where the gotos for a particular nonterminal begin *) + cprintf cos "let _fsyacc_stateToProdIdxsTableRowOffsets = [|" ; + for idx in indexes do + outputCodedUInt16 os idx; + cprintfn cos "|]" ; + end; + + begin + let numActionRows = (Array.length actionTable) + let maxActionColumns = Array.length actionTable.[0] + cprintfn cos "let _fsyacc_action_rows = %d" numActionRows; + cprintf cos "let _fsyacc_actionTableElements = [|" ; + let actionIndexes = Array.create numActionRows 0 + + let actionTableCurrIndex = ref 0 + for i = 0 to nStates-1 do + actionIndexes.[i] <- !actionTableCurrIndex; + let actions = actionTable.[i] + let terminalsByAction = new Dictionary<_,int list>(10) + let countPerAction = new Dictionary<_,_>(10) + for terminal = 0 to actions.Length - 1 do + let action = snd actions.[terminal] + if terminalsByAction.ContainsKey action then + terminalsByAction.[action] <- terminal :: terminalsByAction.[action] ; + else + terminalsByAction.[action] <- [terminal]; + if countPerAction.ContainsKey action then + countPerAction.[action] <- countPerAction.[action]+1 + else + countPerAction.[action] <- 1 + + let mostCommonAction = + let mostCommon = ref Error + let max = ref 0 + for (KeyValue(x,y)) in countPerAction do + if y > !max then (mostCommon := x; max := y) + !mostCommon + + (* Count the number of entries in the association table. *) + let count = ref 0 + for (KeyValue(action,terminals)) in terminalsByAction do + for terminals in terminals do + if action <> mostCommonAction then + incr count; + + (* Write the head of the table (i.e. the number of entries and the default value) *) + actionTableCurrIndex := !actionTableCurrIndex + 1; + outputCodedUInt16 os !count; + outputCodedUInt16 os (actionCoding mostCommonAction); + + (* Write the pairs of entries in incremental order by key *) + (* This lets us implement the lookup by a binary chop. *) + for terminal = 0 to Array.length actions-1 do + let action = snd actions.[terminal] in + if action <> mostCommonAction then ( + actionTableCurrIndex := !actionTableCurrIndex + 1; + outputCodedUInt16 os terminal; + outputCodedUInt16 os (actionCoding action); + ); + cprintfn cos "|]" ; + (* Output offsets into actions table where the actions for a particular nonterminal begin *) + cprintf cos "let _fsyacc_actionTableRowOffsets = [|" ; + for j = 0 to numActionRows-1 do + cprintf cos "%a" outputCodedUInt16 actionIndexes.[j]; + cprintfn cos "|]" ; + + end; + begin + cprintf cos "let _fsyacc_reductionSymbolCounts = [|" ; + for nt,ntIdx,syms,code in prods do + cprintf cos "%a" outputCodedUInt16 (List.length syms); + cprintfn cos "|]" ; + end; + begin + cprintf cos "let _fsyacc_productionToNonTerminalTable = [|" ; + for nt,ntIdx,syms,code in prods do + cprintf cos "%a" outputCodedUInt16 ntIdx; + cprintfn cos "|]" ; + end; + begin + cprintf cos "let _fsyacc_immediateActions = [|" ; + for prodIdx in immediateActionTable do + match prodIdx with + | None -> cprintf cos "%a" outputCodedUInt16 anyMarker (* NONE REP *) + | Some act -> cprintf cos "%a" outputCodedUInt16 (actionCoding act) + cprintfn cos "|]" ; + end; + + let getType nt = if types.ContainsKey nt then types.[nt] else "'"+nt + begin + cprintf cos "let _fsyacc_reductions () =" ; + cprintfn cos " [| " ; + for nt,ntIdx,syms,code in prods do + cprintfn cos "# %d \"%s\"" !lineCountOutput output; + cprintfn cos " (fun (parseState : %s.IParseState) ->" parslib + if !compat then + cprintfn cos " Parsing.set_parse_state parseState;" + syms |> List.iteri (fun i sym -> + let tyopt = + match sym with + | Terminal t -> + if tokens.ContainsKey t then + tokens.[t] + else None + | NonTerminal nt -> Some (getType nt) + match tyopt with + | Some ty -> cprintfn cos " let _%d = (let data = parseState.GetInput(%d) in (Microsoft.FSharp.Core.Operators.unbox data : %s)) in" (i+1) (i+1) ty + | None -> ()) + cprintfn cos " Microsoft.FSharp.Core.Operators.box" + cprintfn cos " ("; + cprintfn cos " ("; + match code with + | Some (_,pos) -> cprintfn cos "# %d \"%s\"" pos.pos_lnum pos.pos_fname + | None -> () + match code with + | Some (code,_) -> + let dollar = ref false in + let c = code |> String.collect (fun c -> + if not !dollar && c = '$' then (dollar := true; "") + elif !dollar && c >= '0' && c <= '9' then (dollar := false; "_"+new System.String(c,1)) + elif !dollar then (dollar := false; "$"+new System.String(c,1)) + else new System.String(c,1)) + let lines = c.Split([| '\r'; '\n' |], System.StringSplitOptions.RemoveEmptyEntries); + for line in lines do + cprintfn cos " %s" line; + if !dollar then os.Write '$' + | None -> + cprintfn cos " raise (%s.Accept(Microsoft.FSharp.Core.Operators.box _1))" parslib + cprintfn cos " )"; + // Place the line count back for the type constraint + match code with + | Some (_,pos) -> cprintfn cos "# %d \"%s\"" pos.pos_lnum pos.pos_fname + | None -> () + cprintfn cos " : %s));" (if types.ContainsKey nt then types.[nt] else "'"+nt); + done; + cprintfn cos "|]" ; + end; + cprintfn cos "# %d \"%s\"" !lineCountOutput output; + cprintfn cos "let tables () : %s.Tables<_> = " parslib + cprintfn cos " { reductions= _fsyacc_reductions ();" + cprintfn cos " endOfInputTag = _fsyacc_endOfInputTag;" + cprintfn cos " tagOfToken = tagOfToken;" + cprintfn cos " dataOfToken = _fsyacc_dataOfToken; " + cprintfn cos " actionTableElements = _fsyacc_actionTableElements;" + cprintfn cos " actionTableRowOffsets = _fsyacc_actionTableRowOffsets;" + cprintfn cos " stateToProdIdxsTableElements = _fsyacc_stateToProdIdxsTableElements;" + cprintfn cos " stateToProdIdxsTableRowOffsets = _fsyacc_stateToProdIdxsTableRowOffsets;" + cprintfn cos " reductionSymbolCounts = _fsyacc_reductionSymbolCounts;" + cprintfn cos " immediateActions = _fsyacc_immediateActions;" + cprintfn cos " gotos = _fsyacc_gotos;" + cprintfn cos " sparseGotoTableRowOffsets = _fsyacc_sparseGotoTableRowOffsets;" + cprintfn cos " tagOfErrorTerminal = _fsyacc_tagOfErrorTerminal;" + cprintfn cos " parseError = (fun (ctxt:%s.ParseErrorContext<_>) -> " parslib + cprintfn cos " match parse_error_rich with " + cprintfn cos " | Some f -> f ctxt" + cprintfn cos " | None -> parse_error ctxt.Message);" + + cprintfn cos " numTerminals = %d;" (Array.length actionTable.[0]); + cprintfn cos " productionToNonTerminalTable = _fsyacc_productionToNonTerminalTable }" + cprintfn cos "let engine lexer lexbuf startState = (tables ()).Interpret(lexer, lexbuf, startState)" + + for (id,startState) in List.zip spec.StartSymbols startStates do + if not (types.ContainsKey id) then + failwith ("a %type declaration is required for for start token "+id); + let ty = types.[id] in + cprintfn cos "let %s lexer lexbuf : %s =" id ty; + cprintfn cos " Microsoft.FSharp.Core.Operators.unbox ((tables ()).Interpret(lexer, lexbuf, %d))" startState + + for id in spec.StartSymbols do + if not (types.ContainsKey id) then + failwith ("a %type declaration is required for start token "+id); + let ty = types.[id] in + cprintfn cosi "val %s : (%s.LexBuffer<%s> -> token) -> %s.LexBuffer<%s> -> (%s) " id lexlib tychar lexlib tychar ty; + + logf (fun oso -> oso.Close()) + +[] +let result(args: string[]) = + try + main() + 0 + with e -> + eprintf "FSYACC: error FSY000: %s" (match e with Failure s -> s | e -> e.Message); + 1 diff --git a/src/buildtools/fsyacc/fsyacc.fsproj b/src/buildtools/fsyacc/fsyacc.fsproj new file mode 100644 index 0000000000..286c7a4eb1 --- /dev/null +++ b/src/buildtools/fsyacc/fsyacc.fsproj @@ -0,0 +1,22 @@ + + + + Exe + netcoreapp2.0 + INTERNALIZED_FSLEXYACC_RUNTIME;$(DefineConstant) + + + + + + + + + + + + + + + + diff --git a/src/buildtools/fsyacc/fsyaccast.fs b/src/buildtools/fsyacc/fsyaccast.fs new file mode 100644 index 0000000000..f4edc39972 --- /dev/null +++ b/src/buildtools/fsyacc/fsyaccast.fs @@ -0,0 +1,1000 @@ +// (c) Microsoft Corporation 2005-2007. + +module internal FsLexYacc.FsYacc.AST + +#nowarn "62" // This construct is for ML compatibility. + + +open System +open System.Collections.Generic +open Printf +open Microsoft.FSharp.Collections +open Internal.Utilities +open Internal.Utilities.Text.Lexing + +/// An active pattern that should be in the F# standard library +let (|KeyValue|) (kvp:KeyValuePair<_,_>) = kvp.Key,kvp.Value + + +type Identifier = string +type Code = string * Position + +type ParserSpec= + { Header : Code; + Tokens : (Identifier * string option) list; + Types : (Identifier * string) list; + Associativities: (Identifier * Associativity) list list; + StartSymbols : Identifier list; + Rules : (Identifier * Rule list) list } + +and Rule = Rule of Identifier list * Identifier option * Code option +and Associativity = LeftAssoc | RightAssoc | NonAssoc + +type Terminal = string +type NonTerminal = string +type Symbol = Terminal of Terminal | NonTerminal of NonTerminal +type Symbols = Symbol list + + +//--------------------------------------------------------------------- +// Output Raw Parser Spec AST + +let StringOfSym sym = match sym with Terminal s -> "'" + s + "'" | NonTerminal s -> s + +let OutputSym os sym = fprintf os "%s" (StringOfSym sym) + +let OutputSyms os syms = + fprintf os "%s" (String.Join(" ",Array.map StringOfSym syms)) + +let OutputTerminalSet os (tset:string seq) = + fprintf os "%s" (String.Join(";", tset |> Seq.toArray)) + +let OutputAssoc os p = + match p with + | LeftAssoc -> fprintf os "left" + | RightAssoc -> fprintf os "right" + | NonAssoc -> fprintf os "nonassoc" + + +//--------------------------------------------------------------------- +// PreProcess Raw Parser Spec AST + +type PrecedenceInfo = + | ExplicitPrec of Associativity * int + | NoPrecedence + +type Production = Production of NonTerminal * PrecedenceInfo * Symbols * Code option + +type ProcessedParserSpec = + { Terminals: (Terminal * PrecedenceInfo) list; + NonTerminals: NonTerminal list; + Productions: Production list; + StartSymbols: NonTerminal list } + + +let ProcessParserSpecAst (spec: ParserSpec) = + let explicitPrecInfo = + spec.Associativities + |> List.mapi (fun n precSpecs -> precSpecs |> List.map (fun (precSym, assoc) -> precSym,ExplicitPrec (assoc, 10000 - n))) + |> List.concat + + for (key,_) in explicitPrecInfo |> Seq.countBy fst |> Seq.filter (fun (_,n) -> n > 1) do + failwithf "%s is given two associativities" key + + let explicitPrecInfo = + explicitPrecInfo |> Map.ofList + + let implicitSymPrecInfo = NoPrecedence + let terminals = List.map fst spec.Tokens @ ["error"]in + let terminalSet = Set.ofList terminals + let IsTerminal z = terminalSet.Contains(z) + let prec_of_terminal sym implicitPrecInfo = + if explicitPrecInfo.ContainsKey(sym) then explicitPrecInfo.[sym] + else match implicitPrecInfo with Some x -> x | None -> implicitSymPrecInfo + + let mkSym s = if IsTerminal s then Terminal s else NonTerminal s + let prods = + spec.Rules |> List.mapi (fun i (nonterm,rules) -> + rules |> List.mapi (fun j (Rule(syms,precsym,code)) -> + let precInfo = + let precsym = List.foldBack (fun x acc -> match acc with Some _ -> acc | None -> match x with z when IsTerminal z -> Some z | _ -> acc) syms precsym + let implicitPrecInfo = NoPrecedence + match precsym with + | None -> implicitPrecInfo + | Some sym -> if explicitPrecInfo.ContainsKey(sym) then explicitPrecInfo.[sym] else implicitPrecInfo + Production(nonterm, precInfo, List.map mkSym syms, code))) + |> List.concat + let nonTerminals = List.map fst spec.Rules + let nonTerminalSet = Set.ofList nonTerminals + let checkNonTerminal nt = + if nt <> "error" && not (nonTerminalSet.Contains(nt)) then + failwith (sprintf "NonTerminal '%s' has no productions" nt) + + for (Production(nt,_,syms,_)) in prods do + for sym in syms do + match sym with + | NonTerminal nt -> + checkNonTerminal nt + | Terminal t -> + if not (IsTerminal t) then failwith (sprintf "token %s is not declared" t) + + if spec.StartSymbols= [] then (failwith "at least one %start declaration is required"); + + for (nt,_) in spec.Types do + checkNonTerminal nt; + + let terminals = terminals |> List.map (fun t -> (t,prec_of_terminal t None)) + + { Terminals=terminals; + NonTerminals=nonTerminals; + Productions=prods; + StartSymbols=spec.StartSymbols } + + +//------------------------------------------------- +// Process LALR(1) grammars to tables + +type ProductionIndex = int +type ProdictionDotIndex = int + +/// Represent (ProductionIndex,ProdictionDotIndex) as one integer +type Item0 = uint32 + +let mkItem0 (prodIdx,dotIdx) : Item0 = (uint32 prodIdx <<< 16) ||| uint32 dotIdx +let prodIdx_of_item0 (item0:Item0) = int32 (item0 >>> 16) +let dotIdx_of_item0 (item0:Item0) = int32 (item0 &&& 0xFFFFu) + +/// Part of the output of CompilerLalrParserSpec +type Action = + | Shift of int + | Reduce of ProductionIndex + | Accept + | Error + +let outputPrecInfo os p = + match p with + | ExplicitPrec (assoc,n) -> fprintf os "explicit %a %d" OutputAssoc assoc n + | NoPrecedence -> fprintf os "noprec" + + +/// LR(0) kernels +type Kernel = Set + +/// Indexes of LR(0) kernels in the KernelTable +type KernelIdx = int + +/// Indexes in the TerminalTable and NonTerminalTable +type TerminalIndex = int +type NonTerminalIndex = int + +/// Representation of Symbols. +/// Ideally would be declared as +/// type SymbolIndex = PTerminal of TerminalIndex | PNonTerminal of NonTerminalIndex +/// but for performance reasons we embed as a simple integer (saves ~10%) +/// +/// We use an active pattern to reverse the embedding. +type SymbolIndex = int +let PTerminal(i:TerminalIndex) : SymbolIndex = -i-1 +let PNonTerminal(i:NonTerminalIndex) : SymbolIndex = i +let (|PTerminal|PNonTerminal|) x = if x < 0 then PTerminal (-(x+1)) else PNonTerminal x + +type SymbolIndexes = SymbolIndex list + +/// Indexes in the LookaheadTable, SpontaneousTable, PropagateTable +/// Embed in a single integer, since these are faster +/// keys for the dictionary hash tables +/// +/// Logically: +/// +/// type KernelItemIndex = KernelItemIdx of KernelIdx * Item0 +type KernelItemIndex = int64 +let KernelItemIdx (i1,i2) = ((int64 i1) <<< 32) ||| int64 i2 + + +/// Indexes into the memoizing table for the Goto computations +/// Embed in a single integer, since these are faster +/// keys for the dictionary hash tables +/// +/// Logically: +/// +/// type GotoItemIndex = GotoItemIdx of KernelIdx * SymbolIndex +type GotoItemIndex = uint64 +let GotoItemIdx (i1:KernelIdx,i2:SymbolIndex) = (uint64 (uint32 i1) <<< 32) ||| uint64 (uint32 i2) +let (|GotoItemIdx|) (i64:uint64) = int32 ((i64 >>> 32) &&& 0xFFFFFFFFUL), int32 (i64 &&& 0xFFFFFFFFUL) + +/// Create a work list and loop until it is exhausted, calling a worker function for +/// each element. Pass a function to queue additional work on the work list +/// to the worker function +let ProcessWorkList start f = + let work = ref (start : 'a list) + let queueWork = (fun x -> work := x :: !work) + let rec loop() = + match !work with + | [] -> () + | x::t -> + work := t; + f queueWork x; + loop() + loop() + +/// A standard utility to compute a least fixed point of a set under a generative computation +let LeastFixedPoint f set = + let acc = ref set + ProcessWorkList (Set.toList set) (fun queueWork item -> + f(item) |> List.iter (fun i2 -> if not (Set.contains i2 !acc) then (acc := Set.add i2 !acc; queueWork i2)) ) + !acc + +/// A general standard memoization utility. Be sure to apply to only one (function) argument to build the +/// residue function! +let Memoize f = + let t = new Dictionary<_,_>(1000) + fun x -> + let ok,v = t.TryGetValue(x) + if ok then v else let res = f x in t.[x] <- res; res + +/// A standard utility to create a dictionary from a list of pairs +let CreateDictionary xs = + let dict = new Dictionary<_,_>() + for x,y in xs do dict.Add(x,y) + dict + +/// Allocate indexes for each non-terminal +type NonTerminalTable(nonTerminals:NonTerminal list) = + let nonterminalsWithIdxs = List.mapi (fun (i:NonTerminalIndex) n -> (i,n)) nonTerminals + let nonterminalIdxs = List.map fst nonterminalsWithIdxs + let a = Array.ofList nonTerminals + let b = CreateDictionary [ for i,x in nonterminalsWithIdxs -> x,i ]; + member table.OfIndex(i) = a.[i] + member table.ToIndex(i) = b.[i] + member table.Indexes = nonterminalIdxs + +/// Allocate indexes for each terminal +type TerminalTable(terminals:(Terminal * PrecedenceInfo) list) = + let terminalsWithIdxs = List.mapi (fun i (t,_) -> (i,t)) terminals + let terminalIdxs = List.map fst terminalsWithIdxs + let a = Array.ofList (List.map fst terminals) + let b = Array.ofList (List.map snd terminals) + let c = CreateDictionary [ for i,x in terminalsWithIdxs -> x,i ] + + member table.OfIndex(i) = a.[i] + member table.PrecInfoOfIndex(i) = b.[i] + member table.ToIndex(i) = c.[i] + member table.Indexes = terminalIdxs + +/// Allocate indexes for each production +type ProductionTable(ntTab:NonTerminalTable, termTab:TerminalTable, nonTerminals:string list, prods: Production list) = + let prodsWithIdxs = List.mapi (fun i n -> (i,n)) prods + let a = + prodsWithIdxs + |> List.map(fun (_,Production(_,_,syms,_)) -> + syms + |> Array.ofList + |> Array.map (function + | Terminal t -> PTerminal (termTab.ToIndex t) + | NonTerminal nt -> PNonTerminal (ntTab.ToIndex nt )) ) + |> Array.ofList + let b = Array.ofList (List.map (fun (_,Production(nt,_,_,_)) -> ntTab.ToIndex nt) prodsWithIdxs) + let c = Array.ofList (List.map (fun (_,Production(_,prec,_,_)) -> prec) prodsWithIdxs) + let productions = + nonTerminals + |> List.map(fun nt -> (ntTab.ToIndex nt, List.choose (fun (i,Production(nt2,prec,syms,_)) -> if nt2=nt then Some i else None) prodsWithIdxs)) + |> CreateDictionary + + member prodTab.Symbols(i) = a.[i] + member prodTab.NonTerminal(i) = b.[i] + member prodTab.Precedence(i) = c.[i] + member prodTab.Symbol i n = + let syms = prodTab.Symbols i + if n >= syms.Length then None else Some (syms.[n]) + member prodTab.Productions = productions + +/// A mutable table maping kernels to sets of lookahead tokens +type LookaheadTable() = + let t = new Dictionary>() + member table.Add(x,y) = + let prev = if t.ContainsKey(x) then t.[x] else Set.empty + t.[x] <- prev.Add(y) + member table.Contains(x,y) = t.ContainsKey(x) && t.[x].Contains(y) + member table.GetLookaheads(idx:KernelItemIndex) = + let ok,v = t.TryGetValue(idx) + if ok then v else Set.empty + member table.Count = t |> Seq.fold(fun acc (KeyValue(_,v)) -> v.Count+acc) 0 + +/// A mutable table giving an index to each LR(0) kernel. Kernels are referred to only by index. +type KernelTable(kernels) = + // Give an index to each LR(0) kernel, and from now on refer to them only by index + // Also develop "kernelItemIdx" to refer to individual items within a kernel + let kernelsAndIdxs = List.mapi (fun i x -> (i,x)) kernels + let kernelIdxs = List.map fst kernelsAndIdxs + let toIdxMap = Map.ofList [ for i,x in kernelsAndIdxs -> x,i ] + let ofIdxMap = Array.ofList kernels + member t.Indexes = kernelIdxs + member t.Index(kernel) = toIdxMap.[kernel] + member t.Kernel(i) = ofIdxMap.[i] + +/// Hold the results of cpmuting the LALR(1) closure of an LR(0) kernel +type Closure1Table() = + let t = new Dictionary>() + member table.Add(a,b) = + if not (t.ContainsKey(a)) then t.[a] <- new HashSet<_>(HashIdentity.Structural) + t.[a].Add(b) + member table.Count = t.Count + member table.IEnumerable = (t :> seq<_>) + member table.Contains(a,b) = t.ContainsKey(a) && t.[a].Contains(b) + +/// A mutable table giving a lookahead set Set for each kernel. The terminals represent the +/// "spontaneous" items for the kernel. TODO: document this more w.r.t. the Dragon book. +type SpontaneousTable() = + let t = new Dictionary>() + member table.Add(a,b) = + if not (t.ContainsKey(a)) then t.[a] <- new HashSet<_>(HashIdentity.Structural) + t.[a].Add(b) + member table.Count = t.Count + member table.IEnumerable = (t :> seq<_>) + +/// A mutable table giving a Set for each kernel. The kernels represent the +/// "propagate" items for the kernel. TODO: document this more w.r.t. the Dragon book. +type PropagateTable() = + let t = new Dictionary>() + member table.Add(a,b) = + if not (t.ContainsKey(a)) then t.[a] <- new HashSet(HashIdentity.Structural) + t.[a].Add(b) + member table.Item + with get(a) = + let ok,v = t.TryGetValue(a) + if ok then v :> seq<_> else Seq.empty + member table.Count = t.Count + + +/// Compile a pre-processed LALR parser spec to tables following the Dragon book algorithm +let CompilerLalrParserSpec logf (spec : ProcessedParserSpec) = + let stopWatch = new System.Diagnostics.Stopwatch() + let reportTime() = printfn " time: %A" stopWatch.Elapsed; stopWatch.Reset(); stopWatch.Start() + stopWatch.Start() + + // Augment the grammar + let fakeStartNonTerminals = spec.StartSymbols |> List.map(fun nt -> "_start" + nt) + let nonTerminals = fakeStartNonTerminals@spec.NonTerminals + let endOfInputTerminal = "$$" + let dummyLookahead = "#" + let dummyPrec = NoPrecedence + let terminals = spec.Terminals @ [(dummyLookahead,dummyPrec); (endOfInputTerminal,dummyPrec)] + let prods = List.map2 (fun a b -> Production(a, dummyPrec,[NonTerminal b],None)) fakeStartNonTerminals spec.StartSymbols @ spec.Productions + let startNonTerminalIdx_to_prodIdx (i:int) = i + + // Build indexed tables + let ntTab = NonTerminalTable(nonTerminals) + let termTab = TerminalTable(terminals) + let prodTab = ProductionTable(ntTab,termTab,nonTerminals,prods) + let dummyLookaheadIdx = termTab.ToIndex dummyLookahead + let endOfInputTerminalIdx = termTab.ToIndex endOfInputTerminal + + let errorTerminalIdx = termTab.ToIndex "error" + + // Compute the FIRST function + printf "computing first function..."; stdout.Flush(); + + let computedFirstTable = + let seed = + Map.ofList + [ for term in termTab.Indexes do yield (PTerminal(term),Set.singleton (Some term)) + for nonTerm in ntTab.Indexes do + yield + (PNonTerminal nonTerm, + List.foldBack + (fun prodIdx acc -> match prodTab.Symbol prodIdx 0 with None -> Set.add None acc | Some _ -> acc) + prodTab.Productions.[nonTerm] + Set.empty) ] + + let add changed ss (x,y) = + let s = Map.find x ss + if Set.contains y s then ss + else (changed := true; Map.add x (Set.add y s) ss) + + let oneRound (ss:Map<_,_>) = + let changed = ref false + let frontier = + let res = ref [] + for nonTermX in ntTab.Indexes do + for prodIdx in prodTab.Productions.[nonTermX] do + let rhs = Array.toList (prodTab.Symbols prodIdx) + let rec place l = + match l with + | (yi::t) -> + res := + List.choose + (function None -> None | Some a -> Some (PNonTerminal nonTermX,Some a)) + (Set.toList ss.[yi]) + @ !res; + if ss.[yi].Contains(None) then place t; + | [] -> + res := (PNonTerminal nonTermX,None) :: !res + place rhs + !res + let ss' = List.fold (add changed) ss frontier + !changed, ss' + + let rec loop ss = + let changed, ss' = oneRound ss + if changed then loop ss' else ss' + loop seed + + + /// Compute the first set of the given sequence of non-terminals. If any of the non-terminals + /// have an empty token in the first set then we have to iterate through those. + let ComputeFirstSetOfTokenList = + Memoize (fun (str,term) -> + let acc = new System.Collections.Generic.List<_>() + let rec add l = + match l with + | [] -> acc.Add(term) + | sym::moreSyms -> + let firstSetOfSym = computedFirstTable.[sym] + firstSetOfSym |> Set.iter (function None -> () | Some v -> acc.Add(v)) + if firstSetOfSym.Contains(None) then add moreSyms + add str; + Set.ofSeq acc) + + // (int,int) representation of LR(0) items + let prodIdx_to_item0 idx = mkItem0(idx,0) + let prec_of_item0 item0 = prodTab.Precedence (prodIdx_of_item0 item0) + let ntIdx_of_item0 item0 = prodTab.NonTerminal (prodIdx_of_item0 item0) + + let lsyms_of_item0 item0 = + let prodIdx = prodIdx_of_item0 item0 + let dotIdx = dotIdx_of_item0 item0 + let syms = prodTab.Symbols prodIdx + if dotIdx <= 0 then [||] else syms.[..dotIdx-1] + + let rsyms_of_item0 item0 = + let prodIdx = prodIdx_of_item0 item0 + let dotIdx = dotIdx_of_item0 item0 + let syms = prodTab.Symbols prodIdx + syms.[dotIdx..] + + let rsym_of_item0 item0 = + let prodIdx = prodIdx_of_item0 item0 + let dotIdx = dotIdx_of_item0 item0 + prodTab.Symbol prodIdx dotIdx + + let advance_of_item0 item0 = + let prodIdx = prodIdx_of_item0 item0 + let dotIdx = dotIdx_of_item0 item0 + mkItem0(prodIdx,dotIdx+1) + let fakeStartNonTerminalsSet = Set.ofList (fakeStartNonTerminals |> List.map ntTab.ToIndex) + + let IsStartItem item0 = fakeStartNonTerminalsSet.Contains(ntIdx_of_item0 item0) + let IsKernelItem item0 = (IsStartItem item0 || dotIdx_of_item0 item0 <> 0) + + let StringOfSym sym = match sym with PTerminal s -> "'" + termTab.OfIndex s + "'" | PNonTerminal s -> ntTab.OfIndex s + + let OutputSym os sym = fprintf os "%s" (StringOfSym sym) + + let OutputSyms os syms = + fprintf os "%s" (String.Join(" ",Array.map StringOfSym syms)) + + // Print items and other stuff + let OutputItem0 os item0 = + fprintf os " %s -> %a . %a" (ntTab.OfIndex (ntIdx_of_item0 item0)) (* outputPrecInfo precInfo *) OutputSyms (lsyms_of_item0 item0) OutputSyms (rsyms_of_item0 item0) + + let OutputItem0Set os s = + Set.iter (fun item -> fprintfn os "%a" OutputItem0 item) s + + let OutputFirstSet os m = + Set.iter (function None -> fprintf os "" | Some x -> fprintfn os " term %s" x) m + + let OutputFirstMap os m = + Map.iter (fun x y -> fprintf os "first '%a' = " OutputSym x; fprintfn os "%a" OutputFirstSet y) m + + let OutputAction os m = + match m with + | Shift n -> fprintf os " shift %d" n + | Reduce prodIdx -> fprintf os " reduce %s --> %a" (ntTab.OfIndex (prodTab.NonTerminal prodIdx)) OutputSyms (prodTab.Symbols prodIdx) + | Error -> fprintf os " error" + | Accept -> fprintf os " accept" + + let OutputActions os m = + Array.iteri (fun i (prec,action) -> let term = termTab.OfIndex i in fprintfn os " action '%s' (%a): %a" term outputPrecInfo prec OutputAction action) m + + let OutputActionTable os m = + Array.iteri (fun i n -> fprintfn os "state %d:" i; fprintfn os "%a" OutputActions n) m + + let OutputImmediateActions os m = + match m with + | None -> fprintf os "" + | Some a -> OutputAction os a + + let OutputGotos os m = + Array.iteri (fun ntIdx s -> let nonterm = ntTab.OfIndex ntIdx in match s with Some st -> fprintfn os " goto %s: %d" nonterm st | None -> ()) m + + let OutputCombined os m = + Array.iteri (fun i (a,b,c,d) -> + fprintf os "state %d:" i + fprintf os " items:" + fprintf os "%a" OutputItem0Set a + fprintf os " actions:" + fprintf os "%a" OutputActions b + fprintf os " immediate action: " + fprintf os "%a" OutputImmediateActions c + fprintf os " gotos:" + fprintf os "%a" OutputGotos d) m + + let OutputLalrTables os (prods,states, startStates,actionTable,immediateActionTable,gotoTable,endOfInputTerminalIdx,errorTerminalIdx) = + let combined = Array.ofList (List.map2 (fun x (y,(z,w)) -> x,y,z,w) (Array.toList states) (List.zip (Array.toList actionTable) (List.zip (Array.toList immediateActionTable) (Array.toList gotoTable)))) + fprintfn os "------------------------"; + fprintfn os "states = "; + fprintfn os "%a" OutputCombined combined; + fprintfn os "startStates = %s" (String.Join(";",Array.ofList (List.map string startStates))); + fprintfn os "------------------------" + + + // Closure of LR(0) nonTerminals, items etc + let ComputeClosure0NonTerminal = + Memoize (fun nt -> + let seed = (List.foldBack (prodIdx_to_item0 >> Set.add) prodTab.Productions.[nt] Set.empty) + LeastFixedPoint + (fun item0 -> + match rsym_of_item0 item0 with + | None -> [] + | Some(PNonTerminal ntB) -> List.map prodIdx_to_item0 prodTab.Productions.[ntB] + | Some(PTerminal _) -> []) + seed) + + // Close a symbol under epsilon moves + let ComputeClosure0Symbol rsym acc = + match rsym with + | Some (PNonTerminal nt) -> Set.union (ComputeClosure0NonTerminal nt) acc + | _ -> acc + + // Close a set under epsilon moves + let ComputeClosure0 iset = + Set.fold (fun acc x -> ComputeClosure0Symbol (rsym_of_item0 x) acc) iset iset + + // Right symbols after closing under epsilon moves + let RelevantSymbolsOfKernel kernel = + let kernelClosure0 = ComputeClosure0 kernel + Set.fold (fun acc x -> Option.fold (fun acc x -> Set.add x acc) acc (rsym_of_item0 x)) Set.empty kernelClosure0 + + // Goto set of a kernel of LR(0) nonTerminals, items etc + // Input is kernel, output is kernel + let ComputeGotosOfKernel iset sym = + let isetClosure = ComputeClosure0 iset + let acc = new System.Collections.Generic.List<_>(10) + isetClosure |> Set.iter (fun item0 -> + match rsym_of_item0 item0 with + | Some sym2 when sym = sym2 -> acc.Add(advance_of_item0 item0) + | _ -> ()) + Set.ofSeq acc + + // Build the full set of LR(0) kernels + reportTime(); printf "building kernels..."; stdout.Flush(); + let startItems = List.mapi (fun i _ -> prodIdx_to_item0 (startNonTerminalIdx_to_prodIdx i)) fakeStartNonTerminals + let startKernels = List.map Set.singleton startItems + let kernels = + + /// We use a set-of-sets here. F# sets support structural comparison but at the time of writing + /// did not structural hashing. + let acc = ref Set.empty + ProcessWorkList startKernels (fun addToWorkList kernel -> + if not ((!acc).Contains(kernel)) then + acc := (!acc).Add(kernel); + for csym in RelevantSymbolsOfKernel kernel do + let gotoKernel = ComputeGotosOfKernel kernel csym + assert (gotoKernel.Count > 0) + addToWorkList gotoKernel ) + + !acc |> Seq.toList |> List.map (Set.filter IsKernelItem) + + reportTime(); printf "building kernel table..."; stdout.Flush(); + // Give an index to each LR(0) kernel, and from now on refer to them only by index + let kernelTab = new KernelTable(kernels) + let startKernelIdxs = List.map kernelTab.Index startKernels + let startKernelItemIdxs = List.map2 (fun a b -> KernelItemIdx(a,b)) startKernelIdxs startItems + + let outputKernelItemIdx os (kernelIdx,item0) = + fprintf os "kernel %d, item %a" kernelIdx OutputItem0 item0 + + /// A cached version of the "goto" computation on LR(0) kernels + let gotoKernel = + Memoize (fun (GotoItemIdx(kernelIdx,sym)) -> + let gset = ComputeGotosOfKernel (kernelTab.Kernel kernelIdx) sym + if gset.IsEmpty then None else Some (kernelTab.Index gset)) + + /// Iterate (iset,sym) pairs such that (gotoKernel kernelIdx sym) is not empty + let IterateGotosOfKernel kernelIdx f = + for sym in RelevantSymbolsOfKernel (kernelTab.Kernel kernelIdx) do + match gotoKernel (GotoItemIdx(kernelIdx,sym)) with + | None -> () + | Some k -> f sym k + + + // This is used to compute the closure of an LALR(1) kernel + // + // For each item [A --> X.BY, a] in I + // For each production B -> g in G' + // For each terminal b in FIRST(Ya) + // such that [B --> .g, b] is not in I do + // add [B --> .g, b] to I + + let ComputeClosure1 iset = + let acc = new Closure1Table() + ProcessWorkList iset (fun addToWorkList (item0,pretokens:Set) -> + pretokens |> Set.iter (fun pretoken -> + if not (acc.Contains(item0,pretoken)) then + acc.Add(item0,pretoken) |> ignore + let rsyms = rsyms_of_item0 item0 + if rsyms.Length > 0 then + match rsyms.[0] with + | (PNonTerminal ntB) -> + let firstSet = ComputeFirstSetOfTokenList (Array.toList rsyms.[1..],pretoken) + for prodIdx in prodTab.Productions.[ntB] do + addToWorkList (prodIdx_to_item0 prodIdx,firstSet) + | PTerminal _ -> ())) + acc + + // Compute the "spontaneous" and "propagate" maps for each LR(0) kernelItem + // + // Input: The kernal K of a set of LR(0) items I and a grammar symbol X + // + // Output: The lookaheads generated spontaneously by items in I for kernel items + // in goto(I,X) and the items I from which lookaheads are propagated to kernel + // items in goto(I,X) + // + // Method + // 1. Construct LR(0) kernel items (done - above) + // 2. + // TODO: this is very, very slow. + // + // PLAN TO OPTIMIZE THIS; + // - Clarify and comment what's going on here + // - verify if we really have to do these enormouos closure computations + // - assess if it's possible to use the symbol we're looking for to help trim the jset + + reportTime(); printf "computing lookahead relations..."; stdout.Flush(); + + + let spontaneous, propagate = + let closure1OfItem0WithDummy = + Memoize (fun item0 -> ComputeClosure1 [(item0,Set.ofList [dummyLookaheadIdx])]) + + let spontaneous = new SpontaneousTable() + let propagate = new PropagateTable() + let count = ref 0 + + for kernelIdx in kernelTab.Indexes do + printf "."; stdout.Flush(); + //printf "kernelIdx = %d\n" kernelIdx; stdout.Flush(); + let kernel = kernelTab.Kernel(kernelIdx) + for item0 in kernel do + let item0Idx = KernelItemIdx(kernelIdx,item0) + let jset = closure1OfItem0WithDummy item0 + //printf "#jset = %d\n" jset.Count; stdout.Flush(); + for (KeyValue(closureItem0, lookaheadTokens)) in jset.IEnumerable do + incr count + match rsym_of_item0 closureItem0 with + | None -> () + | Some rsym -> + match gotoKernel (GotoItemIdx(kernelIdx,rsym)) with + | None -> () + | Some gotoKernelIdx -> + let gotoItem = advance_of_item0 closureItem0 + let gotoItemIdx = KernelItemIdx(gotoKernelIdx,gotoItem) + for lookaheadToken in lookaheadTokens do + if lookaheadToken = dummyLookaheadIdx + then propagate.Add(item0Idx, gotoItemIdx) |> ignore + else spontaneous.Add(gotoItemIdx, lookaheadToken) |> ignore + + + //printfn "#kernelIdxs = %d, count = %d" kernelTab.Indexes.Length !count + spontaneous, + propagate + + //printfn "#spontaneous = %d, #propagate = %d" spontaneous.Count propagate.Count; stdout.Flush(); + + //exit 0; + // Repeatedly use the "spontaneous" and "propagate" maps to build the full set + // of lookaheads for each LR(0) kernelItem. + reportTime(); printf "building lookahead table..."; stdout.Flush(); + let lookaheadTable = + + // Seed the table with the startKernelItems and the spontaneous info + let initialWork = + [ for idx in startKernelItemIdxs do + yield (idx,endOfInputTerminalIdx) + for (KeyValue(kernelItemIdx,lookaheads)) in spontaneous.IEnumerable do + for lookahead in lookaheads do + yield (kernelItemIdx,lookahead) ] + + let acc = new LookaheadTable() + // Compute the closure + ProcessWorkList + initialWork + (fun queueWork (kernelItemIdx,lookahead) -> + acc.Add(kernelItemIdx,lookahead) + for gotoKernelIdx in propagate.[kernelItemIdx] do + if not (acc.Contains(gotoKernelIdx,lookahead)) then + queueWork(gotoKernelIdx,lookahead)) + acc + + //printf "built lookahead table, #lookaheads = %d\n" lookaheadTable.Count; stdout.Flush(); + + reportTime(); printf "building action table..."; stdout.Flush(); + let shiftReduceConflicts = ref 0 + let reduceReduceConflicts = ref 0 + let actionTable, immediateActionTable = + + // Now build the action tables. First a utility to merge the given action + // into the table, taking into account precedences etc. and reporting errors. + let addResolvingPrecedence (arr: _[]) kernelIdx termIdx (precNew, actionNew) = + // printf "DEBUG: state %d: adding action for %s, precNew = %a, actionNew = %a\n" kernelIdx (termTab.OfIndex termIdx) outputPrec precNew OutputAction actionNew; + // We add in order of precedence - however the precedences may be the same, and we give warnings when rpecedence resolution is based on implicit file orderings + + let (precSoFar, actionSoFar) as itemSoFar = arr.[termIdx] + + // printf "DEBUG: state %d: adding action for %s, precNew = %a, precSoFar = %a, actionSoFar = %a\n" kernelIdx (termTab.OfIndex termIdx) outputPrec precNew outputPrec precSoFar OutputAction actionSoFar; + // if compare_prec precSoFar precNew = -1 then failwith "addResolvingPrecedence"; + + let itemNew = (precNew, actionNew) + let winner = + let reportConflict x1 x2 reason = + let reportAction (p, a) = + let an, astr = + match a with + | Shift x -> "shift", sprintf "shift(%d)" x + | Reduce x -> + let nt = prodTab.NonTerminal x + "reduce", prodTab.Symbols x + |> Array.map StringOfSym + |> String.concat " " + |> sprintf "reduce(%s:%s)" (ntTab.OfIndex nt) + | _ -> "", "" + let pstr = + match p with + | ExplicitPrec (assoc,n) -> + let astr = + match assoc with + | LeftAssoc -> "left" + | RightAssoc -> "right" + | NonAssoc -> "nonassoc" + sprintf "[explicit %s %d]" astr n + | NoPrecedence -> + "noprec" + an, "{" + pstr + " " + astr + "}" + let a1n, astr1 = reportAction x1 + let a2n, astr2 = reportAction x2 + printfn " %s/%s error at state %d on terminal %s between %s and %s - assuming the former because %s" a1n a2n kernelIdx (termTab.OfIndex termIdx) astr1 astr2 reason + match itemSoFar,itemNew with + | (_,Shift s1),(_, Shift s2) -> + if actionSoFar <> actionNew then + reportConflict itemSoFar itemNew "internal error" + itemSoFar + + | (((precShift,Shift sIdx) as shiftItem), + ((precReduce,Reduce prodIdx) as reduceItem)) + | (((precReduce,Reduce prodIdx) as reduceItem), + ((precShift,Shift sIdx) as shiftItem)) -> + match precReduce, precShift with + | (ExplicitPrec (_,p1), ExplicitPrec(assocNew,p2)) -> + if p1 < p2 then shiftItem + elif p1 > p2 then reduceItem + else + match assocNew with + | LeftAssoc -> reduceItem + | RightAssoc -> shiftItem + | NonAssoc -> + reportConflict shiftItem reduceItem "we prefer shift on equal precedences" + incr shiftReduceConflicts; + shiftItem + | _ -> + reportConflict shiftItem reduceItem "we prefer shift when unable to compare precedences" + incr shiftReduceConflicts; + shiftItem + | ((_,Reduce prodIdx1),(_, Reduce prodIdx2)) -> + "we prefer the rule earlier in the file" + |> if prodIdx1 < prodIdx2 then reportConflict itemSoFar itemNew else reportConflict itemNew itemSoFar + incr reduceReduceConflicts; + if prodIdx1 < prodIdx2 then itemSoFar else itemNew + | _ -> itemNew + arr.[termIdx] <- winner + + + // This build the action table for one state. + let ComputeActions kernelIdx = + let kernel = kernelTab.Kernel kernelIdx + let arr = Array.create terminals.Length (NoPrecedence,Error) + + //printf "building lookahead table LR(1) items for kernelIdx %d\n" kernelIdx; stdout.Flush(); + + // Compute the LR(1) items based on lookaheads + let items = + [ for item0 in kernel do + let kernelItemIdx = KernelItemIdx(kernelIdx,item0) + let lookaheads = lookaheadTable.GetLookaheads(kernelItemIdx) + yield (item0,lookaheads) ] + |> ComputeClosure1 + + for (KeyValue(item0,lookaheads)) in items.IEnumerable do + + let nonTermA = ntIdx_of_item0 item0 + match rsym_of_item0 item0 with + | Some (PTerminal termIdx) -> + let action = + match gotoKernel (GotoItemIdx(kernelIdx,PTerminal termIdx)) with + | None -> failwith "action on terminal should have found a non-empty goto state" + | Some gkernelItemIdx -> Shift gkernelItemIdx + let prec = termTab.PrecInfoOfIndex termIdx + addResolvingPrecedence arr kernelIdx termIdx (prec, action) + | None -> + for lookahead in lookaheads do + if not (IsStartItem(item0)) then + let prodIdx = prodIdx_of_item0 item0 + let prec = prec_of_item0 item0 + let action = (prec, Reduce prodIdx) + addResolvingPrecedence arr kernelIdx lookahead action + elif lookahead = endOfInputTerminalIdx then + let prec = prec_of_item0 item0 + let action = (prec,Accept) + addResolvingPrecedence arr kernelIdx lookahead action + else () + | _ -> () + + // If there is a single item A -> B C . and no Shift or Accept actions (i.e. only Error or Reduce, so the choice of terminal + // cannot affect what we do) then we emit an immediate reduce action for the rule corresponding to that item + // Also do the same for Accept rules. + let closure = (ComputeClosure0 kernel) + + let immediateAction = + match Set.toList closure with + | [item0] -> + match (rsym_of_item0 item0) with + | None when (let reduceOrErrorAction = function Error | Reduce _ -> true | Shift _ | Accept -> false + termTab.Indexes |> List.forall(fun terminalIdx -> reduceOrErrorAction (snd(arr.[terminalIdx])))) + -> Some (Reduce (prodIdx_of_item0 item0)) + + | None when (let acceptOrErrorAction = function Error | Accept -> true | Shift _ | Reduce _ -> false + List.forall (fun terminalIdx -> acceptOrErrorAction (snd(arr.[terminalIdx]))) termTab.Indexes) + -> Some Accept + + | _ -> None + | _ -> None + + // A -> B C . rules give rise to reductions in favour of errors + for item0 in ComputeClosure0 kernel do + let prec = prec_of_item0 item0 + match rsym_of_item0 item0 with + | None -> + for terminalIdx in termTab.Indexes do + if snd(arr.[terminalIdx]) = Error then + let prodIdx = prodIdx_of_item0 item0 + let action = (prec, (if IsStartItem(item0) then Accept else Reduce prodIdx)) + addResolvingPrecedence arr kernelIdx terminalIdx action + | _ -> () + + arr,immediateAction + + let actionInfo = List.map ComputeActions kernelTab.Indexes + Array.ofList (List.map fst actionInfo), + Array.ofList (List.map snd actionInfo) + + // The goto table is much simpler - it is based on LR(0) kernels alone. + + reportTime(); printf " building goto table..."; stdout.Flush(); + let gotoTable = + let gotos kernelIdx = Array.ofList (List.map (fun nt -> gotoKernel (GotoItemIdx(kernelIdx,PNonTerminal nt))) ntTab.Indexes) + Array.ofList (List.map gotos kernelTab.Indexes) + + reportTime(); printfn " returning tables."; stdout.Flush(); + if !shiftReduceConflicts > 0 then printfn " %d shift/reduce conflicts" !shiftReduceConflicts; stdout.Flush(); + if !reduceReduceConflicts > 0 then printfn " %d reduce/reduce conflicts" !reduceReduceConflicts; stdout.Flush(); + if !shiftReduceConflicts > 0 || !reduceReduceConflicts > 0 then printfn " consider setting precedences explicitly using %%left %%right and %%nonassoc on terminals and/or setting explicit precedence on rules using %%prec" + + /// The final results + let states = kernels |> Array.ofList + let prods = Array.ofList (List.map (fun (Production(nt,prec,syms,code)) -> (nt, ntTab.ToIndex nt, syms,code)) prods) + + logf (fun logStream -> + printfn "writing tables to log"; stdout.Flush(); + OutputLalrTables logStream (prods, states, startKernelIdxs, actionTable, immediateActionTable, gotoTable, (termTab.ToIndex endOfInputTerminal), errorTerminalIdx)); + + let states = states |> Array.map (Set.toList >> List.map prodIdx_of_item0) + (prods, states, startKernelIdxs, + actionTable, immediateActionTable, gotoTable, + (termTab.ToIndex endOfInputTerminal), + errorTerminalIdx, nonTerminals) + + +(* Some examples for testing *) + +(* + +let example1 = + let e = "E" + let t = "Terminal" + let plus = "+" + let mul = "*" + let f = "F" + let lparen = "(" + let rparen = ")" + let id = "id" + + let terminals = [plus; mul; lparen; rparen; id] + let nonTerminals = [e; t; f] + + let p2 = e, (NonAssoc, ExplicitPrec 1), [NonTerminal e; Terminal plus; NonTerminal t], None + let p3 = e, (NonAssoc, ExplicitPrec 2), [NonTerminal t], None in + let p4 = t, (NonAssoc, ExplicitPrec 3), [NonTerminal t; Terminal mul; NonTerminal f], None + let p5 = t, (NonAssoc, ExplicitPrec 4), [NonTerminal f], None + let p6 = f, (NonAssoc, ExplicitPrec 5), [Terminal lparen; NonTerminal e; Terminal rparen], None + let p7 = f, (NonAssoc, ExplicitPrec 6), [Terminal id], None + + let prods = [p2;p3;p4;p5;p6;p7] + Spec(terminals,nonTerminals,prods, [e]) + +let example2 = + let prods = [ "S", (NonAssoc, ExplicitPrec 1), [NonTerminal "C";NonTerminal "C"], None; + "C", (NonAssoc, ExplicitPrec 2), [Terminal "c";NonTerminal "C"], None ; + "C", (NonAssoc, ExplicitPrec 3), [Terminal "d"] , None ]in + Spec(["c";"d"],["S";"C"],prods, ["S"]) + +let example3 = + let terminals = ["+"; "*"; "("; ")"; "id"] + let nonTerminals = ["E"; "Terminal"; "E'"; "F"; "Terminal'"] + let prods = [ "E", (NonAssoc, ExplicitPrec 1), [ NonTerminal "Terminal"; NonTerminal "E'" ], None; + "E'", (NonAssoc, ExplicitPrec 2), [ Terminal "+"; NonTerminal "Terminal"; NonTerminal "E'"], None; + "E'", (NonAssoc, ExplicitPrec 3), [ ], None; + "Terminal", (NonAssoc, ExplicitPrec 4), [ NonTerminal "F"; NonTerminal "Terminal'" ], None; + "Terminal'", (NonAssoc, ExplicitPrec 5), [ Terminal "*"; NonTerminal "F"; NonTerminal "Terminal'"], None; + "Terminal'", (NonAssoc, ExplicitPrec 6), [ ], None; + "F", (NonAssoc, ExplicitPrec 7), [ Terminal "("; NonTerminal "E"; Terminal ")"], None; + "F", (NonAssoc, ExplicitPrec 8), [ Terminal "id"], None ] + Spec(terminals,nonTerminals,prods, ["E"]) + +let example4 = + let terminals = ["+"; "*"; "("; ")"; "id"] + let nonTerminals = ["E"] + let prods = [ "E", (NonAssoc, ExplicitPrec 1), [ NonTerminal "E"; Terminal "+"; NonTerminal "E" ], None; + "E", (NonAssoc, ExplicitPrec 2), [ NonTerminal "E"; Terminal "*"; NonTerminal "E" ], None; + "E", (NonAssoc, ExplicitPrec 3), [ Terminal "("; NonTerminal "E"; Terminal ")"], None; + "E", (NonAssoc, ExplicitPrec 8), [ Terminal "id"], None ] + Spec(terminals,nonTerminals,prods, ["E"]) + +let example5 = + let terminals = ["+"; "*"; "("; ")"; "id"] + let nonTerminals = ["E"] + let prods = [ "E", (NonAssoc, ExplicitPrec 1), [ NonTerminal "E"; Terminal "+"; NonTerminal "E" ], None; + "E", (NonAssoc, ExplicitPrec 2), [ NonTerminal "E"; Terminal "*"; NonTerminal "E" ], None; + "E", (NonAssoc, ExplicitPrec 3), [ Terminal "("; NonTerminal "E"; Terminal ")"], None; + "E", (NonAssoc, ExplicitPrec 8), [ Terminal "id"], None ] + Spec(terminals,nonTerminals,prods, ["E"]) + +let example6 = + let terminals = ["+"; "*"; "("; ")"; "id"; "-"] + let nonTerminals = ["E"] + let prods = [ "E", (RightAssoc, ExplicitPrec 1), [ NonTerminal "E"; Terminal "-"; NonTerminal "E" ], None; + "E", (LeftAssoc, ExplicitPrec 1), [ NonTerminal "E"; Terminal "+"; NonTerminal "E" ], None; + "E", (LeftAssoc, ExplicitPrec 2), [ NonTerminal "E"; Terminal "*"; NonTerminal "E" ], None; + "E", (NonAssoc, ExplicitPrec 3), [ Terminal "("; NonTerminal "E"; Terminal ")"], None; + "E", (NonAssoc, ExplicitPrec 8), [ Terminal "id"], None ] + Spec(terminals,nonTerminals,prods, ["E"]) + + +let example7 = + let prods = [ "S", (NonAssoc, ExplicitPrec 1), [NonTerminal "L";Terminal "="; NonTerminal "R"], None; + "S", (NonAssoc, ExplicitPrec 2), [NonTerminal "R"], None ; + "L", (NonAssoc, ExplicitPrec 3), [Terminal "*"; NonTerminal "R"], None; + "L", (NonAssoc, ExplicitPrec 3), [Terminal "id"], None; + "R", (NonAssoc, ExplicitPrec 3), [NonTerminal "L"], None; ] + Spec(["*";"=";"id"],["S";"L";"R"],prods, ["S"]) + + + +let test ex = CompilerLalrParserSpec stdout ex + +(* let _ = test example2*) +(* let _ = exit 1*) +(* let _ = test example3 +let _ = test example1 +let _ = test example4 +let _ = test example5 +let _ = test example6 *) +*) diff --git a/src/buildtools/fsyacc/fsyacclex.fs b/src/buildtools/fsyacc/fsyacclex.fs new file mode 100644 index 0000000000..a035f6fe01 --- /dev/null +++ b/src/buildtools/fsyacc/fsyacclex.fs @@ -0,0 +1,644 @@ +# 1 "fsyacclex.fsl" + +(* (c) Microsoft Corporation 2005-2008. *) + +module internal FsLexYacc.FsYacc.Lexer + +open FsLexYacc.FsYacc.AST +open FsLexYacc.FsYacc.Parser +open System.Text +open Internal.Utilities.Text.Lexing + +let lexeme (lexbuf : LexBuffer) = new System.String(lexbuf.Lexeme) +let newline (lexbuf:LexBuffer<_>) = lexbuf.EndPos <- lexbuf.EndPos.NextLine + +let unexpected_char lexbuf = + failwith ("Unexpected character '"+(lexeme lexbuf)+"'") + +let typeDepth = ref 0 +let startPos = ref Position.Empty +let mutable str_buf = new System.Text.StringBuilder() + +let appendBuf (str:string) = str_buf.Append str |> ignore +let clearBuf () = str_buf <- new System.Text.StringBuilder() + + +# 26 "fsyacclex.fs" +let trans : uint16[] array = + [| + (* State 0 *) + [| 6us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 2us; 6us; 6us; 3us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 7us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 4us; 6us; 6us; 6us; 6us; 1us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 6us; 5us; |]; + (* State 1 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 11us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 2 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 3 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 10us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 4 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 9us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 5 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 6 *) + [| 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 65535us; 8us; 8us; 65535us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 65535us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 65535us; 8us; 8us; 8us; 8us; 65535us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 65535us; |]; + (* State 7 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 8 *) + [| 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 65535us; 8us; 8us; 65535us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 65535us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 65535us; 8us; 8us; 8us; 8us; 65535us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 8us; 65535us; |]; + (* State 9 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 10 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 11 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 12 *) + [| 19us; 19us; 19us; 19us; 19us; 19us; 19us; 19us; 19us; 17us; 15us; 19us; 19us; 16us; 19us; 19us; 19us; 19us; 19us; 19us; 19us; 19us; 19us; 19us; 19us; 19us; 19us; 19us; 19us; 19us; 19us; 19us; 17us; 19us; 14us; 19us; 19us; 19us; 19us; 19us; 19us; 19us; 19us; 19us; 19us; 19us; 19us; 19us; 17us; 17us; 17us; 17us; 17us; 17us; 17us; 17us; 17us; 17us; 19us; 19us; 19us; 19us; 19us; 19us; 19us; 17us; 17us; 17us; 17us; 17us; 17us; 17us; 17us; 17us; 17us; 17us; 17us; 17us; 17us; 17us; 17us; 17us; 17us; 17us; 17us; 17us; 17us; 17us; 17us; 17us; 17us; 19us; 13us; 19us; 19us; 19us; 19us; 17us; 17us; 17us; 17us; 17us; 17us; 17us; 17us; 17us; 17us; 17us; 17us; 17us; 17us; 17us; 17us; 17us; 17us; 17us; 17us; 17us; 17us; 17us; 17us; 17us; 17us; 19us; 19us; 19us; 19us; 19us; 19us; 19us; 19us; 19us; 19us; 19us; 19us; 19us; 19us; 19us; 19us; 19us; 19us; 19us; 19us; 19us; 19us; 19us; 19us; 19us; 19us; 19us; 19us; 19us; 19us; 19us; 19us; 19us; 19us; 19us; 18us; |]; + (* State 13 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 22us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 22us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 14 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 15 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 16 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 21us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 17 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 20us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 20us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 20us; 20us; 20us; 20us; 20us; 20us; 20us; 20us; 20us; 20us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 20us; 20us; 20us; 20us; 20us; 20us; 20us; 20us; 20us; 20us; 20us; 20us; 20us; 20us; 20us; 20us; 20us; 20us; 20us; 20us; 20us; 20us; 20us; 20us; 20us; 20us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 20us; 20us; 20us; 20us; 20us; 20us; 20us; 20us; 20us; 20us; 20us; 20us; 20us; 20us; 20us; 20us; 20us; 20us; 20us; 20us; 20us; 20us; 20us; 20us; 20us; 20us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 18 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 19 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 20 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 20us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 20us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 20us; 20us; 20us; 20us; 20us; 20us; 20us; 20us; 20us; 20us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 20us; 20us; 20us; 20us; 20us; 20us; 20us; 20us; 20us; 20us; 20us; 20us; 20us; 20us; 20us; 20us; 20us; 20us; 20us; 20us; 20us; 20us; 20us; 20us; 20us; 20us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 20us; 20us; 20us; 20us; 20us; 20us; 20us; 20us; 20us; 20us; 20us; 20us; 20us; 20us; 20us; 20us; 20us; 20us; 20us; 20us; 20us; 20us; 20us; 20us; 20us; 20us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 21 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 22 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 23 *) + [| 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 30us; 26us; 33us; 33us; 27us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 30us; 33us; 29us; 33us; 33us; 33us; 33us; 28us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 31us; 30us; 30us; 30us; 30us; 30us; 30us; 30us; 30us; 30us; 30us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 30us; 30us; 30us; 30us; 30us; 30us; 30us; 30us; 30us; 30us; 30us; 30us; 30us; 30us; 30us; 30us; 30us; 30us; 30us; 30us; 30us; 30us; 30us; 30us; 30us; 30us; 33us; 33us; 33us; 33us; 33us; 33us; 30us; 30us; 30us; 30us; 30us; 30us; 30us; 30us; 30us; 30us; 30us; 30us; 30us; 30us; 30us; 30us; 30us; 30us; 30us; 30us; 30us; 30us; 30us; 30us; 30us; 30us; 25us; 33us; 24us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 33us; 32us; |]; + (* State 24 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 25 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 26 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 27 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 41us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 28 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 37us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 38us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 29 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 30 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 36us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 36us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 36us; 36us; 36us; 36us; 36us; 36us; 36us; 36us; 36us; 36us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 36us; 36us; 36us; 36us; 36us; 36us; 36us; 36us; 36us; 36us; 36us; 36us; 36us; 36us; 36us; 36us; 36us; 36us; 36us; 36us; 36us; 36us; 36us; 36us; 36us; 36us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 36us; 36us; 36us; 36us; 36us; 36us; 36us; 36us; 36us; 36us; 36us; 36us; 36us; 36us; 36us; 36us; 36us; 36us; 36us; 36us; 36us; 36us; 36us; 36us; 36us; 36us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 31 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 34us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 32 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 33 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 34 *) + [| 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 65535us; 35us; 35us; 65535us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 65535us; |]; + (* State 35 *) + [| 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 65535us; 35us; 35us; 65535us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 35us; 65535us; |]; + (* State 36 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 36us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 36us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 36us; 36us; 36us; 36us; 36us; 36us; 36us; 36us; 36us; 36us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 36us; 36us; 36us; 36us; 36us; 36us; 36us; 36us; 36us; 36us; 36us; 36us; 36us; 36us; 36us; 36us; 36us; 36us; 36us; 36us; 36us; 36us; 36us; 36us; 36us; 36us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 36us; 36us; 36us; 36us; 36us; 36us; 36us; 36us; 36us; 36us; 36us; 36us; 36us; 36us; 36us; 36us; 36us; 36us; 36us; 36us; 36us; 36us; 36us; 36us; 36us; 36us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 37 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 40us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 38 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 39us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 39 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 40us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 40 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 41 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 42 *) + [| 51us; 51us; 51us; 51us; 51us; 51us; 51us; 51us; 51us; 46us; 44us; 51us; 51us; 45us; 51us; 51us; 51us; 51us; 51us; 51us; 51us; 51us; 51us; 51us; 51us; 51us; 51us; 51us; 51us; 51us; 51us; 51us; 46us; 51us; 49us; 51us; 51us; 43us; 51us; 48us; 51us; 51us; 51us; 51us; 51us; 51us; 51us; 47us; 46us; 46us; 46us; 46us; 46us; 46us; 46us; 46us; 46us; 46us; 51us; 51us; 51us; 51us; 51us; 51us; 51us; 46us; 46us; 46us; 46us; 46us; 46us; 46us; 46us; 46us; 46us; 46us; 46us; 46us; 46us; 46us; 46us; 46us; 46us; 46us; 46us; 46us; 46us; 46us; 46us; 46us; 46us; 51us; 51us; 51us; 51us; 51us; 51us; 46us; 46us; 46us; 46us; 46us; 46us; 46us; 46us; 46us; 46us; 46us; 46us; 46us; 46us; 46us; 46us; 46us; 46us; 46us; 46us; 46us; 46us; 46us; 46us; 46us; 46us; 51us; 51us; 51us; 51us; 51us; 51us; 51us; 51us; 51us; 51us; 51us; 51us; 51us; 51us; 51us; 51us; 51us; 51us; 51us; 51us; 51us; 51us; 51us; 51us; 51us; 51us; 51us; 51us; 51us; 51us; 51us; 51us; 51us; 51us; 51us; 50us; |]; + (* State 43 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 60us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 44 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 45 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 59us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 46 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 58us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 58us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 58us; 58us; 58us; 58us; 58us; 58us; 58us; 58us; 58us; 58us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 58us; 58us; 58us; 58us; 58us; 58us; 58us; 58us; 58us; 58us; 58us; 58us; 58us; 58us; 58us; 58us; 58us; 58us; 58us; 58us; 58us; 58us; 58us; 58us; 58us; 58us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 58us; 58us; 58us; 58us; 58us; 58us; 58us; 58us; 58us; 58us; 58us; 58us; 58us; 58us; 58us; 58us; 58us; 58us; 58us; 58us; 58us; 58us; 58us; 58us; 58us; 58us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 47 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 56us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 48 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 52us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 53us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 49 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 50 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 51 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 52 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 55us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 53 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 54us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 54 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 55us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 55 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 56 *) + [| 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 65535us; 57us; 57us; 65535us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 65535us; |]; + (* State 57 *) + [| 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 65535us; 57us; 57us; 65535us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 57us; 65535us; |]; + (* State 58 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 58us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 58us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 58us; 58us; 58us; 58us; 58us; 58us; 58us; 58us; 58us; 58us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 58us; 58us; 58us; 58us; 58us; 58us; 58us; 58us; 58us; 58us; 58us; 58us; 58us; 58us; 58us; 58us; 58us; 58us; 58us; 58us; 58us; 58us; 58us; 58us; 58us; 58us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 58us; 58us; 58us; 58us; 58us; 58us; 58us; 58us; 58us; 58us; 58us; 58us; 58us; 58us; 58us; 58us; 58us; 58us; 58us; 58us; 58us; 58us; 58us; 58us; 58us; 58us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 59 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 60 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 61 *) + [| 64us; 64us; 64us; 64us; 64us; 64us; 64us; 64us; 64us; 64us; 64us; 64us; 64us; 64us; 64us; 64us; 64us; 64us; 64us; 64us; 64us; 64us; 64us; 64us; 64us; 64us; 64us; 64us; 64us; 64us; 64us; 64us; 64us; 64us; 64us; 64us; 64us; 64us; 64us; 64us; 64us; 64us; 64us; 64us; 64us; 64us; 64us; 64us; 64us; 64us; 64us; 64us; 64us; 64us; 64us; 64us; 64us; 64us; 64us; 64us; 62us; 64us; 63us; 64us; 64us; 64us; 64us; 64us; 64us; 64us; 64us; 64us; 64us; 64us; 64us; 64us; 64us; 64us; 64us; 64us; 64us; 64us; 64us; 64us; 64us; 64us; 64us; 64us; 64us; 64us; 64us; 64us; 64us; 64us; 64us; 64us; 64us; 64us; 64us; 64us; 64us; 64us; 64us; 64us; 64us; 64us; 64us; 64us; 64us; 64us; 64us; 64us; 64us; 64us; 64us; 64us; 64us; 64us; 64us; 64us; 64us; 64us; 64us; 64us; 64us; 64us; 64us; 64us; 64us; 64us; 64us; 64us; 64us; 64us; 64us; 64us; 64us; 64us; 64us; 64us; 64us; 64us; 64us; 64us; 64us; 64us; 64us; 64us; 64us; 64us; 64us; 64us; 64us; 64us; 64us; 64us; 64us; 64us; 65535us; |]; + (* State 62 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 63 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 64 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 65 *) + [| 79us; 79us; 79us; 79us; 79us; 79us; 79us; 79us; 79us; 72us; 73us; 79us; 79us; 74us; 79us; 79us; 79us; 79us; 79us; 79us; 79us; 79us; 79us; 79us; 79us; 79us; 79us; 79us; 79us; 79us; 79us; 79us; 72us; 79us; 79us; 79us; 79us; 66us; 79us; 79us; 79us; 79us; 79us; 79us; 79us; 79us; 79us; 77us; 79us; 79us; 79us; 79us; 79us; 79us; 79us; 79us; 79us; 79us; 78us; 70us; 68us; 79us; 69us; 79us; 79us; 75us; 75us; 75us; 75us; 75us; 75us; 75us; 75us; 75us; 75us; 75us; 75us; 75us; 75us; 75us; 75us; 75us; 75us; 75us; 75us; 75us; 75us; 75us; 75us; 75us; 75us; 79us; 79us; 79us; 79us; 79us; 79us; 75us; 75us; 75us; 75us; 67us; 75us; 75us; 75us; 75us; 75us; 75us; 75us; 75us; 75us; 75us; 75us; 75us; 75us; 75us; 75us; 75us; 75us; 75us; 75us; 75us; 75us; 71us; 76us; 79us; 79us; 79us; 79us; 79us; 79us; 79us; 79us; 79us; 79us; 79us; 79us; 79us; 79us; 79us; 79us; 79us; 79us; 79us; 79us; 79us; 79us; 79us; 79us; 79us; 79us; 79us; 79us; 79us; 79us; 79us; 79us; 79us; 80us; |]; + (* State 66 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 92us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 96us; 65535us; 98us; 65535us; 95us; 65535us; 97us; 94us; 93us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 91us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 67 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 84us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 65535us; 65535us; 65535us; 65535us; 84us; 65535us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 87us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 68 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 69 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 70 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 71 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 72 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 86us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 86us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 73 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 74 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 85us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 75 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 84us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 65535us; 65535us; 65535us; 65535us; 84us; 65535us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 76 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 77 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 81us; 65535us; 65535us; 65535us; 65535us; 82us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 78 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 79 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 80 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 81 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 82 *) + [| 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 65535us; 83us; 83us; 65535us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 65535us; |]; + (* State 83 *) + [| 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 65535us; 83us; 83us; 65535us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 83us; 65535us; |]; + (* State 84 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 84us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 65535us; 65535us; 65535us; 65535us; 84us; 65535us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 85 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 86 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 86us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 86us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 87 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 84us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 65535us; 65535us; 65535us; 65535us; 84us; 65535us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 88us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 88 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 84us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 65535us; 65535us; 65535us; 65535us; 84us; 65535us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 89us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 89 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 84us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 65535us; 65535us; 65535us; 65535us; 84us; 65535us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 90us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 90 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 84us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 65535us; 65535us; 65535us; 65535us; 84us; 65535us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 84us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 91 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 92 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 93 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 120us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 121us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 94 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 116us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 95 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 113us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 96 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 110us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 97 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 106us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 98 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 99us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 99 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 100us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 100 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 101us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 101 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 102us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 102 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 103us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 103 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 104us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 104 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 105us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 105 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 106 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 107us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 107 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 108us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 108 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 109us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 109 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 110 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 111us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 111 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 112us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 112 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 113 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 114us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 114 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 115us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 115 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 116 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 117us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 117 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 118us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 118 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 119us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 119 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 120 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 126us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 121 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 122us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 122 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 123us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 123 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 125us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 125us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 124us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 124 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 125 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 125us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 125us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 124us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 126 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 127us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 127 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 128us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 128 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 130us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 130us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 129us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 129 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + (* State 130 *) + [| 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 130us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 130us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 129us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; |]; + |] +let actions : uint16[] = [|65535us; 5us; 1us; 5us; 5us; 3us; 4us; 5us; 4us; 2us; 1us; 0us; 65535us; 5us; 1us; 2us; 5us; 3us; 4us; 5us; 3us; 2us; 0us; 65535us; 0us; 1us; 2us; 8us; 8us; 4us; 5us; 8us; 7us; 8us; 6us; 6us; 5us; 65535us; 65535us; 65535us; 3us; 2us; 65535us; 7us; 1us; 7us; 2us; 7us; 7us; 5us; 6us; 7us; 65535us; 65535us; 65535us; 4us; 3us; 3us; 2us; 1us; 0us; 65535us; 0us; 1us; 2us; 65535us; 22us; 17us; 11us; 12us; 13us; 14us; 15us; 16us; 22us; 17us; 18us; 22us; 21us; 22us; 23us; 19us; 20us; 20us; 17us; 16us; 15us; 17us; 17us; 17us; 10us; 0us; 1us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 65535us; 9us; 65535us; 65535us; 65535us; 8us; 65535us; 65535us; 7us; 65535us; 65535us; 5us; 65535us; 65535us; 65535us; 4us; 65535us; 65535us; 65535us; 65535us; 6us; 65535us; 65535us; 65535us; 3us; 2us; 65535us; |] +let _fslex_tables = Internal.Utilities.Text.Lexing.UnicodeTables.Create(trans,actions) +let rec _fslex_dummy () = _fslex_dummy() +(* Rule token *) +and token (lexbuf : Internal.Utilities.Text.Lexing.LexBuffer<_>) = _fslex_token 65 lexbuf +(* Rule fs_type *) +and fs_type (lexbuf : Internal.Utilities.Text.Lexing.LexBuffer<_>) = _fslex_fs_type 61 lexbuf +(* Rule header *) +and header p buff (lexbuf : Internal.Utilities.Text.Lexing.LexBuffer<_>) = _fslex_header p buff 42 lexbuf +(* Rule code *) +and code p buff (lexbuf : Internal.Utilities.Text.Lexing.LexBuffer<_>) = _fslex_code p buff 23 lexbuf +(* Rule codestring *) +and codestring buff (lexbuf : Internal.Utilities.Text.Lexing.LexBuffer<_>) = _fslex_codestring buff 12 lexbuf +(* Rule comment *) +and comment (lexbuf : Internal.Utilities.Text.Lexing.LexBuffer<_>) = _fslex_comment 0 lexbuf +(* Rule token *) +and _fslex_token _fslex_state lexbuf = + match _fslex_tables.Interpret(_fslex_state,lexbuf) with + | 0 -> ( +# 35 "fsyacclex.fsl" + let p = lexbuf.StartPos in header p (new StringBuilder 100) lexbuf +# 313 "fsyacclex.fs" + ) + | 1 -> ( +# 36 "fsyacclex.fsl" + PERCENT_PERCENT +# 318 "fsyacclex.fs" + ) + | 2 -> ( +# 37 "fsyacclex.fsl" + typeDepth := 1; startPos := lexbuf.StartPos; clearBuf(); TOKEN (fs_type lexbuf) +# 323 "fsyacclex.fs" + ) + | 3 -> ( +# 38 "fsyacclex.fsl" + TOKEN (None) +# 328 "fsyacclex.fs" + ) + | 4 -> ( +# 39 "fsyacclex.fsl" + START +# 333 "fsyacclex.fs" + ) + | 5 -> ( +# 40 "fsyacclex.fsl" + PREC +# 338 "fsyacclex.fs" + ) + | 6 -> ( +# 41 "fsyacclex.fsl" + typeDepth := 1; startPos := lexbuf.StartPos; clearBuf(); TYPE (match fs_type lexbuf with Some x -> x | None -> failwith "gettype") +# 343 "fsyacclex.fs" + ) + | 7 -> ( +# 42 "fsyacclex.fsl" + LEFT +# 348 "fsyacclex.fs" + ) + | 8 -> ( +# 43 "fsyacclex.fsl" + RIGHT +# 353 "fsyacclex.fs" + ) + | 9 -> ( +# 44 "fsyacclex.fsl" + NONASSOC +# 358 "fsyacclex.fs" + ) + | 10 -> ( +# 45 "fsyacclex.fsl" + ERROR +# 363 "fsyacclex.fs" + ) + | 11 -> ( +# 46 "fsyacclex.fsl" + LESS +# 368 "fsyacclex.fs" + ) + | 12 -> ( +# 47 "fsyacclex.fsl" + GREATER +# 373 "fsyacclex.fs" + ) + | 13 -> ( +# 48 "fsyacclex.fsl" + SEMI +# 378 "fsyacclex.fs" + ) + | 14 -> ( +# 49 "fsyacclex.fsl" + let p = lexbuf.StartPos in + let buff = (new StringBuilder 100) in + // adjust the first line to get even indentation for all lines w.r.t. the left hand margin + buff.Append (String.replicate (lexbuf.StartPos.Column+1) " ") |> ignore; + code p buff lexbuf +# 387 "fsyacclex.fs" + ) + | 15 -> ( +# 54 "fsyacclex.fsl" + token lexbuf +# 392 "fsyacclex.fs" + ) + | 16 -> ( +# 55 "fsyacclex.fsl" + newline lexbuf; token lexbuf +# 397 "fsyacclex.fs" + ) + | 17 -> ( +# 56 "fsyacclex.fsl" + IDENT (lexeme lexbuf) +# 402 "fsyacclex.fs" + ) + | 18 -> ( +# 57 "fsyacclex.fsl" + BAR +# 407 "fsyacclex.fs" + ) + | 19 -> ( +# 58 "fsyacclex.fsl" + ignore(comment lexbuf); token lexbuf +# 412 "fsyacclex.fs" + ) + | 20 -> ( +# 59 "fsyacclex.fsl" + token lexbuf +# 417 "fsyacclex.fs" + ) + | 21 -> ( +# 60 "fsyacclex.fsl" + COLON +# 422 "fsyacclex.fs" + ) + | 22 -> ( +# 61 "fsyacclex.fsl" + unexpected_char lexbuf +# 427 "fsyacclex.fs" + ) + | 23 -> ( +# 62 "fsyacclex.fsl" + EOF +# 432 "fsyacclex.fs" + ) + | _ -> failwith "token" +(* Rule fs_type *) +and _fslex_fs_type _fslex_state lexbuf = + match _fslex_tables.Interpret(_fslex_state,lexbuf) with + | 0 -> ( +# 65 "fsyacclex.fsl" + incr typeDepth; appendBuf(lexeme lexbuf); fs_type lexbuf +# 441 "fsyacclex.fs" + ) + | 1 -> ( +# 67 "fsyacclex.fsl" + decr typeDepth; + if !typeDepth = 0 + then Some(string str_buf) + else appendBuf(lexeme lexbuf); fs_type lexbuf +# 449 "fsyacclex.fs" + ) + | 2 -> ( +# 71 "fsyacclex.fsl" + appendBuf(lexeme lexbuf); fs_type lexbuf +# 454 "fsyacclex.fs" + ) + | _ -> failwith "fs_type" +(* Rule header *) +and _fslex_header p buff _fslex_state lexbuf = + match _fslex_tables.Interpret(_fslex_state,lexbuf) with + | 0 -> ( +# 74 "fsyacclex.fsl" + HEADER (buff.ToString(), p) +# 463 "fsyacclex.fs" + ) + | 1 -> ( +# 75 "fsyacclex.fsl" + newline lexbuf; + ignore <| buff.Append System.Environment.NewLine; + header p buff lexbuf +# 470 "fsyacclex.fs" + ) + | 2 -> ( +# 79 "fsyacclex.fsl" + ignore <| buff.Append (lexeme lexbuf); + header p buff lexbuf +# 476 "fsyacclex.fs" + ) + | 3 -> ( +# 82 "fsyacclex.fsl" + ignore <| buff.Append (lexeme lexbuf); + header p buff lexbuf +# 482 "fsyacclex.fs" + ) + | 4 -> ( +# 85 "fsyacclex.fsl" + ignore <| buff.Append (lexeme lexbuf); + header p buff lexbuf +# 488 "fsyacclex.fs" + ) + | 5 -> ( +# 88 "fsyacclex.fsl" + ignore <| buff.Append (lexeme lexbuf); + ignore(codestring buff lexbuf); + header p buff lexbuf +# 495 "fsyacclex.fs" + ) + | 6 -> ( +# 91 "fsyacclex.fsl" + EOF +# 500 "fsyacclex.fs" + ) + | 7 -> ( +# 92 "fsyacclex.fsl" + ignore <| buff.Append(lexeme lexbuf).[0]; + header p buff lexbuf +# 506 "fsyacclex.fs" + ) + | _ -> failwith "header" +(* Rule code *) +and _fslex_code p buff _fslex_state lexbuf = + match _fslex_tables.Interpret(_fslex_state,lexbuf) with + | 0 -> ( +# 95 "fsyacclex.fsl" + CODE (buff.ToString(), p) +# 515 "fsyacclex.fs" + ) + | 1 -> ( +# 96 "fsyacclex.fsl" + ignore <| buff.Append (lexeme lexbuf); + ignore(code p buff lexbuf); + ignore <| buff.Append "}"; + code p buff lexbuf +# 523 "fsyacclex.fs" + ) + | 2 -> ( +# 100 "fsyacclex.fsl" + newline lexbuf; + ignore <| buff.Append System.Environment.NewLine; + code p buff lexbuf +# 530 "fsyacclex.fs" + ) + | 3 -> ( +# 104 "fsyacclex.fsl" + ignore <| buff.Append (lexeme lexbuf); + code p buff lexbuf +# 536 "fsyacclex.fs" + ) + | 4 -> ( +# 106 "fsyacclex.fsl" + ignore <| buff.Append (lexeme lexbuf); + ignore(codestring buff lexbuf); + code p buff lexbuf +# 543 "fsyacclex.fs" + ) + | 5 -> ( +# 110 "fsyacclex.fsl" + ignore <| buff.Append (lexeme lexbuf); + code p buff lexbuf +# 549 "fsyacclex.fs" + ) + | 6 -> ( +# 113 "fsyacclex.fsl" + ignore <| buff.Append (lexeme lexbuf); + code p buff lexbuf +# 555 "fsyacclex.fs" + ) + | 7 -> ( +# 115 "fsyacclex.fsl" + EOF +# 560 "fsyacclex.fs" + ) + | 8 -> ( +# 116 "fsyacclex.fsl" + ignore <| buff.Append(lexeme lexbuf).[0]; + code p buff lexbuf +# 566 "fsyacclex.fs" + ) + | _ -> failwith "code" +(* Rule codestring *) +and _fslex_codestring buff _fslex_state lexbuf = + match _fslex_tables.Interpret(_fslex_state,lexbuf) with + | 0 -> ( +# 122 "fsyacclex.fsl" + ignore <| buff.Append (lexeme lexbuf); + codestring buff lexbuf +# 576 "fsyacclex.fs" + ) + | 1 -> ( +# 124 "fsyacclex.fsl" + ignore <| buff.Append (lexeme lexbuf); + buff.ToString() +# 582 "fsyacclex.fs" + ) + | 2 -> ( +# 126 "fsyacclex.fsl" + newline lexbuf; + ignore <| buff.Append System.Environment.NewLine; + codestring buff lexbuf +# 589 "fsyacclex.fs" + ) + | 3 -> ( +# 130 "fsyacclex.fsl" + ignore <| buff.Append (lexeme lexbuf); + codestring buff lexbuf +# 595 "fsyacclex.fs" + ) + | 4 -> ( +# 132 "fsyacclex.fsl" + failwith "unterminated string in code" +# 600 "fsyacclex.fs" + ) + | 5 -> ( +# 133 "fsyacclex.fsl" + ignore <| buff.Append(lexeme lexbuf).[0]; + codestring buff lexbuf +# 606 "fsyacclex.fs" + ) + | _ -> failwith "codestring" +(* Rule comment *) +and _fslex_comment _fslex_state lexbuf = + match _fslex_tables.Interpret(_fslex_state,lexbuf) with + | 0 -> ( +# 138 "fsyacclex.fsl" + ignore(comment lexbuf); comment lexbuf +# 615 "fsyacclex.fs" + ) + | 1 -> ( +# 139 "fsyacclex.fsl" + newline lexbuf; comment lexbuf +# 620 "fsyacclex.fs" + ) + | 2 -> ( +# 140 "fsyacclex.fsl" + () +# 625 "fsyacclex.fs" + ) + | 3 -> ( +# 141 "fsyacclex.fsl" + failwith "end of file in comment" +# 630 "fsyacclex.fs" + ) + | 4 -> ( +# 142 "fsyacclex.fsl" + comment lexbuf +# 635 "fsyacclex.fs" + ) + | 5 -> ( +# 143 "fsyacclex.fsl" + comment lexbuf +# 640 "fsyacclex.fs" + ) + | _ -> failwith "comment" + +# 3000000 "fsyacclex.fs" diff --git a/src/buildtools/fsyacc/fsyaccpars.fs b/src/buildtools/fsyacc/fsyaccpars.fs new file mode 100644 index 0000000000..c6d614f269 --- /dev/null +++ b/src/buildtools/fsyacc/fsyaccpars.fs @@ -0,0 +1,562 @@ +// Implementation file for parser generated by fsyacc +module internal FsLexYacc.FsYacc.Parser +#nowarn "64";; // turn off warnings that type variables used in production annotations are instantiated to concrete type +open Internal.Utilities.Text.Lexing +open Internal.Utilities.Text.Parsing.ParseHelpers +# 1 "fsyaccpars.fsy" + +(* (c) Microsoft Corporation 2005-2008. *) + +// FsLexYacc.FsYacc.Parser + +open FsLexYacc.FsYacc +open FsLexYacc.FsYacc.AST + +#nowarn "62" // This construct is for ML compatibility + + +# 18 "fsyaccpars.fs" +// This type is the type of tokens accepted by the parser +type token = + | TOKEN of (string option) + | TYPE of (string) + | BAR + | PERCENT_PERCENT + | START + | LEFT + | RIGHT + | NONASSOC + | LESS + | GREATER + | COLON + | PREC + | SEMI + | EOF + | ERROR + | HEADER of (AST.Code) + | CODE of (AST.Code) + | IDENT of (string) +// This type is used to give symbolic names to token indexes, useful for error messages +type tokenId = + | TOKEN_TOKEN + | TOKEN_TYPE + | TOKEN_BAR + | TOKEN_PERCENT_PERCENT + | TOKEN_START + | TOKEN_LEFT + | TOKEN_RIGHT + | TOKEN_NONASSOC + | TOKEN_LESS + | TOKEN_GREATER + | TOKEN_COLON + | TOKEN_PREC + | TOKEN_SEMI + | TOKEN_EOF + | TOKEN_ERROR + | TOKEN_HEADER + | TOKEN_CODE + | TOKEN_IDENT + | TOKEN_end_of_input + | TOKEN_error +// This type is used to give symbolic names to token indexes, useful for error messages +type nonTerminalId = + | NONTERM__startspec + | NONTERM_spec + | NONTERM_headeropt + | NONTERM_decls + | NONTERM_decl + | NONTERM_idents + | NONTERM_rules + | NONTERM_rule + | NONTERM_optbar + | NONTERM_optsemi + | NONTERM_clauses + | NONTERM_clause + | NONTERM_syms + | NONTERM_optprec + +// This function maps tokens to integer indexes +let tagOfToken (t:token) = + match t with + | TOKEN _ -> 0 + | TYPE _ -> 1 + | BAR -> 2 + | PERCENT_PERCENT -> 3 + | START -> 4 + | LEFT -> 5 + | RIGHT -> 6 + | NONASSOC -> 7 + | LESS -> 8 + | GREATER -> 9 + | COLON -> 10 + | PREC -> 11 + | SEMI -> 12 + | EOF -> 13 + | ERROR -> 14 + | HEADER _ -> 15 + | CODE _ -> 16 + | IDENT _ -> 17 + +// This function maps integer indexes to symbolic token ids +let tokenTagToTokenId (tokenIdx:int) = + match tokenIdx with + | 0 -> TOKEN_TOKEN + | 1 -> TOKEN_TYPE + | 2 -> TOKEN_BAR + | 3 -> TOKEN_PERCENT_PERCENT + | 4 -> TOKEN_START + | 5 -> TOKEN_LEFT + | 6 -> TOKEN_RIGHT + | 7 -> TOKEN_NONASSOC + | 8 -> TOKEN_LESS + | 9 -> TOKEN_GREATER + | 10 -> TOKEN_COLON + | 11 -> TOKEN_PREC + | 12 -> TOKEN_SEMI + | 13 -> TOKEN_EOF + | 14 -> TOKEN_ERROR + | 15 -> TOKEN_HEADER + | 16 -> TOKEN_CODE + | 17 -> TOKEN_IDENT + | 20 -> TOKEN_end_of_input + | 18 -> TOKEN_error + | _ -> failwith "tokenTagToTokenId: bad token" + +/// This function maps production indexes returned in syntax errors to strings representing the non terminal that would be produced by that production +let prodIdxToNonTerminal (prodIdx:int) = + match prodIdx with + | 0 -> NONTERM__startspec + | 1 -> NONTERM_spec + | 2 -> NONTERM_headeropt + | 3 -> NONTERM_headeropt + | 4 -> NONTERM_decls + | 5 -> NONTERM_decls + | 6 -> NONTERM_decl + | 7 -> NONTERM_decl + | 8 -> NONTERM_decl + | 9 -> NONTERM_decl + | 10 -> NONTERM_decl + | 11 -> NONTERM_decl + | 12 -> NONTERM_idents + | 13 -> NONTERM_idents + | 14 -> NONTERM_rules + | 15 -> NONTERM_rules + | 16 -> NONTERM_rule + | 17 -> NONTERM_optbar + | 18 -> NONTERM_optbar + | 19 -> NONTERM_optsemi + | 20 -> NONTERM_optsemi + | 21 -> NONTERM_clauses + | 22 -> NONTERM_clauses + | 23 -> NONTERM_clause + | 24 -> NONTERM_syms + | 25 -> NONTERM_syms + | 26 -> NONTERM_syms + | 27 -> NONTERM_optprec + | 28 -> NONTERM_optprec + | _ -> failwith "prodIdxToNonTerminal: bad production index" + +let _fsyacc_endOfInputTag = 20 +let _fsyacc_tagOfErrorTerminal = 18 + +// This function gets the name of a token as a string +let token_to_string (t:token) = + match t with + | TOKEN _ -> "TOKEN" + | TYPE _ -> "TYPE" + | BAR -> "BAR" + | PERCENT_PERCENT -> "PERCENT_PERCENT" + | START -> "START" + | LEFT -> "LEFT" + | RIGHT -> "RIGHT" + | NONASSOC -> "NONASSOC" + | LESS -> "LESS" + | GREATER -> "GREATER" + | COLON -> "COLON" + | PREC -> "PREC" + | SEMI -> "SEMI" + | EOF -> "EOF" + | ERROR -> "ERROR" + | HEADER _ -> "HEADER" + | CODE _ -> "CODE" + | IDENT _ -> "IDENT" + +// This function gets the data carried by a token as an object +let _fsyacc_dataOfToken (t:token) = + match t with + | TOKEN _fsyacc_x -> Microsoft.FSharp.Core.Operators.box _fsyacc_x + | TYPE _fsyacc_x -> Microsoft.FSharp.Core.Operators.box _fsyacc_x + | BAR -> (null : System.Object) + | PERCENT_PERCENT -> (null : System.Object) + | START -> (null : System.Object) + | LEFT -> (null : System.Object) + | RIGHT -> (null : System.Object) + | NONASSOC -> (null : System.Object) + | LESS -> (null : System.Object) + | GREATER -> (null : System.Object) + | COLON -> (null : System.Object) + | PREC -> (null : System.Object) + | SEMI -> (null : System.Object) + | EOF -> (null : System.Object) + | ERROR -> (null : System.Object) + | HEADER _fsyacc_x -> Microsoft.FSharp.Core.Operators.box _fsyacc_x + | CODE _fsyacc_x -> Microsoft.FSharp.Core.Operators.box _fsyacc_x + | IDENT _fsyacc_x -> Microsoft.FSharp.Core.Operators.box _fsyacc_x +let _fsyacc_gotos = [| 0us; 65535us; 1us; 65535us; 0us; 1us; 1us; 65535us; 0us; 2us; 2us; 65535us; 2us; 3us; 7us; 8us; 2us; 65535us; 2us; 7us; 7us; 7us; 7us; 65535us; 9us; 10us; 11us; 12us; 13us; 14us; 15us; 16us; 17us; 18us; 19us; 20us; 21us; 22us; 2us; 65535us; 4us; 5us; 23us; 24us; 2us; 65535us; 4us; 23us; 23us; 23us; 1us; 65535us; 26us; 27us; 1us; 65535us; 28us; 29us; 2us; 65535us; 27us; 28us; 33us; 34us; 2us; 65535us; 27us; 32us; 33us; 32us; 4us; 65535us; 27us; 35us; 33us; 35us; 38us; 39us; 40us; 41us; 1us; 65535us; 35us; 36us; |] +let _fsyacc_sparseGotoTableRowOffsets = [|0us; 1us; 3us; 5us; 8us; 11us; 19us; 22us; 25us; 27us; 29us; 32us; 35us; 40us; |] +let _fsyacc_stateToProdIdxsTableElements = [| 1us; 0us; 1us; 0us; 1us; 1us; 1us; 1us; 1us; 1us; 1us; 1us; 1us; 2us; 1us; 5us; 1us; 5us; 1us; 6us; 1us; 6us; 1us; 7us; 1us; 7us; 1us; 8us; 1us; 8us; 1us; 9us; 1us; 9us; 1us; 10us; 1us; 10us; 1us; 11us; 1us; 11us; 1us; 12us; 1us; 12us; 2us; 14us; 15us; 1us; 14us; 1us; 16us; 1us; 16us; 1us; 16us; 1us; 16us; 1us; 16us; 1us; 18us; 1us; 20us; 2us; 21us; 22us; 1us; 21us; 1us; 21us; 1us; 23us; 1us; 23us; 1us; 23us; 1us; 24us; 1us; 24us; 1us; 25us; 1us; 25us; 1us; 28us; 1us; 28us; |] +let _fsyacc_stateToProdIdxsTableRowOffsets = [|0us; 2us; 4us; 6us; 8us; 10us; 12us; 14us; 16us; 18us; 20us; 22us; 24us; 26us; 28us; 30us; 32us; 34us; 36us; 38us; 40us; 42us; 44us; 46us; 49us; 51us; 53us; 55us; 57us; 59us; 61us; 63us; 65us; 68us; 70us; 72us; 74us; 76us; 78us; 80us; 82us; 84us; 86us; 88us; |] +let _fsyacc_action_rows = 44 +let _fsyacc_actionTableElements = [|1us; 16387us; 15us; 6us; 0us; 49152us; 6us; 16388us; 0us; 9us; 1us; 11us; 4us; 13us; 5us; 15us; 6us; 17us; 7us; 19us; 1us; 32768us; 3us; 4us; 1us; 32768us; 17us; 25us; 0us; 16385us; 0us; 16386us; 6us; 16388us; 0us; 9us; 1us; 11us; 4us; 13us; 5us; 15us; 6us; 17us; 7us; 19us; 0us; 16389us; 1us; 16397us; 17us; 21us; 0us; 16390us; 1us; 16397us; 17us; 21us; 0us; 16391us; 1us; 16397us; 17us; 21us; 0us; 16392us; 1us; 16397us; 17us; 21us; 0us; 16393us; 1us; 16397us; 17us; 21us; 0us; 16394us; 1us; 16397us; 17us; 21us; 0us; 16395us; 1us; 16397us; 17us; 21us; 0us; 16396us; 1us; 16399us; 17us; 25us; 0us; 16398us; 1us; 32768us; 10us; 26us; 1us; 16401us; 2us; 30us; 2us; 16410us; 14us; 40us; 17us; 38us; 1us; 16403us; 12us; 31us; 0us; 16400us; 0us; 16402us; 0us; 16404us; 1us; 16406us; 2us; 33us; 2us; 16410us; 14us; 40us; 17us; 38us; 0us; 16405us; 1us; 16411us; 11us; 42us; 1us; 32768us; 16us; 37us; 0us; 16407us; 2us; 16410us; 14us; 40us; 17us; 38us; 0us; 16408us; 2us; 16410us; 14us; 40us; 17us; 38us; 0us; 16409us; 1us; 32768us; 17us; 43us; 0us; 16412us; |] +let _fsyacc_actionTableRowOffsets = [|0us; 2us; 3us; 10us; 12us; 14us; 15us; 16us; 23us; 24us; 26us; 27us; 29us; 30us; 32us; 33us; 35us; 36us; 38us; 39us; 41us; 42us; 44us; 45us; 47us; 48us; 50us; 52us; 55us; 57us; 58us; 59us; 60us; 62us; 65us; 66us; 68us; 70us; 71us; 74us; 75us; 78us; 79us; 81us; |] +let _fsyacc_reductionSymbolCounts = [|1us; 4us; 1us; 0us; 0us; 2us; 2us; 2us; 2us; 2us; 2us; 2us; 2us; 0us; 2us; 1us; 5us; 0us; 1us; 0us; 1us; 3us; 1us; 3us; 2us; 2us; 0us; 0us; 2us; |] +let _fsyacc_productionToNonTerminalTable = [|0us; 1us; 2us; 2us; 3us; 3us; 4us; 4us; 4us; 4us; 4us; 4us; 5us; 5us; 6us; 6us; 7us; 8us; 8us; 9us; 9us; 10us; 10us; 11us; 12us; 12us; 12us; 13us; 13us; |] +let _fsyacc_immediateActions = [|65535us; 49152us; 65535us; 65535us; 65535us; 16385us; 16386us; 65535us; 16389us; 65535us; 16390us; 65535us; 16391us; 65535us; 16392us; 65535us; 16393us; 65535us; 16394us; 65535us; 16395us; 65535us; 16396us; 65535us; 16398us; 65535us; 65535us; 65535us; 65535us; 16400us; 16402us; 16404us; 65535us; 65535us; 16405us; 65535us; 65535us; 16407us; 65535us; 16408us; 65535us; 16409us; 65535us; 16412us; |] +let _fsyacc_reductions () = [| +# 216 "fsyaccpars.fs" + (fun (parseState : Internal.Utilities.Text.Parsing.IParseState) -> + let _1 = (let data = parseState.GetInput(1) in (Microsoft.FSharp.Core.Operators.unbox data : AST.ParserSpec)) in + Microsoft.FSharp.Core.Operators.box + ( + ( + raise (Internal.Utilities.Text.Parsing.Accept(Microsoft.FSharp.Core.Operators.box _1)) + ) + : '_startspec)); +# 225 "fsyaccpars.fs" + (fun (parseState : Internal.Utilities.Text.Parsing.IParseState) -> + let _1 = (let data = parseState.GetInput(1) in (Microsoft.FSharp.Core.Operators.unbox data : 'headeropt)) in + let _2 = (let data = parseState.GetInput(2) in (Microsoft.FSharp.Core.Operators.unbox data : 'decls)) in + let _4 = (let data = parseState.GetInput(4) in (Microsoft.FSharp.Core.Operators.unbox data : 'rules)) in + Microsoft.FSharp.Core.Operators.box + ( + ( +# 25 "fsyaccpars.fsy" + List.foldBack (fun f x -> f x) _2 { Header=_1;Tokens=[];Types=[];Associativities=[];StartSymbols=[];Rules=_4 } + ) +# 25 "fsyaccpars.fsy" + : AST.ParserSpec)); +# 238 "fsyaccpars.fs" + (fun (parseState : Internal.Utilities.Text.Parsing.IParseState) -> + let _1 = (let data = parseState.GetInput(1) in (Microsoft.FSharp.Core.Operators.unbox data : AST.Code)) in + Microsoft.FSharp.Core.Operators.box + ( + ( +# 29 "fsyaccpars.fsy" + _1 + ) +# 29 "fsyaccpars.fsy" + : 'headeropt)); +# 249 "fsyaccpars.fs" + (fun (parseState : Internal.Utilities.Text.Parsing.IParseState) -> + Microsoft.FSharp.Core.Operators.box + ( + ( +# 31 "fsyaccpars.fsy" + "", (parseState.ResultRange |> fst) + ) +# 31 "fsyaccpars.fsy" + : 'headeropt)); +# 259 "fsyaccpars.fs" + (fun (parseState : Internal.Utilities.Text.Parsing.IParseState) -> + Microsoft.FSharp.Core.Operators.box + ( + ( +# 34 "fsyaccpars.fsy" + [] + ) +# 34 "fsyaccpars.fsy" + : 'decls)); +# 269 "fsyaccpars.fs" + (fun (parseState : Internal.Utilities.Text.Parsing.IParseState) -> + let _1 = (let data = parseState.GetInput(1) in (Microsoft.FSharp.Core.Operators.unbox data : 'decl)) in + let _2 = (let data = parseState.GetInput(2) in (Microsoft.FSharp.Core.Operators.unbox data : 'decls)) in + Microsoft.FSharp.Core.Operators.box + ( + ( +# 35 "fsyaccpars.fsy" + _1 :: _2 + ) +# 35 "fsyaccpars.fsy" + : 'decls)); +# 281 "fsyaccpars.fs" + (fun (parseState : Internal.Utilities.Text.Parsing.IParseState) -> + let _1 = (let data = parseState.GetInput(1) in (Microsoft.FSharp.Core.Operators.unbox data : string option)) in + let _2 = (let data = parseState.GetInput(2) in (Microsoft.FSharp.Core.Operators.unbox data : 'idents)) in + Microsoft.FSharp.Core.Operators.box + ( + ( +# 38 "fsyaccpars.fsy" + (fun x -> {x with Tokens = x.Tokens @ (List.map (fun x -> (x,_1)) _2)}) + ) +# 38 "fsyaccpars.fsy" + : 'decl)); +# 293 "fsyaccpars.fs" + (fun (parseState : Internal.Utilities.Text.Parsing.IParseState) -> + let _1 = (let data = parseState.GetInput(1) in (Microsoft.FSharp.Core.Operators.unbox data : string)) in + let _2 = (let data = parseState.GetInput(2) in (Microsoft.FSharp.Core.Operators.unbox data : 'idents)) in + Microsoft.FSharp.Core.Operators.box + ( + ( +# 39 "fsyaccpars.fsy" + (fun x -> {x with Types = x.Types @ (List.map (fun x -> (x,_1)) _2)} ) + ) +# 39 "fsyaccpars.fsy" + : 'decl)); +# 305 "fsyaccpars.fs" + (fun (parseState : Internal.Utilities.Text.Parsing.IParseState) -> + let _2 = (let data = parseState.GetInput(2) in (Microsoft.FSharp.Core.Operators.unbox data : 'idents)) in + Microsoft.FSharp.Core.Operators.box + ( + ( +# 40 "fsyaccpars.fsy" + (fun x -> {x with StartSymbols = x.StartSymbols @ _2} ) + ) +# 40 "fsyaccpars.fsy" + : 'decl)); +# 316 "fsyaccpars.fs" + (fun (parseState : Internal.Utilities.Text.Parsing.IParseState) -> + let _2 = (let data = parseState.GetInput(2) in (Microsoft.FSharp.Core.Operators.unbox data : 'idents)) in + Microsoft.FSharp.Core.Operators.box + ( + ( +# 41 "fsyaccpars.fsy" + (fun x -> {x with Associativities = x.Associativities @ [(List.map (fun x -> (x,LeftAssoc)) _2)]} ) + ) +# 41 "fsyaccpars.fsy" + : 'decl)); +# 327 "fsyaccpars.fs" + (fun (parseState : Internal.Utilities.Text.Parsing.IParseState) -> + let _2 = (let data = parseState.GetInput(2) in (Microsoft.FSharp.Core.Operators.unbox data : 'idents)) in + Microsoft.FSharp.Core.Operators.box + ( + ( +# 42 "fsyaccpars.fsy" + (fun x -> {x with Associativities = x.Associativities @ [(List.map (fun x -> (x,RightAssoc)) _2)]} ) + ) +# 42 "fsyaccpars.fsy" + : 'decl)); +# 338 "fsyaccpars.fs" + (fun (parseState : Internal.Utilities.Text.Parsing.IParseState) -> + let _2 = (let data = parseState.GetInput(2) in (Microsoft.FSharp.Core.Operators.unbox data : 'idents)) in + Microsoft.FSharp.Core.Operators.box + ( + ( +# 43 "fsyaccpars.fsy" + (fun x -> {x with Associativities = x.Associativities @ [(List.map (fun x -> (x,NonAssoc)) _2)]} ) + ) +# 43 "fsyaccpars.fsy" + : 'decl)); +# 349 "fsyaccpars.fs" + (fun (parseState : Internal.Utilities.Text.Parsing.IParseState) -> + let _1 = (let data = parseState.GetInput(1) in (Microsoft.FSharp.Core.Operators.unbox data : string)) in + let _2 = (let data = parseState.GetInput(2) in (Microsoft.FSharp.Core.Operators.unbox data : 'idents)) in + Microsoft.FSharp.Core.Operators.box + ( + ( +# 45 "fsyaccpars.fsy" + _1 :: _2 + ) +# 45 "fsyaccpars.fsy" + : 'idents)); +# 361 "fsyaccpars.fs" + (fun (parseState : Internal.Utilities.Text.Parsing.IParseState) -> + Microsoft.FSharp.Core.Operators.box + ( + ( +# 45 "fsyaccpars.fsy" + [] + ) +# 45 "fsyaccpars.fsy" + : 'idents)); +# 371 "fsyaccpars.fs" + (fun (parseState : Internal.Utilities.Text.Parsing.IParseState) -> + let _1 = (let data = parseState.GetInput(1) in (Microsoft.FSharp.Core.Operators.unbox data : 'rule)) in + let _2 = (let data = parseState.GetInput(2) in (Microsoft.FSharp.Core.Operators.unbox data : 'rules)) in + Microsoft.FSharp.Core.Operators.box + ( + ( +# 46 "fsyaccpars.fsy" + _1 :: _2 + ) +# 46 "fsyaccpars.fsy" + : 'rules)); +# 383 "fsyaccpars.fs" + (fun (parseState : Internal.Utilities.Text.Parsing.IParseState) -> + let _1 = (let data = parseState.GetInput(1) in (Microsoft.FSharp.Core.Operators.unbox data : 'rule)) in + Microsoft.FSharp.Core.Operators.box + ( + ( +# 46 "fsyaccpars.fsy" + [_1] + ) +# 46 "fsyaccpars.fsy" + : 'rules)); +# 394 "fsyaccpars.fs" + (fun (parseState : Internal.Utilities.Text.Parsing.IParseState) -> + let _1 = (let data = parseState.GetInput(1) in (Microsoft.FSharp.Core.Operators.unbox data : string)) in + let _3 = (let data = parseState.GetInput(3) in (Microsoft.FSharp.Core.Operators.unbox data : 'optbar)) in + let _4 = (let data = parseState.GetInput(4) in (Microsoft.FSharp.Core.Operators.unbox data : 'clauses)) in + let _5 = (let data = parseState.GetInput(5) in (Microsoft.FSharp.Core.Operators.unbox data : 'optsemi)) in + Microsoft.FSharp.Core.Operators.box + ( + ( +# 47 "fsyaccpars.fsy" + (_1,_4) + ) +# 47 "fsyaccpars.fsy" + : 'rule)); +# 408 "fsyaccpars.fs" + (fun (parseState : Internal.Utilities.Text.Parsing.IParseState) -> + Microsoft.FSharp.Core.Operators.box + ( + ( +# 48 "fsyaccpars.fsy" + + ) +# 48 "fsyaccpars.fsy" + : 'optbar)); +# 418 "fsyaccpars.fs" + (fun (parseState : Internal.Utilities.Text.Parsing.IParseState) -> + Microsoft.FSharp.Core.Operators.box + ( + ( +# 48 "fsyaccpars.fsy" + + ) +# 48 "fsyaccpars.fsy" + : 'optbar)); +# 428 "fsyaccpars.fs" + (fun (parseState : Internal.Utilities.Text.Parsing.IParseState) -> + Microsoft.FSharp.Core.Operators.box + ( + ( +# 49 "fsyaccpars.fsy" + + ) +# 49 "fsyaccpars.fsy" + : 'optsemi)); +# 438 "fsyaccpars.fs" + (fun (parseState : Internal.Utilities.Text.Parsing.IParseState) -> + Microsoft.FSharp.Core.Operators.box + ( + ( +# 49 "fsyaccpars.fsy" + + ) +# 49 "fsyaccpars.fsy" + : 'optsemi)); +# 448 "fsyaccpars.fs" + (fun (parseState : Internal.Utilities.Text.Parsing.IParseState) -> + let _1 = (let data = parseState.GetInput(1) in (Microsoft.FSharp.Core.Operators.unbox data : 'clause)) in + let _3 = (let data = parseState.GetInput(3) in (Microsoft.FSharp.Core.Operators.unbox data : 'clauses)) in + Microsoft.FSharp.Core.Operators.box + ( + ( +# 50 "fsyaccpars.fsy" + _1 :: _3 + ) +# 50 "fsyaccpars.fsy" + : 'clauses)); +# 460 "fsyaccpars.fs" + (fun (parseState : Internal.Utilities.Text.Parsing.IParseState) -> + let _1 = (let data = parseState.GetInput(1) in (Microsoft.FSharp.Core.Operators.unbox data : 'clause)) in + Microsoft.FSharp.Core.Operators.box + ( + ( +# 50 "fsyaccpars.fsy" + [_1] + ) +# 50 "fsyaccpars.fsy" + : 'clauses)); +# 471 "fsyaccpars.fs" + (fun (parseState : Internal.Utilities.Text.Parsing.IParseState) -> + let _1 = (let data = parseState.GetInput(1) in (Microsoft.FSharp.Core.Operators.unbox data : 'syms)) in + let _2 = (let data = parseState.GetInput(2) in (Microsoft.FSharp.Core.Operators.unbox data : 'optprec)) in + let _3 = (let data = parseState.GetInput(3) in (Microsoft.FSharp.Core.Operators.unbox data : AST.Code)) in + Microsoft.FSharp.Core.Operators.box + ( + ( +# 51 "fsyaccpars.fsy" + Rule(_1,_2,Some _3) + ) +# 51 "fsyaccpars.fsy" + : 'clause)); +# 484 "fsyaccpars.fs" + (fun (parseState : Internal.Utilities.Text.Parsing.IParseState) -> + let _1 = (let data = parseState.GetInput(1) in (Microsoft.FSharp.Core.Operators.unbox data : string)) in + let _2 = (let data = parseState.GetInput(2) in (Microsoft.FSharp.Core.Operators.unbox data : 'syms)) in + Microsoft.FSharp.Core.Operators.box + ( + ( +# 52 "fsyaccpars.fsy" + _1 :: _2 + ) +# 52 "fsyaccpars.fsy" + : 'syms)); +# 496 "fsyaccpars.fs" + (fun (parseState : Internal.Utilities.Text.Parsing.IParseState) -> + let _2 = (let data = parseState.GetInput(2) in (Microsoft.FSharp.Core.Operators.unbox data : 'syms)) in + Microsoft.FSharp.Core.Operators.box + ( + ( +# 52 "fsyaccpars.fsy" + "error" :: _2 + ) +# 52 "fsyaccpars.fsy" + : 'syms)); +# 507 "fsyaccpars.fs" + (fun (parseState : Internal.Utilities.Text.Parsing.IParseState) -> + Microsoft.FSharp.Core.Operators.box + ( + ( +# 52 "fsyaccpars.fsy" + [] + ) +# 52 "fsyaccpars.fsy" + : 'syms)); +# 517 "fsyaccpars.fs" + (fun (parseState : Internal.Utilities.Text.Parsing.IParseState) -> + Microsoft.FSharp.Core.Operators.box + ( + ( +# 53 "fsyaccpars.fsy" + None + ) +# 53 "fsyaccpars.fsy" + : 'optprec)); +# 527 "fsyaccpars.fs" + (fun (parseState : Internal.Utilities.Text.Parsing.IParseState) -> + let _2 = (let data = parseState.GetInput(2) in (Microsoft.FSharp.Core.Operators.unbox data : string)) in + Microsoft.FSharp.Core.Operators.box + ( + ( +# 53 "fsyaccpars.fsy" + Some _2 + ) +# 53 "fsyaccpars.fsy" + : 'optprec)); +|] +# 539 "fsyaccpars.fs" +let tables () : Internal.Utilities.Text.Parsing.Tables<_> = + { reductions= _fsyacc_reductions (); + endOfInputTag = _fsyacc_endOfInputTag; + tagOfToken = tagOfToken; + dataOfToken = _fsyacc_dataOfToken; + actionTableElements = _fsyacc_actionTableElements; + actionTableRowOffsets = _fsyacc_actionTableRowOffsets; + stateToProdIdxsTableElements = _fsyacc_stateToProdIdxsTableElements; + stateToProdIdxsTableRowOffsets = _fsyacc_stateToProdIdxsTableRowOffsets; + reductionSymbolCounts = _fsyacc_reductionSymbolCounts; + immediateActions = _fsyacc_immediateActions; + gotos = _fsyacc_gotos; + sparseGotoTableRowOffsets = _fsyacc_sparseGotoTableRowOffsets; + tagOfErrorTerminal = _fsyacc_tagOfErrorTerminal; + parseError = (fun (ctxt:Internal.Utilities.Text.Parsing.ParseErrorContext<_>) -> + match parse_error_rich with + | Some f -> f ctxt + | None -> parse_error ctxt.Message); + numTerminals = 21; + productionToNonTerminalTable = _fsyacc_productionToNonTerminalTable } +let engine lexer lexbuf startState = (tables ()).Interpret(lexer, lexbuf, startState) +let spec lexer lexbuf : AST.ParserSpec = + Microsoft.FSharp.Core.Operators.unbox ((tables ()).Interpret(lexer, lexbuf, 0)) diff --git a/src/fsharp/AccessibilityLogic.fs b/src/fsharp/AccessibilityLogic.fs index 7e2e2ef5d9..dcd8d5d801 100644 --- a/src/fsharp/AccessibilityLogic.fs +++ b/src/fsharp/AccessibilityLogic.fs @@ -194,9 +194,10 @@ let CheckTyconReprAccessible amap m ad tcref = /// Indicates if a type is accessible (both definition and instantiation) let rec IsTypeAccessible g amap m ad ty = - not (isAppTy g ty) || - let tcref, tinst = destAppTy g ty - IsEntityAccessible amap m ad tcref && IsTypeInstAccessible g amap m ad tinst + match tryAppTy g ty with + | ValueNone -> true + | ValueSome(tcref, tinst) -> + IsEntityAccessible amap m ad tcref && IsTypeInstAccessible g amap m ad tinst and IsTypeInstAccessible g amap m ad tinst = match tinst with @@ -210,7 +211,7 @@ let IsProvidedMemberAccessible (amap:Import.ImportMap) m ad ty access = if not isTyAccessible then false else not (isAppTy g ty) || - let tcrefOfViewedItem, _ = destAppTy g ty + let tcrefOfViewedItem = tcrefOfAppTy g ty IsILMemberAccessible g amap m tcrefOfViewedItem ad access /// Compute the accessibility of a provided member diff --git a/src/fsharp/AttributeChecking.fs b/src/fsharp/AttributeChecking.fs index 3be4a3a070..a28598d970 100644 --- a/src/fsharp/AttributeChecking.fs +++ b/src/fsharp/AttributeChecking.fs @@ -449,8 +449,8 @@ let MethInfoIsUnseen g m ty minfo = // We are only interested in filtering out the method on System.Object, so it is sufficient // just to look at the attributes on IL methods. if tcref.IsILTycon then - tcref.ILTyconRawMetadata.CustomAttrs.AsList - |> List.exists (fun attr -> attr.Method.DeclaringType.TypeSpec.Name = typeof.FullName) + tcref.ILTyconRawMetadata.CustomAttrs.AsArray + |> Array.exists (fun attr -> attr.Method.DeclaringType.TypeSpec.Name = typeof.FullName) else false #else diff --git a/src/fsharp/CheckFormatStrings.fs b/src/fsharp/CheckFormatStrings.fs index 4d532904a1..9d7fd72d7a 100755 --- a/src/fsharp/CheckFormatStrings.fs +++ b/src/fsharp/CheckFormatStrings.fs @@ -54,15 +54,15 @@ let parseFormatStringInternal (m:range) (g: TcGlobals) (context: FormatStringChe let (offset, fmt) = match context with | Some context -> - let length = context.NormalizedSource.Length - if m.EndLine < context.LineEndPositions.Length then - let startIndex = context.LineEndPositions.[m.StartLine-1] + m.StartColumn - let endIndex = context.LineEndPositions.[m.EndLine-1] + m.EndColumn - 1 - if startIndex < length-3 && context.NormalizedSource.[startIndex..startIndex+2] = "\"\"\"" then - (3, context.NormalizedSource.[startIndex+3..endIndex-3]) - elif startIndex < length-2 && context.NormalizedSource.[startIndex..startIndex+1] = "@\"" then - (2, context.NormalizedSource.[startIndex+2..endIndex-1]) - else (1, context.NormalizedSource.[startIndex+1..endIndex-1]) + let length = context.Source.Length + if m.EndLine < context.LineStartPositions.Length then + let startIndex = context.LineStartPositions.[m.StartLine-1] + m.StartColumn + let endIndex = context.LineStartPositions.[m.EndLine-1] + m.EndColumn - 1 + if startIndex < length-3 && context.Source.[startIndex..startIndex+2] = "\"\"\"" then + (3, context.Source.[startIndex+3..endIndex-3]) + elif startIndex < length-2 && context.Source.[startIndex..startIndex+1] = "@\"" then + (2, context.Source.[startIndex+2..endIndex-1]) + else (1, context.Source.[startIndex+1..endIndex-1]) else (1, fmt) | None -> (1, fmt) diff --git a/src/fsharp/CompileOps.fs b/src/fsharp/CompileOps.fs index d54373c554..830a08bf2f 100755 --- a/src/fsharp/CompileOps.fs +++ b/src/fsharp/CompileOps.fs @@ -960,12 +960,12 @@ let OutputPhasedErrorR (os:StringBuilder) (err:PhasedDiagnostic) = | Parser.TOKEN_RPAREN | Parser.TOKEN_RPAREN_COMING_SOON | Parser.TOKEN_RPAREN_IS_HERE -> getErrorString("Parser.TOKEN.RPAREN") | Parser.TOKEN_LQUOTE -> getErrorString("Parser.TOKEN.LQUOTE") | Parser.TOKEN_LBRACK -> getErrorString("Parser.TOKEN.LBRACK") + | Parser.TOKEN_LBRACE_BAR -> getErrorString("Parser.TOKEN.LBRACE.BAR") | Parser.TOKEN_LBRACK_BAR -> getErrorString("Parser.TOKEN.LBRACK.BAR") | Parser.TOKEN_LBRACK_LESS -> getErrorString("Parser.TOKEN.LBRACK.LESS") | Parser.TOKEN_LBRACE -> getErrorString("Parser.TOKEN.LBRACE") - | Parser.TOKEN_LBRACE_LESS-> getErrorString("Parser.TOKEN.LBRACE.LESS") | Parser.TOKEN_BAR_RBRACK -> getErrorString("Parser.TOKEN.BAR.RBRACK") - | Parser.TOKEN_GREATER_RBRACE -> getErrorString("Parser.TOKEN.GREATER.RBRACE") + | Parser.TOKEN_BAR_RBRACE -> getErrorString("Parser.TOKEN.BAR.RBRACE") | Parser.TOKEN_GREATER_RBRACK -> getErrorString("Parser.TOKEN.GREATER.RBRACK") | Parser.TOKEN_RQUOTE_DOT _ | Parser.TOKEN_RQUOTE -> getErrorString("Parser.TOKEN.RQUOTE") @@ -1096,7 +1096,7 @@ let OutputPhasedErrorR (os:StringBuilder) (err:PhasedDiagnostic) = (* Merge a bunch of expression non terminals *) let (|NONTERM_Category_Expr|_|) = function | Parser.NONTERM_argExpr|Parser.NONTERM_minusExpr|Parser.NONTERM_parenExpr|Parser.NONTERM_atomicExpr - | Parser.NONTERM_appExpr|Parser.NONTERM_tupleExpr|Parser.NONTERM_declExpr|Parser.NONTERM_braceExpr + | Parser.NONTERM_appExpr|Parser.NONTERM_tupleExpr|Parser.NONTERM_declExpr|Parser.NONTERM_braceExpr|Parser.NONTERM_braceBarExpr | Parser.NONTERM_typedSeqExprBlock | Parser.NONTERM_interactiveExpr -> Some() | _ -> None @@ -1825,6 +1825,7 @@ let DefaultReferencesForScriptsAndOutOfProjectSources(assumeDotNetFramework) = yield "System.Data" yield "System.Drawing" yield "System.Core" + // These are the Portable-profile and .NET Standard 1.6 dependencies of FSharp.Core.dll. These are needed // when an F# sript references an F# profile 7, 78, 259 or .NET Standard 1.6 component which in turn refers // to FSharp.Core for profile 7, 78, 259 or .NET Standard. @@ -1850,17 +1851,24 @@ let DefaultReferencesForScriptsAndOutOfProjectSources(assumeDotNetFramework) = yield "System.Windows.Forms" yield "System.Numerics" else - yield Path.Combine(Path.GetDirectoryName(typeof.Assembly.Location), "mscorlib.dll"); // mscorlib - yield typeof.Assembly.Location; // System.Console - yield typeof.Assembly.Location; // System.Runtime - yield typeof.Assembly.Location; // System.ObjectModel - yield typeof.Assembly.Location; // System.IO - yield typeof.Assembly.Location; // System.Linq - //yield typeof.Assembly.Location; // System.Xml.Linq - yield typeof.Assembly.Location; // System.Net.Requests - yield typeof.Assembly.Location; // System.Runtime.Numerics - yield typeof.Assembly.Location; // System.Threading.Tasks - yield typeof.Assembly.Location; // FSharp.Core + yield Path.Combine(Path.GetDirectoryName(typeof.Assembly.Location), "mscorlib.dll") // mscorlib + yield typeof.Assembly.Location // System.Console + yield typeof.Assembly.Location // System.Collections + yield typeof.Assembly.Location // System.Data.SqlClient + yield typeof.Assembly.Location // System.ObjectModel + yield typeof.Assembly.Location // System.IO.FileSystem + yield typeof.Assembly.Location // System.IO + yield typeof.Assembly.Location // System.Linq + yield typeof.Assembly.Location // System.Xml + yield typeof.Assembly.Location // System.Xml.Linq + yield typeof.Assembly.Location // System.Net.Requests + yield typeof.Assembly.Location // System.Runtime.Numerics + yield typeof.Assembly.Location // System.Net.Security + yield typeof.Assembly.Location // System.Security.Claims + yield typeof.Assembly.Location // System.Text.RegularExpressions.Regex + yield typeof.Assembly.Location // System.Threading.Tasks + yield typeof.Assembly.Location // System.Threading + yield typeof.Assembly.Location // FSharp.Core ] @@ -2348,6 +2356,8 @@ type TcConfigBuilder = mutable tryGetMetadataSnapshot : ILReaderTryGetMetadataSnapshot mutable internalTestSpanStackReferring : bool + + mutable noConditionalErasure : bool } static member Initial = @@ -2485,6 +2495,7 @@ type TcConfigBuilder = shadowCopyReferences = false tryGetMetadataSnapshot = (fun _ -> None) internalTestSpanStackReferring = false + noConditionalErasure = false } static member CreateNew(legacyReferenceResolver, defaultFSharpBinariesDir, reduceMemoryUsage, implicitIncludeDir, @@ -2609,13 +2620,13 @@ type TcConfigBuilder = member tcConfigB.RemoveReferencedAssemblyByPath (m, path) = tcConfigB.referencedDLLs <- tcConfigB.referencedDLLs |> List.filter (fun ar-> ar.Range <> m || ar.Text <> path) - static member SplitCommandLineResourceInfo ri = - if String.contains ri ',' then - let p = String.index ri ',' + static member SplitCommandLineResourceInfo (ri:string) = + let p = ri.IndexOf ',' + if p <> -1 then let file = String.sub ri 0 p let rest = String.sub ri (p+1) (String.length ri - p - 1) - if String.contains rest ',' then - let p = String.index rest ',' + let p = rest.IndexOf ',' + if p <> -1 then let name = String.sub rest 0 p+".resources" let pubpri = String.sub rest (p+1) (rest.Length - p - 1) if pubpri = "public" then file, name, ILResourceAccess.Public @@ -2674,9 +2685,9 @@ type AssemblyResolution = member this.GetILAssemblyRef(ctok, reduceMemoryUsage, tryGetMetadataSnapshot) = cancellable { match !this.ilAssemblyRef with - | Some(assref) -> return assref + | Some(assemblyRef) -> return assemblyRef | None -> - let! assRefOpt = + let! assemblyRefOpt = cancellable { match this.ProjectReference with | Some r -> @@ -2689,8 +2700,8 @@ type AssemblyResolution = | _ -> return None | None -> return None } - let assRef = - match assRefOpt with + let assemblyRef = + match assemblyRefOpt with | Some aref -> aref | None -> let readerSettings : ILReaderOptions = @@ -2701,8 +2712,8 @@ type AssemblyResolution = tryGetMetadataSnapshot = tryGetMetadataSnapshot } use reader = OpenILModuleReader this.resolvedPath readerSettings mkRefToILAssembly reader.ILModuleDef.ManifestOfAssembly - this.ilAssemblyRef := Some(assRef) - return assRef + this.ilAssemblyRef := Some(assemblyRef) + return assemblyRef } //---------------------------------------------------------------------------- @@ -2946,6 +2957,8 @@ type TcConfig private (data : TcConfigBuilder, validate:bool) = member x.shadowCopyReferences = data.shadowCopyReferences member x.tryGetMetadataSnapshot = data.tryGetMetadataSnapshot member x.internalTestSpanStackReferring = data.internalTestSpanStackReferring + member x.noConditionalErasure = data.noConditionalErasure + static member Create(builder, validate) = use unwindBuildPhase = PushThreadBuildPhaseUntilUnwind BuildPhase.Parameter TcConfig(builder, validate) @@ -3376,14 +3389,14 @@ let ComputeQualifiedNameOfFileFromUniquePath (m, p: string list) = QualifiedName let QualFileNameOfSpecs filename specs = match specs with - | [SynModuleOrNamespaceSig(modname, _, true, _, _, _, _, m)] -> QualFileNameOfModuleName m filename modname - | [SynModuleOrNamespaceSig(_, _, false, _, _, _, _, m)] -> QualFileNameOfFilename m filename + | [SynModuleOrNamespaceSig(modname, _, kind, _, _, _, _, m)] when kind.IsModule -> QualFileNameOfModuleName m filename modname + | [SynModuleOrNamespaceSig(_, _, kind, _, _, _, _, m)] when not kind.IsModule -> QualFileNameOfFilename m filename | _ -> QualFileNameOfFilename (mkRange filename pos0 pos0) filename let QualFileNameOfImpls filename specs = match specs with - | [SynModuleOrNamespace(modname, _, true, _, _, _, _, m)] -> QualFileNameOfModuleName m filename modname - | [SynModuleOrNamespace(_, _, false, _, _, _, _, m)] -> QualFileNameOfFilename m filename + | [SynModuleOrNamespace(modname, _, kind, _, _, _, _, m)] when kind.IsModule -> QualFileNameOfModuleName m filename modname + | [SynModuleOrNamespace(_, _, kind, _, _, _, _, m)] when not kind.IsModule -> QualFileNameOfFilename m filename | _ -> QualFileNameOfFilename (mkRange filename pos0 pos0) filename let PrepandPathToQualFileName x (QualifiedNameOfFile(q)) = ComputeQualifiedNameOfFileFromUniquePath (q.idRange, pathOfLid x@[q.idText]) @@ -3412,13 +3425,14 @@ let ComputeAnonModuleName check defaultNamespace filename (m: range) = let PostParseModuleImpl (_i, defaultNamespace, isLastCompiland, filename, impl) = match impl with - | ParsedImplFileFragment.NamedModule(SynModuleOrNamespace(lid, isRec, isModule, decls, xmlDoc, attribs, access, m)) -> + | ParsedImplFileFragment.NamedModule(SynModuleOrNamespace(lid, isRec, kind, decls, xmlDoc, attribs, access, m)) -> let lid = match lid with - | [id] when isModule && id.idText = MangledGlobalName -> error(Error(FSComp.SR.buildInvalidModuleOrNamespaceName(), id.idRange)) + | [id] when kind.IsModule && id.idText = MangledGlobalName -> + error(Error(FSComp.SR.buildInvalidModuleOrNamespaceName(), id.idRange)) | id :: rest when id.idText = MangledGlobalName -> rest | _ -> lid - SynModuleOrNamespace(lid, isRec, isModule, decls, xmlDoc, attribs, access, m) + SynModuleOrNamespace(lid, isRec, kind, decls, xmlDoc, attribs, access, m) | ParsedImplFileFragment.AnonModule (defs, m)-> let isLast, isExe = isLastCompiland @@ -3429,24 +3443,26 @@ let PostParseModuleImpl (_i, defaultNamespace, isLastCompiland, filename, impl) | _ -> errorR(Error(FSComp.SR.buildMultiFileRequiresNamespaceOrModule(), trimRangeToLine m)) let modname = ComputeAnonModuleName (not (isNil defs)) defaultNamespace filename (trimRangeToLine m) - SynModuleOrNamespace(modname, false, true, defs, PreXmlDoc.Empty, [], None, m) + SynModuleOrNamespace(modname, false, AnonModule, defs, PreXmlDoc.Empty, [], None, m) - | ParsedImplFileFragment.NamespaceFragment (lid, a, b, c, d, e, m)-> - let lid = + | ParsedImplFileFragment.NamespaceFragment (lid, a, kind, c, d, e, m)-> + let lid, kind = match lid with - | id :: rest when id.idText = MangledGlobalName -> rest - | _ -> lid - SynModuleOrNamespace(lid, a, b, c, d, e, None, m) + | id :: rest when id.idText = MangledGlobalName -> + rest, if List.isEmpty rest then GlobalNamespace else kind + | _ -> lid, kind + SynModuleOrNamespace(lid, a, kind, c, d, e, None, m) let PostParseModuleSpec (_i, defaultNamespace, isLastCompiland, filename, intf) = match intf with - | ParsedSigFileFragment.NamedModule(SynModuleOrNamespaceSig(lid, isRec, isModule, decls, xmlDoc, attribs, access, m)) -> + | ParsedSigFileFragment.NamedModule(SynModuleOrNamespaceSig(lid, isRec, kind, decls, xmlDoc, attribs, access, m)) -> let lid = match lid with - | [id] when isModule && id.idText = MangledGlobalName -> error(Error(FSComp.SR.buildInvalidModuleOrNamespaceName(), id.idRange)) + | [id] when kind.IsModule && id.idText = MangledGlobalName -> + error(Error(FSComp.SR.buildInvalidModuleOrNamespaceName(), id.idRange)) | id :: rest when id.idText = MangledGlobalName -> rest | _ -> lid - SynModuleOrNamespaceSig(lid, isRec, isModule, decls, xmlDoc, attribs, access, m) + SynModuleOrNamespaceSig(lid, isRec, NamedModule, decls, xmlDoc, attribs, access, m) | ParsedSigFileFragment.AnonModule (defs, m) -> let isLast, isExe = isLastCompiland @@ -3457,14 +3473,15 @@ let PostParseModuleSpec (_i, defaultNamespace, isLastCompiland, filename, intf) | _ -> errorR(Error(FSComp.SR.buildMultiFileRequiresNamespaceOrModule(), m)) let modname = ComputeAnonModuleName (not (isNil defs)) defaultNamespace filename (trimRangeToLine m) - SynModuleOrNamespaceSig(modname, false, true, defs, PreXmlDoc.Empty, [], None, m) + SynModuleOrNamespaceSig(modname, false, AnonModule, defs, PreXmlDoc.Empty, [], None, m) - | ParsedSigFileFragment.NamespaceFragment (lid, a, b, c, d, e, m)-> - let lid = + | ParsedSigFileFragment.NamespaceFragment (lid, a, kind, c, d, e, m)-> + let lid, kind = match lid with - | id :: rest when id.idText = MangledGlobalName -> rest - | _ -> lid - SynModuleOrNamespaceSig(lid, a, b, c, d, e, None, m) + | id :: rest when id.idText = MangledGlobalName -> + rest, if List.isEmpty rest then GlobalNamespace else kind + | _ -> lid, kind + SynModuleOrNamespaceSig(lid, a, kind, c, d, e, None, m) @@ -3508,34 +3525,37 @@ let PostParseModuleSpecs (defaultNamespace, filename, isLastCompiland, ParsedSig ParsedInput.SigFile(ParsedSigFileInput(filename, qualName, scopedPragmas, hashDirectives, specs)) +type ModuleNamesDict = Map> + /// Checks if a module name is already given and deduplicates the name if needed. -let DeduplicateModuleName (moduleNamesDict:IDictionary>) (paths: Set) path (qualifiedNameOfFile: QualifiedNameOfFile) = - let count = if paths.Contains path then paths.Count else paths.Count + 1 - moduleNamesDict.[qualifiedNameOfFile.Text] <- Set.add path paths - let id = qualifiedNameOfFile.Id - if count = 1 then qualifiedNameOfFile else QualifiedNameOfFile(Ident(id.idText + "___" + count.ToString(), id.idRange)) +let DeduplicateModuleName (moduleNamesDict:ModuleNamesDict) fileName (qualNameOfFile: QualifiedNameOfFile) = + let path = Path.GetDirectoryName fileName + let path = if FileSystem.IsPathRootedShim path then try FileSystem.GetFullPathShim path with _ -> path else path + match moduleNamesDict.TryGetValue qualNameOfFile.Text with + | true, paths -> + if paths.ContainsKey path then + paths.[path], moduleNamesDict + else + let count = paths.Count + 1 + let id = qualNameOfFile.Id + let qualNameOfFileT = if count = 1 then qualNameOfFile else QualifiedNameOfFile(Ident(id.idText + "___" + count.ToString(), id.idRange)) + let moduleNamesDictT = moduleNamesDict.Add(qualNameOfFile.Text, paths.Add(path, qualNameOfFileT)) + qualNameOfFileT, moduleNamesDictT + | _ -> + let moduleNamesDictT = moduleNamesDict.Add(qualNameOfFile.Text, Map.empty.Add(path, qualNameOfFile)) + qualNameOfFile, moduleNamesDictT /// Checks if a ParsedInput is using a module name that was already given and deduplicates the name if needed. -let DeduplicateParsedInputModuleName (moduleNamesDict:IDictionary>) input = +let DeduplicateParsedInputModuleName (moduleNamesDict: ModuleNamesDict) input = match input with - | ParsedInput.ImplFile (ParsedImplFileInput.ParsedImplFileInput(fileName, isScript, qualifiedNameOfFile, scopedPragmas, hashDirectives, modules, (isLastCompiland, isExe))) -> - let path = Path.GetDirectoryName fileName - match moduleNamesDict.TryGetValue qualifiedNameOfFile.Text with - | true, paths -> - let qualifiedNameOfFile = DeduplicateModuleName moduleNamesDict paths path qualifiedNameOfFile - ParsedInput.ImplFile(ParsedImplFileInput.ParsedImplFileInput(fileName, isScript, qualifiedNameOfFile, scopedPragmas, hashDirectives, modules, (isLastCompiland, isExe))) - | _ -> - moduleNamesDict.[qualifiedNameOfFile.Text] <- Set.singleton path - input - | ParsedInput.SigFile (ParsedSigFileInput.ParsedSigFileInput(fileName, qualifiedNameOfFile, scopedPragmas, hashDirectives, modules)) -> - let path = Path.GetDirectoryName fileName - match moduleNamesDict.TryGetValue qualifiedNameOfFile.Text with - | true, paths -> - let qualifiedNameOfFile = DeduplicateModuleName moduleNamesDict paths path qualifiedNameOfFile - ParsedInput.SigFile (ParsedSigFileInput.ParsedSigFileInput(fileName, qualifiedNameOfFile, scopedPragmas, hashDirectives, modules)) - | _ -> - moduleNamesDict.[qualifiedNameOfFile.Text] <- Set.singleton path - input + | ParsedInput.ImplFile (ParsedImplFileInput.ParsedImplFileInput(fileName, isScript, qualNameOfFile, scopedPragmas, hashDirectives, modules, (isLastCompiland, isExe))) -> + let qualNameOfFileT, moduleNamesDictT = DeduplicateModuleName moduleNamesDict fileName qualNameOfFile + let inputT = ParsedInput.ImplFile(ParsedImplFileInput.ParsedImplFileInput(fileName, isScript, qualNameOfFileT, scopedPragmas, hashDirectives, modules, (isLastCompiland, isExe))) + inputT, moduleNamesDictT + | ParsedInput.SigFile (ParsedSigFileInput.ParsedSigFileInput(fileName, qualNameOfFile, scopedPragmas, hashDirectives, modules)) -> + let qualNameOfFileT, moduleNamesDictT = DeduplicateModuleName moduleNamesDict fileName qualNameOfFile + let inputT = ParsedInput.SigFile (ParsedSigFileInput.ParsedSigFileInput(fileName, qualNameOfFileT, scopedPragmas, hashDirectives, modules)) + inputT, moduleNamesDictT let ParseInput (lexer, errorLogger:ErrorLogger, lexbuf:UnicodeLexing.Lexbuf, defaultNamespace, filename, isLastCompiland) = // The assert below is almost ok, but it fires in two cases: @@ -3655,10 +3675,10 @@ type TcAssemblyResolutions(tcConfig: TcConfig, results: AssemblyResolution list, member tcResolutions.TryFindByOriginalReference(assemblyReference:AssemblyReference) = originalReferenceToResolution.TryFind assemblyReference.Text /// This doesn't need to be cancellable, it is only used by F# Interactive - member tcResolution.TryFindByExactILAssemblyRef (ctok, assref) = + member tcResolution.TryFindByExactILAssemblyRef (ctok, assemblyRef) = results |> List.tryFind (fun ar-> let r = ar.GetILAssemblyRef(ctok, tcConfig.reduceMemoryUsage, tcConfig.tryGetMetadataSnapshot) |> Cancellable.runWithoutCancellation - r = assref) + r = assemblyRef) /// This doesn't need to be cancellable, it is only used by F# Interactive member tcResolution.TryFindBySimpleAssemblyName (ctok, simpleAssemName) = @@ -4026,11 +4046,11 @@ type TcImports(tcConfigP:TcConfigProvider, initialResolutions:TcAssemblyResoluti | ResolvedImportedAssembly(importedAssembly) -> ResolvedCcu(importedAssembly.FSharpViewOfMetadata) | UnresolvedImportedAssembly(assemblyName) -> UnresolvedCcu(assemblyName) - member tcImports.FindCcuFromAssemblyRef(ctok, m, assref:ILAssemblyRef) = + member tcImports.FindCcuFromAssemblyRef(ctok, m, assemblyRef:ILAssemblyRef) = CheckDisposed() - match tcImports.FindCcuInfo(ctok, m, assref.Name, lookupOnly=false) with + match tcImports.FindCcuInfo(ctok, m, assemblyRef.Name, lookupOnly=false) with | ResolvedImportedAssembly(importedAssembly) -> ResolvedCcu(importedAssembly.FSharpViewOfMetadata) - | UnresolvedImportedAssembly _ -> UnresolvedCcu(assref.QualifiedName) + | UnresolvedImportedAssembly _ -> UnresolvedCcu(assemblyRef.QualifiedName) #if !NO_EXTENSIONTYPING @@ -4641,8 +4661,8 @@ type TcImports(tcConfigP:TcConfigProvider, initialResolutions:TcAssemblyResoluti resolutions.TryFindBySimpleAssemblyName (ctok, simpleAssemName) |> Option.map (fun r -> r.resolvedPath) /// This doesn't need to be cancellable, it is only used by F# Interactive - member tcImports.TryFindExistingFullyQualifiedPathByExactAssemblyRef(ctok, assref:ILAssemblyRef) : string option = - resolutions.TryFindByExactILAssemblyRef (ctok, assref) |> Option.map (fun r -> r.resolvedPath) + member tcImports.TryFindExistingFullyQualifiedPathByExactAssemblyRef(ctok, assemblyRef:ILAssemblyRef) : string option = + resolutions.TryFindByExactILAssemblyRef (ctok, assemblyRef) |> Option.map (fun r -> r.resolvedPath) member tcImports.TryResolveAssemblyReference(ctok, assemblyReference:AssemblyReference, mode:ResolveAssemblyReferenceMode) : OperationResult = let tcConfig = tcConfigP.Get(ctok) @@ -5432,9 +5452,12 @@ let TypeCheckOneInputEventually (checkForErrors, tcConfig:TcConfig, tcImports:Tc if Zset.contains qualNameOfFile tcState.tcsRootImpls then errorR(Error(FSComp.SR.buildImplementationAlreadyGivenDetail(qualNameOfFile.Text), m)) + let conditionalDefines = + if tcConfig.noConditionalErasure then None else Some (tcConfig.conditionalCompilationDefines) + // Typecheck the signature file let! (tcEnv, sigFileType, createsGeneratedProvidedTypes) = - TypeCheckOneSigFile (tcGlobals, tcState.tcsNiceNameGen, amap, tcState.tcsCcu, checkForErrors, tcConfig.conditionalCompilationDefines, tcSink, tcConfig.internalTestSpanStackReferring) tcState.tcsTcSigEnv file + TypeCheckOneSigFile (tcGlobals, tcState.tcsNiceNameGen, amap, tcState.tcsCcu, checkForErrors, conditionalDefines, tcSink, tcConfig.internalTestSpanStackReferring) tcState.tcsTcSigEnv file let rootSigs = Zmap.add qualNameOfFile sigFileType tcState.tcsRootSigs @@ -5469,9 +5492,12 @@ let TypeCheckOneInputEventually (checkForErrors, tcConfig:TcConfig, tcImports:Tc let tcImplEnv = tcState.tcsTcImplEnv + let conditionalDefines = + if tcConfig.noConditionalErasure then None else Some (tcConfig.conditionalCompilationDefines) + // Typecheck the implementation file let! topAttrs, implFile, _implFileHiddenType, tcEnvAtEnd, createsGeneratedProvidedTypes = - TypeCheckOneImplFile (tcGlobals, tcState.tcsNiceNameGen, amap, tcState.tcsCcu, checkForErrors, tcConfig.conditionalCompilationDefines, tcSink, tcConfig.internalTestSpanStackReferring) tcImplEnv rootSigOpt file + TypeCheckOneImplFile (tcGlobals, tcState.tcsNiceNameGen, amap, tcState.tcsCcu, checkForErrors, conditionalDefines, tcSink, tcConfig.internalTestSpanStackReferring) tcImplEnv rootSigOpt file let hadSig = rootSigOpt.IsSome let implFileSigType = SigTypeOfImplFile implFile diff --git a/src/fsharp/CompileOps.fsi b/src/fsharp/CompileOps.fsi index eb371fa592..9ee74ee993 100755 --- a/src/fsharp/CompileOps.fsi +++ b/src/fsharp/CompileOps.fsi @@ -59,12 +59,13 @@ val ComputeQualifiedNameOfFileFromUniquePath: range * string list -> Ast.Qualifi val PrependPathToInput: Ast.Ident list -> Ast.ParsedInput -> Ast.ParsedInput -/// Checks if a module name is already given and deduplicates the name if needed. -val DeduplicateModuleName: IDictionary> -> Set -> string -> Ast.QualifiedNameOfFile -> Ast.QualifiedNameOfFile +/// State used to de-deuplicate module names along a list of file names +type ModuleNamesDict = Map> /// Checks if a ParsedInput is using a module name that was already given and deduplicates the name if needed. -val DeduplicateParsedInputModuleName: IDictionary> -> Ast.ParsedInput -> Ast.ParsedInput +val DeduplicateParsedInputModuleName: ModuleNamesDict -> Ast.ParsedInput -> Ast.ParsedInput * ModuleNamesDict +/// Parse a single input (A signature file or implementation file) val ParseInput: (UnicodeLexing.Lexbuf -> Parser.token) * ErrorLogger * UnicodeLexing.Lexbuf * string option * string * isLastCompiland:(bool * bool) -> Ast.ParsedInput //---------------------------------------------------------------------------- @@ -366,6 +367,9 @@ type TcConfigBuilder = /// if true - 'let mutable x = Span.Empty', the value 'x' is a stack referring span. Used for internal testing purposes only until we get true stack spans. mutable internalTestSpanStackReferring : bool + + /// Prevent erasure of conditional attributes and methods so tooling is able analyse them. + mutable noConditionalErasure: bool } static member Initial: TcConfigBuilder diff --git a/src/fsharp/CompileOptions.fs b/src/fsharp/CompileOptions.fs index 6ae18644de..344c0e1412 100755 --- a/src/fsharp/CompileOptions.fs +++ b/src/fsharp/CompileOptions.fs @@ -848,8 +848,8 @@ let testFlag tcConfigB = | str -> warning(Error(FSComp.SR.optsUnknownArgumentToTheTestSwitch(str),rangeCmdArgs))), None, None) -// not shown in fsc.exe help, no warning on use, motivation is for use from VS -let vsSpecificFlags (tcConfigB: TcConfigBuilder) = +// Not shown in fsc.exe help, no warning on use, motivation is for use from tooling. +let editorSpecificFlags (tcConfigB: TcConfigBuilder) = [ CompilerOption("vserrors", tagNone, OptionUnit (fun () -> tcConfigB.errorStyle <- ErrorStyle.VSErrors), None, None) CompilerOption("validate-type-providers", tagNone, OptionUnit (id), None, None) // preserved for compatibility's sake, no longer has any effect CompilerOption("LCID", tagInt, OptionInt ignore, None, None) @@ -857,7 +857,8 @@ let vsSpecificFlags (tcConfigB: TcConfigBuilder) = CompilerOption("sqmsessionguid", tagNone, OptionString ignore, None, None) CompilerOption("gccerrors", tagNone, OptionUnit (fun () -> tcConfigB.errorStyle <- ErrorStyle.GccErrors), None, None) CompilerOption("exename", tagNone, OptionString (fun s -> tcConfigB.exename <- Some(s)), None, None) - CompilerOption("maxerrors", tagInt, OptionInt (fun n -> tcConfigB.maxErrors <- n), None, None) ] + CompilerOption("maxerrors", tagInt, OptionInt (fun n -> tcConfigB.maxErrors <- n), None, None) + CompilerOption("noconditionalerasure", tagNone, OptionUnit (fun () -> tcConfigB.noConditionalErasure <- true), None, None) ] let internalFlags (tcConfigB:TcConfigBuilder) = [ @@ -896,7 +897,7 @@ let internalFlags (tcConfigB:TcConfigBuilder) = CompilerOption("alwayscallvirt",tagNone,OptionSwitch(callVirtSwitch tcConfigB),Some(InternalCommandLineOption("alwayscallvirt",rangeCmdArgs)), None) CompilerOption("nodebugdata",tagNone, OptionUnit (fun () -> tcConfigB.noDebugData<-true),Some(InternalCommandLineOption("--nodebugdata",rangeCmdArgs)), None) testFlag tcConfigB ] @ - vsSpecificFlags tcConfigB @ + editorSpecificFlags tcConfigB @ [ CompilerOption("jit", tagNone, OptionSwitch (jitoptimizeSwitch tcConfigB), Some(InternalCommandLineOption("jit", rangeCmdArgs)), None) CompilerOption("localoptimize", tagNone, OptionSwitch(localoptimizeSwitch tcConfigB),Some(InternalCommandLineOption("localoptimize", rangeCmdArgs)), None) CompilerOption("splitting", tagNone, OptionSwitch(splittingSwitch tcConfigB),Some(InternalCommandLineOption("splitting", rangeCmdArgs)), None) diff --git a/src/fsharp/ConstraintSolver.fs b/src/fsharp/ConstraintSolver.fs index 4997c4ba59..230474a2e8 100755 --- a/src/fsharp/ConstraintSolver.fs +++ b/src/fsharp/ConstraintSolver.fs @@ -227,6 +227,7 @@ let rec occursCheck g un ty = match stripTyEqns g ty with | TType_ucase(_, l) | TType_app (_, l) + | TType_anon(_, l) | TType_tuple (_, l) -> List.exists (occursCheck g un) l | TType_fun (d, r) -> occursCheck g un d || occursCheck g un r | TType_var r -> typarEq un r @@ -301,6 +302,7 @@ type TraitConstraintSolution = | TTraitBuiltIn | TTraitSolved of MethInfo * TypeInst | TTraitSolvedRecdProp of RecdFieldInfo * bool + | TTraitSolvedAnonRecdProp of AnonRecdTypeInfo * TypeInst * int let BakedInTraitConstraintNames = [ "op_Division" ; "op_Multiply"; "op_Addition" @@ -471,11 +473,14 @@ and SolveTypStaticReq (csenv:ConstraintSolverEnv) trace req ty = match stripTyparEqns ty with | TType_measure ms -> let vs = ListMeasureVarOccsWithNonZeroExponents ms - IterateD (fun ((tpr:Typar), _) -> SolveTypStaticReqTypar csenv trace req tpr) vs + trackErrors { + for (tpr, _) in vs do + return! SolveTypStaticReqTypar csenv trace req tpr + } | _ -> match tryAnyParTy csenv.g ty with - | Some tpr -> SolveTypStaticReqTypar csenv trace req tpr - | None -> CompleteD + | ValueSome tpr -> SolveTypStaticReqTypar csenv trace req tpr + | ValueNone -> CompleteD let TransactDynamicReq (trace:OptionalTrace) (tpr:Typar) req = let orig = tpr.DynamicReq @@ -487,7 +492,7 @@ let SolveTypDynamicReq (csenv:ConstraintSolverEnv) trace req ty = | TyparDynamicReq.No -> CompleteD | TyparDynamicReq.Yes -> match tryAnyParTy csenv.g ty with - | Some tpr when tpr.DynamicReq <> TyparDynamicReq.Yes -> + | ValueSome tpr when tpr.DynamicReq <> TyparDynamicReq.Yes -> TransactDynamicReq trace tpr TyparDynamicReq.Yes | _ -> CompleteD @@ -499,25 +504,27 @@ let TransactIsCompatFlex (trace:OptionalTrace) (tpr:Typar) req = let SolveTypIsCompatFlex (csenv:ConstraintSolverEnv) trace req ty = if req then match tryAnyParTy csenv.g ty with - | Some tpr when not tpr.IsCompatFlex -> TransactIsCompatFlex trace tpr req + | ValueSome tpr when not tpr.IsCompatFlex -> TransactIsCompatFlex trace tpr req | _ -> CompleteD else CompleteD -let SubstMeasureWarnIfRigid (csenv:ConstraintSolverEnv) trace (v:Typar) ms = +let SubstMeasureWarnIfRigid (csenv:ConstraintSolverEnv) trace (v:Typar) ms = trackErrors { if v.Rigidity.WarnIfUnified && not (isAnyParTy csenv.g (TType_measure ms)) then // NOTE: we grab the name eagerly to make sure the type variable prints as a type variable - let tpnmOpt = if v.IsCompilerGenerated then None else Some v.Name - SolveTypStaticReq csenv trace v.StaticReq (TType_measure ms) ++ (fun () -> + let tpnmOpt = if v.IsCompilerGenerated then None else Some v.Name + do! SolveTypStaticReq csenv trace v.StaticReq (TType_measure ms) SubstMeasure v ms - WarnD(NonRigidTypar(csenv.DisplayEnv, tpnmOpt, v.Range, TType_measure (Measure.Var v), TType_measure ms, csenv.m))) + return! WarnD(NonRigidTypar(csenv.DisplayEnv, tpnmOpt, v.Range, TType_measure (Measure.Var v), TType_measure ms, csenv.m)) else // Propagate static requirements from 'tp' to 'ty' - SolveTypStaticReq csenv trace v.StaticReq (TType_measure ms) ++ (fun () -> + do! SolveTypStaticReq csenv trace v.StaticReq (TType_measure ms) SubstMeasure v ms if v.Rigidity = TyparRigidity.Anon && measureEquiv csenv.g ms Measure.One then - WarnD(Error(FSComp.SR.csCodeLessGeneric(), v.Range)) - else CompleteD) + return! WarnD(Error(FSComp.SR.csCodeLessGeneric(), v.Range)) + else + () + } /// Imperatively unify the unit-of-measure expression ms against 1. /// There are three cases @@ -576,6 +583,7 @@ let rec SimplifyMeasuresInType g resultFirst ((generalizable, generalized) as pa match stripTyparEqns ty with | TType_ucase(_, l) | TType_app (_, l) + | TType_anon (_,l) | TType_tuple (_, l) -> SimplifyMeasuresInTypes g param l | TType_fun (d, r) -> if resultFirst then SimplifyMeasuresInTypes g param [r;d] else SimplifyMeasuresInTypes g param [d;r] @@ -613,6 +621,7 @@ let rec GetMeasureVarGcdInType v ty = match stripTyparEqns ty with | TType_ucase(_, l) | TType_app (_, l) + | TType_anon (_,l) | TType_tuple (_, l) -> GetMeasureVarGcdInTypes v l | TType_fun (d, r) -> GcdRational (GetMeasureVarGcdInType v d) (GetMeasureVarGcdInType v r) @@ -687,8 +696,8 @@ let CheckWarnIfRigid (csenv:ConstraintSolverEnv) ty1 (r:Typar) ty = if not r.Rigidity.WarnIfUnified then CompleteD else let needsWarning = match tryAnyParTy g ty with - | None -> true - | Some tp2 -> + | ValueNone -> true + | ValueSome tp2 -> not tp2.IsCompilerGenerated && (r.IsCompilerGenerated || // exclude this warning for two identically named user-specified type parameters, e.g. from different mutually recursive functions or types @@ -703,21 +712,17 @@ let CheckWarnIfRigid (csenv:ConstraintSolverEnv) ty1 (r:Typar) ty = /// Add the constraint "ty1 = ty" to the constraint problem, where ty1 is a type variable. /// Propagate all effects of adding this constraint, e.g. to solve other variables -let rec SolveTyparEqualsType (csenv:ConstraintSolverEnv) ndeep m2 (trace:OptionalTrace) ty1 ty = +let rec SolveTyparEqualsType (csenv:ConstraintSolverEnv) ndeep m2 (trace:OptionalTrace) ty1 ty = trackErrors { let m = csenv.m - - DepthCheck ndeep m ++ (fun () -> + do! DepthCheck ndeep m match ty1 with | TType_var r | TType_measure (Measure.Var r) -> // The types may still be equivalent due to abbreviations, which we are trying not to eliminate - if typeEquiv csenv.g ty1 ty then CompleteD else - + if typeEquiv csenv.g ty1 ty then () else // The famous 'occursCheck' check to catch "infinite types" like 'a = list<'a> - see also https://github.com/Microsoft/visualfsharp/issues/1170 - if occursCheck csenv.g r ty then ErrorD (ConstraintSolverInfiniteTypes(csenv.eContextInfo, csenv.DisplayEnv, ty1, ty, m, m2)) else - + if occursCheck csenv.g r ty then return! ErrorD (ConstraintSolverInfiniteTypes(csenv.eContextInfo, csenv.DisplayEnv, ty1, ty, m, m2)) else // Note: warn _and_ continue! - CheckWarnIfRigid csenv ty1 r ty ++ (fun () -> - + do! CheckWarnIfRigid csenv ty1 r ty // Record the solution before we solve the constraints, since // We may need to make use of the equation when solving the constraints. // Record a entry in the undo trace if one is provided @@ -726,40 +731,39 @@ let rec SolveTyparEqualsType (csenv:ConstraintSolverEnv) ndeep m2 (trace:Optiona (* dprintf "setting typar %d to type %s at %a\n" r.Stamp ((DebugPrint.showType ty)) outputRange m; *) // Only solve constraints if this is not an error var - if r.IsFromError then CompleteD else - + if r.IsFromError then () else // Check to see if this type variable is relevant to any trait constraints. // If so, re-solve the relevant constraints. - (if csenv.SolverState.ExtraCxs.ContainsKey r.Stamp then - RepeatWhileD ndeep (fun ndeep -> SolveRelevantMemberConstraintsForTypar csenv ndeep false trace r) - else - CompleteD) ++ (fun _ -> - + if csenv.SolverState.ExtraCxs.ContainsKey r.Stamp then + do! RepeatWhileD ndeep (fun ndeep -> SolveRelevantMemberConstraintsForTypar csenv ndeep false trace r) // Re-solve the other constraints associated with this type variable - solveTypMeetsTyparConstraints csenv ndeep m2 trace ty r)) + return! solveTypMeetsTyparConstraints csenv ndeep m2 trace ty r - | _ -> failwith "SolveTyparEqualsType") + | _ -> failwith "SolveTyparEqualsType" + } /// Apply the constraints on 'typar' to the type 'ty' -and solveTypMeetsTyparConstraints (csenv:ConstraintSolverEnv) ndeep m2 trace ty (r: Typar) = +and solveTypMeetsTyparConstraints (csenv:ConstraintSolverEnv) ndeep m2 trace ty (r: Typar) = trackErrors { let g = csenv.g // Propagate compat flex requirements from 'tp' to 'ty' - SolveTypIsCompatFlex csenv trace r.IsCompatFlex ty ++ (fun () -> + do! SolveTypIsCompatFlex csenv trace r.IsCompatFlex ty // Propagate dynamic requirements from 'tp' to 'ty' - SolveTypDynamicReq csenv trace r.DynamicReq ty ++ (fun () -> + do! SolveTypDynamicReq csenv trace r.DynamicReq ty // Propagate static requirements from 'tp' to 'ty' - SolveTypStaticReq csenv trace r.StaticReq ty ++ (fun () -> + do! SolveTypStaticReq csenv trace r.StaticReq ty // Solve constraints on 'tp' w.r.t. 'ty' - r.Constraints |> IterateD (function + for e in r.Constraints do + do! + match e with | TyparConstraint.DefaultsTo (priority, dty, m) -> if typeEquiv g ty dty then CompleteD else match tryDestTyparTy g ty with - | None -> CompleteD - | Some destTypar -> + | ValueNone -> CompleteD + | ValueSome destTypar -> AddConstraint csenv ndeep m2 trace destTypar (TyparConstraint.DefaultsTo(priority, dty, m)) | TyparConstraint.SupportsNull m2 -> SolveTypeSupportsNull csenv ndeep m2 trace ty @@ -774,10 +778,18 @@ and solveTypMeetsTyparConstraints (csenv:ConstraintSolverEnv) ndeep m2 trace ty | TyparConstraint.SimpleChoice(tys, m2) -> SolveTypeChoice csenv ndeep m2 trace ty tys | TyparConstraint.CoercesTo(ty2, m2) -> SolveTypeSubsumesTypeKeepAbbrevs csenv ndeep m2 trace None ty2 ty | TyparConstraint.MayResolveMember(traitInfo, m2) -> - SolveMemberConstraint csenv false false ndeep m2 trace traitInfo ++ (fun _ -> CompleteD) - )))) + SolveMemberConstraint csenv false false ndeep m2 trace traitInfo |> OperationResult.ignore + } +and SolveAnonInfoEqualsAnonInfo (csenv:ConstraintSolverEnv) m2 (anonInfo1: AnonRecdTypeInfo) (anonInfo2: AnonRecdTypeInfo) = + if evalTupInfoIsStruct anonInfo1.TupInfo <> evalTupInfoIsStruct anonInfo2.TupInfo then ErrorD (ConstraintSolverError(FSComp.SR.tcTupleStructMismatch(), csenv.m,m2)) else + (match anonInfo1.Assembly, anonInfo2.Assembly with + | ccu1, ccu2 -> if not (ccuEq ccu1 ccu2) then ErrorD (ConstraintSolverError(FSComp.SR.tcAnonRecdCcuMismatch(ccu1.AssemblyName, ccu2.AssemblyName), csenv.m,m2)) else ResultD () + ) ++ (fun () -> + if not (anonInfo1.SortedNames = anonInfo2.SortedNames) then ErrorD (ConstraintSolverError(FSComp.SR.tcAnonRecdFieldNameMismatch(sprintf "%A" (Array.toList anonInfo1.SortedNames), sprintf "%A" (Array.toList anonInfo2.SortedNames)), csenv.m,m2)) else + ResultD ()) + /// Add the constraint "ty1 = ty2" to the constraint problem. /// Propagate all effects of adding this constraint, e.g. to solve type variables and SolveTypeEqualsType (csenv:ConstraintSolverEnv) ndeep m2 (trace: OptionalTrace) (cxsln:(TraitConstraintInfo * TraitConstraintSln) option) ty1 ty2 = @@ -818,6 +830,9 @@ and SolveTypeEqualsType (csenv:ConstraintSolverEnv) ndeep m2 (trace: OptionalTra | TType_tuple (tupInfo1, l1) , TType_tuple (tupInfo2, l2) -> if evalTupInfoIsStruct tupInfo1 <> evalTupInfoIsStruct tupInfo2 then ErrorD (ConstraintSolverError(FSComp.SR.tcTupleStructMismatch(), csenv.m, m2)) else SolveTypeEqualsTypeEqns csenv ndeep m2 trace None l1 l2 + | TType_anon (anonInfo1, l1),TType_anon (anonInfo2, l2) -> + SolveAnonInfoEqualsAnonInfo csenv m2 anonInfo1 anonInfo2 ++ (fun () -> + SolveTypeEqualsTypeEqns csenv ndeep m2 trace None l1 l2) | TType_fun (d1, r1) , TType_fun (d2, r2) -> SolveFunTypeEqn csenv ndeep m2 trace None d1 d2 r1 r2 | TType_measure ms1 , TType_measure ms2 -> UnifyMeasures csenv trace ms1 ms2 | TType_forall(tps1, rty1), TType_forall(tps2, rty2) -> @@ -854,9 +869,10 @@ and SolveTypeEqualsTypeEqns csenv ndeep m2 trace cxsln origl1 origl2 = ErrorD(ConstraintSolverTupleDiffLengths(csenv.DisplayEnv, origl1, origl2, csenv.m, m2)) loop origl1 origl2 -and SolveFunTypeEqn csenv ndeep m2 trace cxsln d1 d2 r1 r2 = - SolveTypeEqualsTypeKeepAbbrevsWithCxsln csenv ndeep m2 trace cxsln d1 d2 ++ (fun () -> - SolveTypeEqualsTypeKeepAbbrevsWithCxsln csenv ndeep m2 trace cxsln r1 r2) +and SolveFunTypeEqn csenv ndeep m2 trace cxsln d1 d2 r1 r2 = trackErrors { + do! SolveTypeEqualsTypeKeepAbbrevsWithCxsln csenv ndeep m2 trace cxsln d1 d2 + return! SolveTypeEqualsTypeKeepAbbrevsWithCxsln csenv ndeep m2 trace cxsln r1 r2 + } // ty1: expected // ty2: actual @@ -890,6 +906,9 @@ and SolveTypeSubsumesType (csenv:ConstraintSolverEnv) ndeep m2 (trace: OptionalT | TType_tuple (tupInfo1, l1) , TType_tuple (tupInfo2, l2) -> if evalTupInfoIsStruct tupInfo1 <> evalTupInfoIsStruct tupInfo2 then ErrorD (ConstraintSolverError(FSComp.SR.tcTupleStructMismatch(), csenv.m, m2)) else SolveTypeEqualsTypeEqns csenv ndeep m2 trace cxsln l1 l2 (* nb. can unify since no variance *) + | TType_anon (anonInfo1, l1), TType_anon (anonInfo2, l2) -> + SolveAnonInfoEqualsAnonInfo csenv m2 anonInfo1 anonInfo2 ++ (fun () -> + SolveTypeEqualsTypeEqns csenv ndeep m2 trace cxsln l1 l2) (* nb. can unify since no variance *) | TType_fun (d1, r1) , TType_fun (d2, r2) -> SolveFunTypeEqn csenv ndeep m2 trace cxsln d1 d2 r1 r2 (* nb. can unify since no variance *) | TType_measure ms1, TType_measure ms2 -> UnifyMeasures csenv trace ms1 ms2 @@ -902,13 +921,14 @@ and SolveTypeSubsumesType (csenv:ConstraintSolverEnv) ndeep m2 (trace: OptionalT // Special subsumption rule for byref tags | TType_app (tc1, l1) , TType_app (tc2, l2) when tyconRefEq g tc1 tc2 && g.byref2_tcr.CanDeref && tyconRefEq g g.byref2_tcr tc1 -> match l1, l2 with - | [ h1; tag1 ], [ h2; tag2 ] -> - SolveTypeEqualsType csenv ndeep m2 trace None h1 h2 ++ (fun () -> + | [ h1; tag1 ], [ h2; tag2 ] -> trackErrors { + do! SolveTypeEqualsType csenv ndeep m2 trace None h1 h2 match stripTyEqnsA csenv.g canShortcut tag1, stripTyEqnsA csenv.g canShortcut tag2 with | TType_app(tagc1, []), TType_app(tagc2, []) when (tyconRefEq g tagc2 g.byrefkind_InOut_tcr && - (tyconRefEq g tagc1 g.byrefkind_In_tcr || tyconRefEq g tagc1 g.byrefkind_Out_tcr) ) -> CompleteD - | _ -> SolveTypeEqualsType csenv ndeep m2 trace cxsln tag1 tag2) + (tyconRefEq g tagc1 g.byrefkind_In_tcr || tyconRefEq g tagc1 g.byrefkind_Out_tcr) ) -> () + | _ -> return! SolveTypeEqualsType csenv ndeep m2 trace cxsln tag1 tag2 + } | _ -> SolveTypeEqualsTypeEqns csenv ndeep m2 trace cxsln l1 l2 | TType_app (tc1, l1) , TType_app (tc2, l2) when tyconRefEq g tc1 tc2 -> @@ -988,16 +1008,16 @@ and SolveDimensionlessNumericType (csenv:ConstraintSolverEnv) ndeep m2 trace ty /// We pretend int and other types support a number of operators. In the actual IL for mscorlib they /// don't, however the type-directed static optimization rules in the library code that makes use of this /// will deal with the problem. -and SolveMemberConstraint (csenv:ConstraintSolverEnv) ignoreUnresolvedOverload permitWeakResolution ndeep m2 trace (TTrait(tys, nm, memFlags, argtys, rty, sln)): OperationResult = +and SolveMemberConstraint (csenv:ConstraintSolverEnv) ignoreUnresolvedOverload permitWeakResolution ndeep m2 trace (TTrait(tys, nm, memFlags, argtys, rty, sln)): OperationResult = trackErrors { // Do not re-solve if already solved - if sln.Value.IsSome then ResultD true else + if sln.Value.IsSome then return true else let g = csenv.g let m = csenv.m let amap = csenv.amap let aenv = csenv.EquivEnv let denv = csenv.DisplayEnv let ndeep = ndeep + 1 - DepthCheck ndeep m ++ (fun () -> + do! DepthCheck ndeep m // Remove duplicates from the set of types in the support let tys = ListSet.setify (typeAEquiv g aenv) tys @@ -1008,19 +1028,19 @@ and SolveMemberConstraint (csenv:ConstraintSolverEnv) ignoreUnresolvedOverload p // Assert the object type if the constraint is for an instance member if memFlags.IsInstance then match tys, argtys with - | [ty], (h :: _) -> SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace h ty - | _ -> ErrorD (ConstraintSolverError(FSComp.SR.csExpectedArguments(), m, m2)) - else CompleteD - ++ (fun () -> - + | [ty], (h :: _) -> do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace h ty + | _ -> do! ErrorD (ConstraintSolverError(FSComp.SR.csExpectedArguments(), m, m2)) // Trait calls are only supported on pseudo type (variables) - tys |> IterateD (SolveTypStaticReq csenv trace HeadTypeStaticReq)) ++ (fun () -> + for e in tys do + do! SolveTypStaticReq csenv trace HeadTypeStaticReq e let argtys = if memFlags.IsInstance then List.tail argtys else argtys let minfos = GetRelevantMethodsForTrait csenv permitWeakResolution nm traitInfo - match minfos, tys, memFlags.IsInstance, nm, argtys with + let! res = + trackErrors { + match minfos, tys, memFlags.IsInstance, nm, argtys with | _, _, false, ("op_Division" | "op_Multiply"), [argty1;argty2] when // This simulates the existence of @@ -1063,153 +1083,155 @@ and SolveMemberConstraint (csenv:ConstraintSolverEnv) ignoreUnresolvedOverload p checkRuleAppliesInPreferenceToMethods argty2 argty1) -> match GetMeasureOfType g argty1 with - | Some (tcref, ms1) -> + | Some (tcref, ms1) -> let ms2 = freshMeasure () - SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace argty2 (mkAppTy tcref [TType_measure ms2]) ++ (fun () -> - SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace rty (mkAppTy tcref [TType_measure (Measure.Prod(ms1, if nm = "op_Multiply" then ms2 else Measure.Inv ms2))]) ++ (fun () -> - ResultD TTraitBuiltIn)) + do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace argty2 (mkAppTy tcref [TType_measure ms2]) + do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace rty (mkAppTy tcref [TType_measure (Measure.Prod(ms1, if nm = "op_Multiply" then ms2 else Measure.Inv ms2))]) + return TTraitBuiltIn | _ -> match GetMeasureOfType g argty2 with - | Some (tcref, ms2) -> + | Some (tcref, ms2) -> let ms1 = freshMeasure () - SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace argty1 (mkAppTy tcref [TType_measure ms1]) ++ (fun () -> - SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace rty (mkAppTy tcref [TType_measure (Measure.Prod(ms1, if nm = "op_Multiply" then ms2 else Measure.Inv ms2))]) ++ (fun () -> - ResultD TTraitBuiltIn)) - | _ -> - SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace argty2 argty1 ++ (fun () -> - SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace rty argty1 ++ (fun () -> - ResultD TTraitBuiltIn)) + do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace argty1 (mkAppTy tcref [TType_measure ms1]) + do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace rty (mkAppTy tcref [TType_measure (Measure.Prod(ms1, if nm = "op_Multiply" then ms2 else Measure.Inv ms2))]) + return TTraitBuiltIn + | _ -> + do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace argty2 argty1 + do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace rty argty1 + return TTraitBuiltIn | _, _, false, ("op_Addition" | "op_Subtraction" | "op_Modulus"), [argty1;argty2] when // Ignore any explicit +/- overloads from any basic integral types (minfos |> List.forall (fun minfo -> isIntegerTy g minfo.ApparentEnclosingType ) && ( (IsNumericOrIntegralEnumType g argty1 || (nm = "op_Addition" && (isCharTy g argty1 || isStringTy g argty1))) && (permitWeakResolution || not (isTyparTy g argty2)) - || (IsNumericOrIntegralEnumType g argty2 || (nm = "op_Addition" && (isCharTy g argty2 || isStringTy g argty2))) && (permitWeakResolution || not (isTyparTy g argty1)))) -> - SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace argty2 argty1 ++ (fun () -> - SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace rty argty1 ++ (fun () -> - ResultD TTraitBuiltIn)) + || (IsNumericOrIntegralEnumType g argty2 || (nm = "op_Addition" && (isCharTy g argty2 || isStringTy g argty2))) && (permitWeakResolution || not (isTyparTy g argty1)))) -> + do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace argty2 argty1 + do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace rty argty1 + return TTraitBuiltIn | _, _, false, ("op_LessThan" | "op_LessThanOrEqual" | "op_GreaterThan" | "op_GreaterThanOrEqual" | "op_Equality" | "op_Inequality" ), [argty1;argty2] when // Ignore any explicit overloads from any basic integral types (minfos |> List.forall (fun minfo -> isIntegerTy g minfo.ApparentEnclosingType ) && ( (IsRelationalType g argty1 && (permitWeakResolution || not (isTyparTy g argty2))) - || (IsRelationalType g argty2 && (permitWeakResolution || not (isTyparTy g argty1))))) -> - SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace argty2 argty1 ++ (fun () -> - SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace rty g.bool_ty ++ (fun () -> - ResultD TTraitBuiltIn)) + || (IsRelationalType g argty2 && (permitWeakResolution || not (isTyparTy g argty1))))) -> + do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace argty2 argty1 + do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace rty g.bool_ty + return TTraitBuiltIn // We pretend for uniformity that the numeric types have a static property called Zero and One // As with constants, only zero is polymorphic in its units | [], [ty], false, "get_Zero", [] - when IsNumericType g ty -> - SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace rty ty ++ (fun () -> - ResultD TTraitBuiltIn) + when IsNumericType g ty -> + do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace rty ty + return TTraitBuiltIn | [], [ty], false, "get_One", [] - when IsNumericType g ty || isCharTy g ty -> - SolveDimensionlessNumericType csenv ndeep m2 trace ty ++ (fun () -> - SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace rty ty ++ (fun () -> - ResultD TTraitBuiltIn)) + when IsNumericType g ty || isCharTy g ty -> + do! SolveDimensionlessNumericType csenv ndeep m2 trace ty + do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace rty ty + return TTraitBuiltIn | [], _, false, ("DivideByInt"), [argty1;argty2] - when isFpTy g argty1 || isDecimalTy g argty1 -> - SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace argty2 g.int_ty ++ (fun () -> - SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace rty argty1 ++ (fun () -> - ResultD TTraitBuiltIn)) + when isFpTy g argty1 || isDecimalTy g argty1 -> + do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace argty2 g.int_ty + do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace rty argty1 + return TTraitBuiltIn // We pretend for uniformity that the 'string' and 'array' types have an indexer property called 'Item' | [], [ty], true, ("get_Item"), [argty1] - when isStringTy g ty -> + when isStringTy g ty -> - SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace argty1 g.int_ty ++ (fun () -> - SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace rty g.char_ty ++ (fun () -> - ResultD TTraitBuiltIn)) + do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace argty1 g.int_ty + do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace rty g.char_ty + return TTraitBuiltIn | [], [ty], true, ("get_Item"), argtys - when isArrayTy g ty -> + when isArrayTy g ty -> - (if rankOfArrayTy g ty <> argtys.Length then ErrorD(ConstraintSolverError(FSComp.SR.csIndexArgumentMismatch((rankOfArrayTy g ty), argtys.Length), m, m2)) else CompleteD) ++ (fun () -> - (argtys |> IterateD (fun argty -> SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace argty g.int_ty)) ++ (fun () -> + if rankOfArrayTy g ty <> argtys.Length then do! ErrorD(ConstraintSolverError(FSComp.SR.csIndexArgumentMismatch((rankOfArrayTy g ty), argtys.Length), m, m2)) + for argty in argtys do + do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace argty g.int_ty let ety = destArrayTy g ty - SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace rty ety ++ (fun () -> - ResultD TTraitBuiltIn))) + do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace rty ety + return TTraitBuiltIn | [], [ty], true, ("set_Item"), argtys - when isArrayTy g ty -> + when isArrayTy g ty -> - (if rankOfArrayTy g ty <> argtys.Length - 1 then ErrorD(ConstraintSolverError(FSComp.SR.csIndexArgumentMismatch((rankOfArrayTy g ty), (argtys.Length - 1)), m, m2)) else CompleteD) ++ (fun () -> + if rankOfArrayTy g ty <> argtys.Length - 1 then do! ErrorD(ConstraintSolverError(FSComp.SR.csIndexArgumentMismatch((rankOfArrayTy g ty), (argtys.Length - 1)), m, m2)) let argtys, ety = List.frontAndBack argtys - (argtys |> IterateD (fun argty -> SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace argty g.int_ty)) ++ (fun () -> + for argty in argtys do + do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace argty g.int_ty let etys = destArrayTy g ty - SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace ety etys ++ (fun () -> - ResultD TTraitBuiltIn))) + do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace ety etys + return TTraitBuiltIn | [], _, false, ("op_BitwiseAnd" | "op_BitwiseOr" | "op_ExclusiveOr"), [argty1;argty2] when (isIntegerOrIntegerEnumTy g argty1 || (isEnumTy g argty1)) && (permitWeakResolution || not (isTyparTy g argty2)) - || (isIntegerOrIntegerEnumTy g argty2 || (isEnumTy g argty2)) && (permitWeakResolution || not (isTyparTy g argty1)) -> + || (isIntegerOrIntegerEnumTy g argty2 || (isEnumTy g argty2)) && (permitWeakResolution || not (isTyparTy g argty1)) -> - SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace argty2 argty1 ++ (fun () -> - SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace rty argty1 ++ (fun () -> - SolveDimensionlessNumericType csenv ndeep m2 trace argty1 ++ (fun () -> - ResultD TTraitBuiltIn))); + do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace argty2 argty1 + do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace rty argty1 + do! SolveDimensionlessNumericType csenv ndeep m2 trace argty1 + return TTraitBuiltIn | [], _, false, ("op_LeftShift" | "op_RightShift"), [argty1;argty2] - when isIntegerOrIntegerEnumTy g argty1 -> + when isIntegerOrIntegerEnumTy g argty1 -> - SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace argty2 g.int_ty ++ (fun () -> - SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace rty argty1 ++ (fun () -> - SolveDimensionlessNumericType csenv ndeep m2 trace argty1 ++ (fun () -> - ResultD TTraitBuiltIn))) + do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace argty2 g.int_ty + do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace rty argty1 + do! SolveDimensionlessNumericType csenv ndeep m2 trace argty1 + return TTraitBuiltIn | _, _, false, ("op_UnaryPlus"), [argty] - when IsNumericOrIntegralEnumType g argty -> + when IsNumericOrIntegralEnumType g argty -> - SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace rty argty ++ (fun () -> - ResultD TTraitBuiltIn) + do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace rty argty + return TTraitBuiltIn | _, _, false, ("op_UnaryNegation"), [argty] - when isSignedIntegerTy g argty || isFpTy g argty || isDecimalTy g argty -> + when isSignedIntegerTy g argty || isFpTy g argty || isDecimalTy g argty -> - SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace rty argty ++ (fun () -> - ResultD TTraitBuiltIn) + do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace rty argty + return TTraitBuiltIn | _, _, true, ("get_Sign"), [] - when (let argty = tys.Head in isSignedIntegerTy g argty || isFpTy g argty || isDecimalTy g argty) -> + when (let argty = tys.Head in isSignedIntegerTy g argty || isFpTy g argty || isDecimalTy g argty) -> - SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace rty g.int32_ty ++ (fun () -> - ResultD TTraitBuiltIn) + do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace rty g.int32_ty + return TTraitBuiltIn | _, _, false, ("op_LogicalNot" | "op_OnesComplement"), [argty] - when isIntegerOrIntegerEnumTy g argty -> + when isIntegerOrIntegerEnumTy g argty -> - SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace rty argty ++ (fun () -> - SolveDimensionlessNumericType csenv ndeep m2 trace argty ++ (fun () -> - ResultD TTraitBuiltIn)) + do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace rty argty + do! SolveDimensionlessNumericType csenv ndeep m2 trace argty + return TTraitBuiltIn | _, _, false, ("Abs"), [argty] - when isSignedIntegerTy g argty || isFpTy g argty || isDecimalTy g argty -> + when isSignedIntegerTy g argty || isFpTy g argty || isDecimalTy g argty -> - SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace rty argty ++ (fun () -> - ResultD TTraitBuiltIn) + do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace rty argty + return TTraitBuiltIn | _, _, false, "Sqrt", [argty1] when isFpTy g argty1 -> match GetMeasureOfType g argty1 with - | Some (tcref, _) -> + | Some (tcref, _) -> let ms1 = freshMeasure () - SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace argty1 (mkAppTy tcref [TType_measure (Measure.Prod (ms1, ms1))]) ++ (fun () -> - SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace rty (mkAppTy tcref [TType_measure ms1]) ++ (fun () -> - ResultD TTraitBuiltIn)) - | None -> - SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace rty argty1 ++ (fun () -> - ResultD TTraitBuiltIn) + do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace argty1 (mkAppTy tcref [TType_measure (Measure.Prod (ms1, ms1))]) + do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace rty (mkAppTy tcref [TType_measure ms1]) + return TTraitBuiltIn + | None -> + do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace rty argty1 + return TTraitBuiltIn | _, _, false, ("Sin" | "Cos" | "Tan" | "Sinh" | "Cosh" | "Tanh" | "Atan" | "Acos" | "Asin" | "Exp" | "Ceiling" | "Floor" | "Round" | "Truncate" | "Log10" | "Log" | "Sqrt"), [argty] - when isFpTy g argty -> + when isFpTy g argty -> - SolveDimensionlessNumericType csenv ndeep m2 trace argty ++ (fun () -> - SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace rty argty ++ (fun () -> - ResultD TTraitBuiltIn)) + do! SolveDimensionlessNumericType csenv ndeep m2 trace argty + do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace rty argty + return TTraitBuiltIn | _, _, false, ("op_Explicit"), [argty] when (// The input type. @@ -1221,7 +1243,7 @@ and SolveMemberConstraint (csenv:ConstraintSolverEnv) ignoreUnresolvedOverload p // Exclusion: No conversion from char to decimal not (isCharTy g argty && isDecimalTy g rty)) -> - ResultD TTraitBuiltIn + return TTraitBuiltIn | _, _, false, ("op_Explicit"), [argty] @@ -1230,23 +1252,23 @@ and SolveMemberConstraint (csenv:ConstraintSolverEnv) ignoreUnresolvedOverload p // The output type (isDecimalTy g rty)) -> - ResultD TTraitBuiltIn + return TTraitBuiltIn | [], _, false, "Pow", [argty1; argty2] - when isFpTy g argty1 -> + when isFpTy g argty1 -> - SolveDimensionlessNumericType csenv ndeep m2 trace argty1 ++ (fun () -> - SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace argty2 argty1 ++ (fun () -> - SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace rty argty1 ++ (fun () -> - ResultD TTraitBuiltIn))) + do! SolveDimensionlessNumericType csenv ndeep m2 trace argty1 + do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace argty2 argty1 + do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace rty argty1 + return TTraitBuiltIn | _, _, false, ("Atan2"), [argty1; argty2] - when isFpTy g argty1 -> - SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace argty2 argty1 ++ (fun () -> + when isFpTy g argty1 -> + do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace argty2 argty1 match GetMeasureOfType g argty1 with - | None -> SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace rty argty1 - | Some (tcref, _) -> SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace rty (mkAppTy tcref [TType_measure Measure.One])) ++ (fun () -> - ResultD TTraitBuiltIn) + | None -> do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace rty argty1 + | Some (tcref, _) -> do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace rty (mkAppTy tcref [TType_measure Measure.One]) + return TTraitBuiltIn | _ -> // OK, this is not solved by a built-in constraint. @@ -1275,16 +1297,31 @@ and SolveMemberConstraint (csenv:ConstraintSolverEnv) ignoreUnresolvedOverload p else None + let anonRecdPropSearch = + let isGetProp = nm.StartsWith "get_" + if isGetProp && memFlags.IsInstance then + let propName = nm.[4..] + let props = + tys |> List.choose (fun ty -> + match NameResolution.TryFindAnonRecdFieldOfType g ty propName with + | Some (NameResolution.Item.AnonRecdField(anonInfo, tinst, i, _)) -> Some (anonInfo, tinst, i) + | _ -> None) + match props with + | [ prop ] -> Some prop + | _ -> None + else + None + // Now check if there are no feasible solutions at all - match minfos, recdPropSearch with - | [], None when not (tys |> List.exists (isAnyParTy g)) -> + match minfos, recdPropSearch, anonRecdPropSearch with + | [], None, None when not (tys |> List.exists (isAnyParTy g)) -> if tys |> List.exists (isFunTy g) then - ErrorD (ConstraintSolverError(FSComp.SR.csExpectTypeWithOperatorButGivenFunction(DecompileOpName nm), m, m2)) + return! ErrorD (ConstraintSolverError(FSComp.SR.csExpectTypeWithOperatorButGivenFunction(DecompileOpName nm), m, m2)) elif tys |> List.exists (isAnyTupleTy g) then - ErrorD (ConstraintSolverError(FSComp.SR.csExpectTypeWithOperatorButGivenTuple(DecompileOpName nm), m, m2)) + return! ErrorD (ConstraintSolverError(FSComp.SR.csExpectTypeWithOperatorButGivenTuple(DecompileOpName nm), m, m2)) else match nm, argtys with - | "op_Explicit", [argty] -> ErrorD (ConstraintSolverError(FSComp.SR.csTypeDoesNotSupportConversion((NicePrint.prettyStringOfTy denv argty), (NicePrint.prettyStringOfTy denv rty)), m, m2)) + | "op_Explicit", [argty] -> return! ErrorD (ConstraintSolverError(FSComp.SR.csTypeDoesNotSupportConversion((NicePrint.prettyStringOfTy denv argty), (NicePrint.prettyStringOfTy denv rty)), m, m2)) | _ -> let tyString = match tys with @@ -1301,10 +1338,9 @@ and SolveMemberConstraint (csenv:ConstraintSolverEnv) ignoreUnresolvedOverload p | _ -> if tys.Length = 1 then FSComp.SR.csTypeDoesNotSupportOperator(tyString, opName) else FSComp.SR.csTypesDoNotSupportOperator(tyString, opName) - ErrorD(ConstraintSolverError(err, m, m2)) + return! ErrorD(ConstraintSolverError(err, m, m2)) | _ -> - let dummyExpr = mkUnit g m let calledMethGroup = minfos @@ -1319,42 +1355,49 @@ and SolveMemberConstraint (csenv:ConstraintSolverEnv) ignoreUnresolvedOverload p let methOverloadResult, errors = trace.CollectThenUndoOrCommit (fun (a, _) -> Option.isSome a) (fun trace -> ResolveOverloading csenv (WithTrace trace) nm ndeep (Some traitInfo) (0, 0) AccessibleFromEverywhere calledMethGroup false (Some rty)) - match recdPropSearch, methOverloadResult with - | Some (rfinfo, isSetProp), None -> + match anonRecdPropSearch, recdPropSearch, methOverloadResult with + | Some (anonInfo, tinst, i), None, None -> + // OK, the constraint is solved by a record property. Assert that the return types match. + let rty2 = List.item i tinst + do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace rty rty2 + return TTraitSolvedAnonRecdProp(anonInfo, tinst, i) + + | None, Some (rfinfo, isSetProp), None -> // OK, the constraint is solved by a record property. Assert that the return types match. let rty2 = if isSetProp then g.unit_ty else rfinfo.FieldType - SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace rty rty2 ++ (fun () -> - ResultD (TTraitSolvedRecdProp(rfinfo, isSetProp))) - | None, Some (calledMeth:CalledMeth<_>) -> + do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace rty rty2 + return TTraitSolvedRecdProp(rfinfo, isSetProp) + + | None, None, Some (calledMeth:CalledMeth<_>) -> // OK, the constraint is solved. let minfo = calledMeth.Method - errors ++ (fun () -> - let isInstance = minfo.IsInstance - if isInstance <> memFlags.IsInstance then + do! errors + let isInstance = minfo.IsInstance + if isInstance <> memFlags.IsInstance then + return! if isInstance then ErrorD(ConstraintSolverError(FSComp.SR.csMethodFoundButIsNotStatic((NicePrint.minimalStringOfType denv minfo.ApparentEnclosingType), (DecompileOpName nm), nm), m, m2 )) else ErrorD(ConstraintSolverError(FSComp.SR.csMethodFoundButIsStatic((NicePrint.minimalStringOfType denv minfo.ApparentEnclosingType), (DecompileOpName nm), nm), m, m2 )) - else - CheckMethInfoAttributes g m None minfo ++ (fun () -> - ResultD (TTraitSolved (minfo, calledMeth.CalledTyArgs)))) + else + do! CheckMethInfoAttributes g m None minfo + return TTraitSolved (minfo, calledMeth.CalledTyArgs) - | _ -> + | _ -> let support = GetSupportOfMemberConstraint csenv traitInfo let frees = GetFreeTyparsOfMemberConstraint csenv traitInfo - // If there's nothing left to learn then raise the errors - (if (permitWeakResolution && isNil support) || isNil frees then errors - // Otherwise re-record the trait waiting for canonicalization - else AddMemberConstraint csenv ndeep m2 trace traitInfo support frees) ++ (fun () -> + if (permitWeakResolution && isNil support) || isNil frees then do! errors + // Otherwise re-record the trait waiting for canonicalization + else do! AddMemberConstraint csenv ndeep m2 trace traitInfo support frees + return! match errors with | ErrorResult (_, UnresolvedOverloading _) when not ignoreUnresolvedOverload && (not (nm = "op_Explicit" || nm = "op_Implicit")) -> ErrorD LocallyAbortOperationThatFailsToResolveOverload - | _ -> ResultD TTraitUnsolved) - ) - ++ - (fun res -> RecordMemberConstraintSolution csenv.SolverState m trace traitInfo res)) - + | _ -> ResultD TTraitUnsolved + } + return! RecordMemberConstraintSolution csenv.SolverState m trace traitInfo res + } /// Record the solution to a member constraint in the mutable reference cell attached to /// each member constraint. @@ -1372,8 +1415,13 @@ and RecordMemberConstraintSolution css m trace traitInfo res = TransactMemberConstraintSolution traitInfo trace BuiltInSln; ResultD true - | TTraitSolvedRecdProp (rfinfo, isSetProp) -> - let sln = MemberConstraintSolutionOfRecdFieldInfo rfinfo isSetProp + | TTraitSolvedRecdProp (rfinfo, isSet) -> + let sln = FSRecdFieldSln(rfinfo.TypeInst,rfinfo.RecdFieldRef,isSet) + TransactMemberConstraintSolution traitInfo trace sln; + ResultD true + + | TTraitSolvedAnonRecdProp (anonInfo, tinst, i) -> + let sln = FSAnonRecdFieldSln(anonInfo, tinst, i) TransactMemberConstraintSolution traitInfo trace sln; ResultD true @@ -1418,9 +1466,6 @@ and MemberConstraintSolutionOfMethInfo css m minfo minst = #endif -and MemberConstraintSolutionOfRecdFieldInfo rfinfo isSet = - FSRecdFieldSln(rfinfo.TypeInst, rfinfo.RecdFieldRef, isSet) - /// Write into the reference cell stored in the TAST and add to the undo trace if necessary and TransactMemberConstraintSolution traitInfo (trace:OptionalTrace) sln = let prev = traitInfo.Solution @@ -1446,7 +1491,14 @@ and GetRelevantMethodsForTrait (csenv:ConstraintSolverEnv) permitWeakResolution /// to a generic instantiation for an operator based on the right hand type. let minfos = List.reduce (ListSet.unionFavourLeft MethInfo.MethInfosUseIdenticalDefinitions) minfos + + /// Check that the available members aren't hiding a member from the parent (depth 1 only) + let relevantMinfos = minfos |> List.filter(fun minfo -> not minfo.IsDispatchSlot && not minfo.IsVirtual && minfo.IsInstance) minfos + |> List.filter(fun minfo1 -> + not(minfo1.IsDispatchSlot && + relevantMinfos + |> List.exists (fun minfo2 -> MethInfosEquivByNameAndSig EraseAll true csenv.g csenv.amap m minfo2 minfo1))) else [] // The trait name "op_Explicit" also covers "op_Implicit", so look for that one too. @@ -1458,7 +1510,7 @@ and GetRelevantMethodsForTrait (csenv:ConstraintSolverEnv) permitWeakResolution /// The nominal support of the member constraint and GetSupportOfMemberConstraint (csenv:ConstraintSolverEnv) (TTrait(tys, _, _, _, _, _)) = - tys |> List.choose (tryAnyParTy csenv.g) + tys |> List.choose (tryAnyParTyOption csenv.g) /// All the typars relevant to the member constraint *) and GetFreeTyparsOfMemberConstraint (csenv:ConstraintSolverEnv) (TTrait(tys, _, _, argtys, rty, _)) = @@ -1475,9 +1527,9 @@ and SolveRelevantMemberConstraints (csenv:ConstraintSolverEnv) ndeep permitWeakR /// Normalize the typar let ty = mkTyparTy tp match tryAnyParTy csenv.g ty with - | Some tp -> + | ValueSome tp -> SolveRelevantMemberConstraintsForTypar csenv ndeep permitWeakResolution trace tp - | None -> + | ValueNone -> ResultD false)) and SolveRelevantMemberConstraintsForTypar (csenv:ConstraintSolverEnv) ndeep permitWeakResolution (trace:OptionalTrace) tp = @@ -1518,7 +1570,10 @@ and AddMemberConstraint (csenv:ConstraintSolverEnv) ndeep m2 trace traitInfo sup // Associate the constraint with each type variable in the support, so if the type variable // gets generalized then this constraint is attached at the binding site. - support |> IterateD (fun tp -> AddConstraint csenv ndeep m2 trace tp (TyparConstraint.MayResolveMember(traitInfo, m2))) + trackErrors { + for tp in support do + do! AddConstraint csenv ndeep m2 trace tp (TyparConstraint.MayResolveMember(traitInfo, m2)) + } /// Record a constraint on an inference type variable. @@ -1548,9 +1603,11 @@ and AddConstraint (csenv:ConstraintSolverEnv) ndeep m2 trace tp newConstraint = let rty1 = GetFSharpViewOfReturnType g rty1 let rty2 = GetFSharpViewOfReturnType g rty2 - Iterate2D (SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace) argtys1 argtys2 ++ (fun () -> - SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace rty1 rty2 ++ (fun () -> - CompleteD)) + trackErrors { + do! Iterate2D (SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace) argtys1 argtys2 + do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace rty1 rty2 + () + } | (TyparConstraint.CoercesTo(ty1, _), TyparConstraint.CoercesTo(ty2, _)) -> @@ -1564,19 +1621,22 @@ and AddConstraint (csenv:ConstraintSolverEnv) ndeep m2 trace tp newConstraint = List.rev !res let parents1 = collect ty1 let parents2 = collect ty2 - parents1 |> IterateD (fun ty1Parent -> - parents2 |> IterateD (fun ty2Parent -> - if not (HaveSameHeadType g ty1Parent ty2Parent) then CompleteD else - SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace ty1Parent ty2Parent)) + trackErrors { + for ty1Parent in parents1 do + for ty2Parent in parents2 do + do! if not (HaveSameHeadType g ty1Parent ty2Parent) then CompleteD else + SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace ty1Parent ty2Parent + } | (TyparConstraint.IsEnum (u1, _), TyparConstraint.IsEnum (u2, m2)) -> SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace u1 u2 | (TyparConstraint.IsDelegate (aty1, bty1, _), - TyparConstraint.IsDelegate (aty2, bty2, m2)) -> - SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace aty1 aty2 ++ (fun () -> - SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace bty1 bty2) + TyparConstraint.IsDelegate (aty2, bty2, m2)) -> trackErrors { + do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace aty1 aty2 + return! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace bty1 bty2 + } | TyparConstraint.SupportsComparison _, TyparConstraint.IsDelegate _ | TyparConstraint.IsDelegate _ , TyparConstraint.SupportsComparison _ @@ -1635,36 +1695,34 @@ and AddConstraint (csenv:ConstraintSolverEnv) ndeep m2 trace tp newConstraint = let existingConstraints = tp.Constraints let allCxs = newConstraint :: List.rev existingConstraints - begin + trackErrors { let rec enforceMutualConsistency i cxs = match cxs with | [] -> CompleteD - | cx :: rest -> IterateIdxD (fun j cx2 -> if i = j then CompleteD else consistent cx cx2) allCxs ++ (fun () -> enforceMutualConsistency (i+1) rest) - - enforceMutualConsistency 0 allCxs - end ++ (fun () -> + | cx :: rest -> + trackErrors { + do! IterateIdxD (fun j cx2 -> if i = j then CompleteD else consistent cx cx2) allCxs + return! enforceMutualConsistency (i+1) rest + } + do! enforceMutualConsistency 0 allCxs - let impliedByExistingConstraints = existingConstraints |> List.exists (fun tpc2 -> implies tpc2 newConstraint) + let impliedByExistingConstraints = existingConstraints |> List.exists (fun tpc2 -> implies tpc2 newConstraint) - if impliedByExistingConstraints then - CompleteD - // "Default" constraints propagate softly and can be omitted from explicit declarations of type parameters - elif (match tp.Rigidity, newConstraint with - | (TyparRigidity.Rigid | TyparRigidity.WillBeRigid), TyparConstraint.DefaultsTo _ -> true - | _ -> false) then - CompleteD - elif tp.Rigidity = TyparRigidity.Rigid then - ErrorD (ConstraintSolverMissingConstraint(denv, tp, newConstraint, m, m2)) - else - (// It is important that we give a warning if a constraint is missing from a + if impliedByExistingConstraints then () + // "Default" constraints propagate softly and can be omitted from explicit declarations of type parameters + elif (match tp.Rigidity, newConstraint with + | (TyparRigidity.Rigid | TyparRigidity.WillBeRigid), TyparConstraint.DefaultsTo _ -> true + | _ -> false) then + () + elif tp.Rigidity = TyparRigidity.Rigid then + return! ErrorD (ConstraintSolverMissingConstraint(denv, tp, newConstraint, m, m2)) + else + // It is important that we give a warning if a constraint is missing from a // will-be-made-rigid type variable. This is because the existence of these warnings // is relevant to the overload resolution rules (see 'candidateWarnCount' in the overload resolution // implementation). See also FSharp 1.0 bug 5461 - (if tp.Rigidity.WarnIfMissingConstraint then - WarnD (ConstraintSolverMissingConstraint(denv, tp, newConstraint, m, m2)) - else - CompleteD) ++ (fun () -> - + if tp.Rigidity.WarnIfMissingConstraint then + do! WarnD (ConstraintSolverMissingConstraint(denv, tp, newConstraint, m, m2)) let newConstraints = // Eliminate any constraints where one constraint implies another // Keep constraints in the left-to-right form according to the order they are asserted. @@ -1676,23 +1734,23 @@ and AddConstraint (csenv:ConstraintSolverEnv) ndeep m2 trace tp newConstraint = eliminateRedundant rest (if List.exists (fun cx2 -> implies cx2 cx) acc then acc else (cx::acc)) eliminateRedundant allCxs [] - // Write the constraint into the type variable // Record a entry in the undo trace if one is provided let orig = tp.Constraints trace.Exec (fun () -> tp.SetConstraints newConstraints) (fun () -> tp.SetConstraints orig) + () + } - CompleteD))) and SolveTypeSupportsNull (csenv:ConstraintSolverEnv) ndeep m2 trace ty = let g = csenv.g let m = csenv.m let denv = csenv.DisplayEnv match tryDestTyparTy g ty with - | Some destTypar -> + | ValueSome destTypar -> AddConstraint csenv ndeep m2 trace destTypar (TyparConstraint.SupportsNull m) - | None -> + | ValueNone -> if TypeSatisfiesNullConstraint g m ty then CompleteD else match ty with | NullableTy g _ -> @@ -1706,12 +1764,12 @@ and SolveTypeSupportsComparison (csenv:ConstraintSolverEnv) ndeep m2 trace ty = let amap = csenv.amap let denv = csenv.DisplayEnv match tryDestTyparTy g ty with - | Some destTypar -> + | ValueSome destTypar -> AddConstraint csenv ndeep m2 trace destTypar (TyparConstraint.SupportsComparison m) - | None -> + | ValueNone -> // Check it isn't ruled out by the user match tryDestAppTy g ty with - | Some tcref when HasFSharpAttribute g g.attrib_NoComparisonAttribute tcref.Attribs -> + | ValueSome tcref when HasFSharpAttribute g g.attrib_NoComparisonAttribute tcref.Attribs -> ErrorD (ConstraintSolverError(FSComp.SR.csTypeDoesNotSupportComparison1(NicePrint.minimalStringOfType denv ty), m, m2)) | _ -> match ty with @@ -1750,11 +1808,11 @@ and SolveTypeSupportsEquality (csenv:ConstraintSolverEnv) ndeep m2 trace ty = let m = csenv.m let denv = csenv.DisplayEnv match tryDestTyparTy g ty with - | Some destTypar -> + | ValueSome destTypar -> AddConstraint csenv ndeep m2 trace destTypar (TyparConstraint.SupportsEquality m) - | None -> + | _ -> match tryDestAppTy g ty with - | Some tcref when HasFSharpAttribute g g.attrib_NoEqualityAttribute tcref.Attribs -> + | ValueSome tcref when HasFSharpAttribute g g.attrib_NoEqualityAttribute tcref.Attribs -> ErrorD (ConstraintSolverError(FSComp.SR.csTypeDoesNotSupportEquality1(NicePrint.minimalStringOfType denv ty), m, m2)) | _ -> match ty with @@ -1787,9 +1845,9 @@ and SolveTypeIsEnum (csenv:ConstraintSolverEnv) ndeep m2 trace ty underlying = let m = csenv.m let denv = csenv.DisplayEnv match tryDestTyparTy g ty with - | Some destTypar -> + | ValueSome destTypar -> return! AddConstraint csenv ndeep m2 trace destTypar (TyparConstraint.IsEnum(underlying, m)) - | None -> + | _ -> if isEnumTy g ty then do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace underlying (underlyingTypeOfEnumTy g ty) return! CompleteD @@ -1803,9 +1861,9 @@ and SolveTypeIsDelegate (csenv:ConstraintSolverEnv) ndeep m2 trace ty aty bty = let m = csenv.m let denv = csenv.DisplayEnv match tryDestTyparTy g ty with - | Some destTypar -> + | ValueSome destTypar -> return! AddConstraint csenv ndeep m2 trace destTypar (TyparConstraint.IsDelegate(aty, bty, m)) - | None -> + | _ -> if isDelegateTy g ty then match TryDestStandardDelegateType csenv.InfoReader m AccessibleFromSomewhere ty with | Some (tupledArgTy, rty) -> @@ -1823,9 +1881,9 @@ and SolveTypeIsNonNullableValueType (csenv:ConstraintSolverEnv) ndeep m2 trace t let m = csenv.m let denv = csenv.DisplayEnv match tryDestTyparTy g ty with - | Some destTypar -> + | ValueSome destTypar -> return! AddConstraint csenv ndeep m2 trace destTypar (TyparConstraint.IsNonNullableStruct m) - | None -> + | _ -> let underlyingTy = stripTyEqnsAndMeasureEqns g ty if isStructTy g underlyingTy then if tyconRefEq g g.system_Nullable_tcref (tcrefOfAppTy g underlyingTy) then @@ -1839,9 +1897,9 @@ and SolveTypeIsUnmanaged (csenv:ConstraintSolverEnv) ndeep m2 trace ty = let m = csenv.m let denv = csenv.DisplayEnv match tryDestTyparTy g ty with - | Some destTypar -> + | ValueSome destTypar -> AddConstraint csenv ndeep m2 trace destTypar (TyparConstraint.IsUnmanaged m) - | None -> + | _ -> if isUnmanagedTy g ty then CompleteD else @@ -1853,9 +1911,9 @@ and SolveTypeChoice (csenv:ConstraintSolverEnv) ndeep m2 trace ty tys = let m = csenv.m let denv = csenv.DisplayEnv match tryDestTyparTy g ty with - | Some destTypar -> + | ValueSome destTypar -> AddConstraint csenv ndeep m2 trace destTypar (TyparConstraint.SimpleChoice(tys, m)) - | None -> + | _ -> if List.exists (typeEquivAux Erasure.EraseMeasures g ty) tys then CompleteD else ErrorD (ConstraintSolverError(FSComp.SR.csTypeNotCompatibleBecauseOfPrintf((NicePrint.minimalStringOfType denv ty), (String.concat "," (List.map (NicePrint.prettyStringOfTy denv) tys))), m, m2)) @@ -1865,9 +1923,9 @@ and SolveTypeIsReferenceType (csenv:ConstraintSolverEnv) ndeep m2 trace ty = let m = csenv.m let denv = csenv.DisplayEnv match tryDestTyparTy g ty with - | Some destTypar -> + | ValueSome destTypar -> AddConstraint csenv ndeep m2 trace destTypar (TyparConstraint.IsReferenceType m) - | None -> + | _ -> if isRefTy g ty then CompleteD else ErrorD (ConstraintSolverError(FSComp.SR.csGenericConstructRequiresReferenceSemantics(NicePrint.minimalStringOfType denv ty), m, m)) @@ -1878,9 +1936,9 @@ and SolveTypeRequiresDefaultConstructor (csenv:ConstraintSolverEnv) ndeep m2 tra let denv = csenv.DisplayEnv let ty = stripTyEqnsAndMeasureEqns g origTy match tryDestTyparTy g ty with - | Some destTypar -> + | ValueSome destTypar -> AddConstraint csenv ndeep m2 trace destTypar (TyparConstraint.RequiresDefaultConstructor m) - | None -> + | _ -> if isStructTy g ty && TypeHasDefaultValue g m ty then CompleteD else @@ -1888,13 +1946,13 @@ and SolveTypeRequiresDefaultConstructor (csenv:ConstraintSolverEnv) ndeep m2 tra |> List.exists (fun x -> x.IsNullary && IsMethInfoAccessible amap m AccessibleFromEverywhere x) then match tryDestAppTy g ty with - | Some tcref when HasFSharpAttribute g g.attrib_AbstractClassAttribute tcref.Attribs -> + | ValueSome tcref when HasFSharpAttribute g g.attrib_AbstractClassAttribute tcref.Attribs -> ErrorD (ConstraintSolverError(FSComp.SR.csGenericConstructRequiresNonAbstract(NicePrint.minimalStringOfType denv origTy), m, m2)) | _ -> CompleteD else match tryDestAppTy g ty with - | Some tcref when + | ValueSome tcref when tcref.PreEstablishedHasDefaultConstructor || // F# 3.1 feature: records with CLIMutable attribute should satisfy 'default constructor' constraint (tcref.IsRecordTycon && HasFSharpAttribute g g.attrib_CLIMutableAttribute tcref.Attribs) -> @@ -2029,17 +2087,16 @@ and ArgsMustSubsumeOrConvert cxsln isConstraint (calledArg: CalledArg) - (callerArg: CallerArg<'T>) = + (callerArg: CallerArg<'T>) = trackErrors { let g = csenv.g let m = callerArg.Range let calledArgTy = AdjustCalledArgType csenv.InfoReader isConstraint calledArg callerArg - SolveTypeSubsumesTypeWithReport csenv ndeep m trace cxsln calledArgTy callerArg.Type ++ (fun () -> - + do! SolveTypeSubsumesTypeWithReport csenv ndeep m trace cxsln calledArgTy callerArg.Type if calledArg.IsParamArray && isArray1DTy g calledArgTy && not (isArray1DTy g callerArg.Type) then - ErrorD(Error(FSComp.SR.csMethodExpectsParams(), m)) - else - CompleteD) + return! ErrorD(Error(FSComp.SR.csMethodExpectsParams(), m)) + else () + } and MustUnify csenv ndeep trace cxsln ty1 ty2 = SolveTypeEqualsTypeWithReport csenv ndeep csenv.m trace cxsln ty1 ty2 @@ -2324,7 +2381,7 @@ and ResolveOverloading // Func<_> is always considered better than any other delegate type match tryDestAppTy csenv.g ty1 with - | Some tcref1 when + | ValueSome tcref1 when tcref1.DisplayName = "Func" && (match tcref1.PublicPath with Some p -> p.EnclosingPath = [| "System" |] | _ -> false) && isDelegateTy g ty1 && @@ -2462,11 +2519,12 @@ and ResolveOverloading match calledMethOpt with | Some calledMeth -> calledMethOpt, - errors ++ (fun () -> + trackErrors { + do! errors let cxsln = Option.map (fun traitInfo -> (traitInfo, MemberConstraintSolutionOfMethInfo csenv.SolverState m calledMeth.Method calledMeth.CalledTyArgs)) cx match calledMethTrace with | NoTrace -> - + return! // No trace available for CanMemberSigsMatchUpToCheck with ArgsMustSubsumeOrConvert CanMemberSigsMatchUpToCheck csenv @@ -2484,14 +2542,15 @@ and ResolveOverloading // Unify return type match reqdRetTyOpt with - | None -> CompleteD - | Some _ when calledMeth.Method.IsConstructor -> CompleteD + | None -> () + | Some _ when calledMeth.Method.IsConstructor -> () | Some reqdRetTy -> let actualRetTy = calledMeth.CalledReturnTypeAfterOutArgTupling if isByrefTy g reqdRetTy then - ErrorD(Error(FSComp.SR.tcByrefReturnImplicitlyDereferenced(), m)) + return! ErrorD(Error(FSComp.SR.tcByrefReturnImplicitlyDereferenced(), m)) else - MustUnify csenv ndeep trace cxsln reqdRetTy actualRetTy) + return! MustUnify csenv ndeep trace cxsln reqdRetTy actualRetTy + } | None -> None, errors @@ -2511,7 +2570,8 @@ let UnifyUniqueOverloading let candidates = calledMethGroup |> List.filter (fun cmeth -> cmeth.IsCandidate(m, ad)) let ndeep = 0 match calledMethGroup, candidates with - | _, [calledMeth] -> + | _, [calledMeth] -> trackErrors { + do! // Only one candidate found - we thus know the types we expect of arguments CanMemberSigsMatchUpToCheck csenv @@ -2522,13 +2582,15 @@ let UnifyUniqueOverloading (ArgsMustSubsumeOrConvert csenv ndeep NoTrace None false) // UnifyUniqueOverloading is not called in case of trait call - pass isConstraint=false (Some reqdRetTy) calledMeth - ++ (fun () -> ResultD true) + return true + } | [], _ -> ErrorD (Error (FSComp.SR.csMethodNotFound(methodName), m)) - | _, [] -> - ReportNoCandidatesErrorSynExpr csenv callerArgCounts methodName ad calledMethGroup - ++ (fun () -> ResultD false) + | _, [] -> trackErrors { + do! ReportNoCandidatesErrorSynExpr csenv callerArgCounts methodName ad calledMethGroup + return false + } | _ -> ResultD false @@ -2591,7 +2653,12 @@ let AddCxTypeMustSubsumeType contextInfo denv css m trace ty1 ty2 = |> RaiseOperationResult let AddCxMethodConstraint denv css m trace traitInfo = - TryD (fun () -> SolveMemberConstraint (MakeConstraintSolverEnv ContextInfo.NoContext css m denv) true false 0 m trace traitInfo ++ (fun _ -> CompleteD)) + TryD (fun () -> + trackErrors { + do! + SolveMemberConstraint (MakeConstraintSolverEnv ContextInfo.NoContext css m denv) true false 0 m trace traitInfo + |> OperationResult.ignore + }) (fun res -> ErrorD (ErrorFromAddingConstraint(denv, res, m))) |> RaiseOperationResult @@ -2640,7 +2707,7 @@ let AddCxTypeIsDelegate denv css m trace ty aty bty = (fun res -> ErrorD (ErrorFromAddingConstraint(denv, res, m))) |> RaiseOperationResult -let CodegenWitnessThatTypeSupportsTraitConstraint tcVal g amap m (traitInfo:TraitConstraintInfo) argExprs = +let CodegenWitnessThatTypeSupportsTraitConstraint tcVal g amap m (traitInfo:TraitConstraintInfo) argExprs = trackErrors { let css = { g = g amap = amap @@ -2649,15 +2716,15 @@ let CodegenWitnessThatTypeSupportsTraitConstraint tcVal g amap m (traitInfo:Trai InfoReader = new InfoReader(g, amap) } let csenv = MakeConstraintSolverEnv ContextInfo.NoContext css m (DisplayEnv.Empty g) - SolveMemberConstraint csenv true true 0 m NoTrace traitInfo ++ (fun _res -> - let sln = + let! _res = SolveMemberConstraint csenv true true 0 m NoTrace traitInfo + let sln = match traitInfo.Solution with - | None -> Choice4Of4() + | None -> Choice5Of5() | Some sln -> match sln with | ILMethSln(origTy, extOpt, mref, minst) -> let metadataTy = convertToTypeWithMetadataIfPossible g origTy - let tcref, _tinst = destAppTy g metadataTy + let tcref = tcrefOfAppTy g metadataTy let mdef = IL.resolveILMethodRef tcref.ILTyconRawMetadata mref let ilMethInfo = match extOpt with @@ -2665,17 +2732,20 @@ let CodegenWitnessThatTypeSupportsTraitConstraint tcVal g amap m (traitInfo:Trai | Some ilActualTypeRef -> let actualTyconRef = Import.ImportILTypeRef amap m ilActualTypeRef MethInfo.CreateILExtensionMeth(amap, m, origTy, actualTyconRef, None, mdef) - Choice1Of4 (ilMethInfo, minst) + Choice1Of5 (ilMethInfo, minst) | FSMethSln(ty, vref, minst) -> - Choice1Of4 (FSMeth(g, ty, vref, None), minst) + Choice1Of5 (FSMeth(g, ty, vref, None), minst) | FSRecdFieldSln(tinst, rfref, isSetProp) -> - Choice2Of4 (tinst, rfref, isSetProp) + Choice2Of5 (tinst, rfref, isSetProp) + | FSAnonRecdFieldSln(anonInfo, tinst, i) -> + Choice3Of5 (anonInfo, tinst, i) | BuiltInSln -> - Choice4Of4 () + Choice5Of5 () | ClosedExprSln expr -> - Choice3Of4 expr + Choice4Of5 expr + return! match sln with - | Choice1Of4(minfo, methArgTys) -> + | Choice1Of5(minfo, methArgTys) -> let argExprs = // FIX for #421894 - typechecker assumes that coercion can be applied for the trait calls arguments but codegen doesn't emit coercion operations // result - generation of non-verifyable code @@ -2706,7 +2776,7 @@ let CodegenWitnessThatTypeSupportsTraitConstraint tcVal g amap m (traitInfo:Trai else ResultD (Some (MakeMethInfoCall amap m minfo methArgTys argExprs )) - | Choice2Of4 (tinst, rfref, isSet) -> + | Choice2Of5 (tinst, rfref, isSet) -> let res = match isSet, rfref.RecdField.IsStatic, argExprs.Length with | true, true, 1 -> @@ -2729,8 +2799,19 @@ let CodegenWitnessThatTypeSupportsTraitConstraint tcVal g amap m (traitInfo:Trai Some (mkRecdFieldGet g (argExprs.[0], rfref, tinst, m)) | _ -> None ResultD res - | Choice3Of4 expr -> ResultD (Some (MakeApplicationAndBetaReduce g (expr, tyOfExpr g expr, [], argExprs, m))) - | Choice4Of4 () -> ResultD None) + | Choice3Of5 (anonInfo, tinst, i) -> + let res = + let tupInfo = anonInfo.TupInfo + if evalTupInfoIsStruct tupInfo && isByrefTy g (tyOfExpr g argExprs.[0]) then + Some (mkAnonRecdFieldGetViaExprAddr (anonInfo, argExprs.[0], tinst, i, m)) + else + Some (mkAnonRecdFieldGet g (anonInfo, argExprs.[0], tinst, i, m)) + ResultD res + + | Choice4Of5 expr -> ResultD (Some (MakeApplicationAndBetaReduce g (expr, tyOfExpr g expr, [], argExprs, m))) + + | Choice5Of5 () -> ResultD None + } let ChooseTyparSolutionAndSolve css denv tp = @@ -2769,6 +2850,7 @@ let IsApplicableMethApprox g amap m (minfo:MethInfo) availObjTy = let minst = FreshenMethInfo m minfo match minfo.GetObjArgTypes(amap, m, minst) with | [reqdObjTy] -> + let reqdObjTy = if isByrefTy g reqdObjTy then destByrefTy g reqdObjTy else reqdObjTy // This is to support byref extension methods. TryD (fun () -> SolveTypeSubsumesType csenv 0 m NoTrace None reqdObjTy availObjTy ++ (fun () -> ResultD true)) (fun _err -> ResultD false) |> CommitOperationResult diff --git a/src/fsharp/DetupleArgs.fs b/src/fsharp/DetupleArgs.fs index bf56deeeb7..9a7f99e63a 100755 --- a/src/fsharp/DetupleArgs.fs +++ b/src/fsharp/DetupleArgs.fs @@ -850,11 +850,11 @@ let postTransformExpr (penv:penv) expr = | _ -> None -let passImplFile penv ass = - ass |> RewriteImplFile {PreIntercept =None - PreInterceptBinding=None - PostTransform= postTransformExpr penv - IsUnderQuotations=false } +let passImplFile penv assembly = + assembly |> RewriteImplFile {PreIntercept =None + PreInterceptBinding=None + PostTransform= postTransformExpr penv + IsUnderQuotations=false } //------------------------------------------------------------------------- diff --git a/src/fsharp/Directory.Build.props b/src/fsharp/Directory.Build.props new file mode 100644 index 0000000000..151415117e --- /dev/null +++ b/src/fsharp/Directory.Build.props @@ -0,0 +1,12 @@ + + + + + + true + true + false + $(ArtifactsPackagesDir)\$(Configuration) + + + diff --git a/src/fsharp/Directory.Build.targets b/src/fsharp/Directory.Build.targets new file mode 100644 index 0000000000..068f4dc3c5 --- /dev/null +++ b/src/fsharp/Directory.Build.targets @@ -0,0 +1,4 @@ + + + + diff --git a/src/fsharp/Directory.Nuget.props b/src/fsharp/Directory.Nuget.props new file mode 100644 index 0000000000..6521936cfe --- /dev/null +++ b/src/fsharp/Directory.Nuget.props @@ -0,0 +1,27 @@ + + + + https://github.com/Microsoft/visualfsharp/blob/master/License.txt + https://github.com/Microsoft/visualfsharp + Microsoft and F# Software Foundation + Microsoft and F# Software Foundation + Visual F# Compiler FSharp functional programming + (C) Microsoft Corporation. All rights reserved. + + $(GitHeadSha) + [developer build] + + + licenseUrl=$(PackageLicenceUrl); + authors=$(PackageAuthors); + owners=$(PackageOwners); + projectUrl=$(PackageProjectUrl); + copyright=$(PackageCopyright); + tags=$(PackageTags); + githeadsha=$(NormalizedGitHeadSha); + configuration=$(Configuration); + artifactsbindir=$(ArtifactsBinDir); + + + + diff --git a/src/fsharp/Directory.Nuget.targets b/src/fsharp/Directory.Nuget.targets new file mode 100644 index 0000000000..e30b155faa --- /dev/null +++ b/src/fsharp/Directory.Nuget.targets @@ -0,0 +1,11 @@ + + + + + $(NuspecProperties); + packageId=$(PackageId); + version=$(PackageVersion); + + + + diff --git a/src/fsharp/ErrorLogger.fs b/src/fsharp/ErrorLogger.fs index d29874bb0d..41be3768ed 100755 --- a/src/fsharp/ErrorLogger.fs +++ b/src/fsharp/ErrorLogger.fs @@ -596,15 +596,27 @@ let rec Iterate2D f xs ys = | h1 :: t1, h2::t2 -> f h1 h2 ++ (fun () -> Iterate2D f t1 t2) | _ -> failwith "Iterate2D" +/// Keep the warnings, propagate the error to the exception continuation. let TryD f g = match f() with - | ErrorResult(warns, err) -> (OkResult(warns, ())) ++ (fun () -> g err) + | ErrorResult(warns, err) -> + trackErrors { + do! OkResult(warns, ()) + return! g err + } | res -> res let rec RepeatWhileD ndeep body = body ndeep ++ (fun x -> if x then RepeatWhileD (ndeep+1) body else CompleteD) let AtLeastOneD f l = MapD f l ++ (fun res -> ResultD (List.exists id res)) +[] +module OperationResult = + let inline ignore (res: OperationResult<'a>) = + match res with + | OkResult(warnings, _) -> OkResult(warnings, ()) + | ErrorResult(warnings, err) -> ErrorResult(warnings, err) + // Code below is for --flaterrors flag that is only used by the IDE let stringThatIsAProxyForANewlineInFlatErrors = new System.String [|char 29 |] diff --git a/src/fsharp/ErrorResolutionHints.fs b/src/fsharp/ErrorResolutionHints.fs index e674adb6f4..20bcb13fd2 100644 --- a/src/fsharp/ErrorResolutionHints.fs +++ b/src/fsharp/ErrorResolutionHints.fs @@ -43,6 +43,7 @@ let FilterPredictions (idText:string) (suggestionF:ErrorLogger.Suggestions) = name |> Seq.forall (fun c -> c <> ' ') if allSuggestions.Contains idText then [] else // some other parsing error occurred + let dotIdText = "." + idText allSuggestions |> Seq.choose (fun suggestion -> // Because beginning a name with _ is used both to indicate an unused @@ -53,7 +54,7 @@ let FilterPredictions (idText:string) (suggestionF:ErrorLogger.Suggestions) = let suggestion:string = demangle suggestion let suggestedText = suggestion.ToUpperInvariant() let similarity = EditDistance.JaroWinklerDistance uppercaseText suggestedText - if similarity >= highConfidenceThreshold || suggestion.EndsWithOrdinal("." + idText) then + if similarity >= highConfidenceThreshold || suggestion.EndsWithOrdinal(dotIdText) then Some(similarity, suggestion) elif similarity < minThresholdForSuggestions && suggestedText.Length > minStringLengthForThreshold then None diff --git a/src/fsharp/ExtensionTyping.fs b/src/fsharp/ExtensionTyping.fs index 2f3eb3aafb..0d86ca58a0 100755 --- a/src/fsharp/ExtensionTyping.fs +++ b/src/fsharp/ExtensionTyping.fs @@ -428,7 +428,7 @@ module internal ExtensionTyping = member __.GetGenericArguments() = x.GetGenericArguments() |> ProvidedType.CreateArray ctxt member __.ApplyStaticArguments(provider: ITypeProvider, fullTypePathAfterArguments, staticArgs: obj[]) = provider.ApplyStaticArguments(x, fullTypePathAfterArguments, staticArgs) |> ProvidedType.Create ctxt - member __.IsVoid = (typeof.Equals(x)) + member __.IsVoid = (typeof.Equals(x) || (x.Namespace = "System" && x.Name = "Void")) member __.IsGenericParameter = x.IsGenericParameter member __.IsValueType = x.IsValueType member __.IsByRef = x.IsByRef diff --git a/src/fsharp/FSComp.txt b/src/fsharp/FSComp.txt index 8293a709e5..cb5747f3c5 100755 --- a/src/fsharp/FSComp.txt +++ b/src/fsharp/FSComp.txt @@ -440,6 +440,7 @@ parsParenFormIsForML,"In F# code you may use 'expr.[expr]'. A type annotation ma 602,parsUnmatched,"Unmatched '%s'" 603,parsUnmatchedBracketBar,"Unmatched '[|'" 604,parsUnmatchedBrace,"Unmatched '{{'" +605,parsUnmatchedBraceBar,"Unmatched '{{|'" 609,parsFieldBinding,"Field bindings must have the form 'id = expr;'" 610,parsMemberIllegalInObjectImplementation,"This member is not permitted in an object implementation" 611,parsMissingFunctionBody,"Missing function body" @@ -922,6 +923,7 @@ typeInfoProperty,"property" typeInfoExtension,"extension" typeInfoCustomOperation,"custom operation" typeInfoArgument,"argument" +typeInfoAnonRecdField,"anonymous record field" typeInfoPatternVariable,"patvar" typeInfoNamespace,"namespace" typeInfoModule,"module" @@ -1040,8 +1042,8 @@ lexHashBangMustBeFirstInFile,"#! may only appear as the first line at the start 1186,parsInvalidProperty,"Invalid property getter or setter" 1187,parsIndexerPropertyRequiresAtLeastOneArgument,"An indexer property must be given at least one argument" 1188,tastInvalidAddressOfMutableAcrossAssemblyBoundary,"This operation accesses a mutable top-level value defined in another assembly in an unsupported way. The value cannot be accessed through its address. Consider copying the expression to a mutable local, e.g. 'let mutable x = ...', and if necessary assigning the value back after the completion of the operation" -1189,parsNonAdjacentTypars,"Type parameters must be placed directly adjacent to the type name, e.g. \"type C<'T>\", not type \"C <'T>\"" -1190,parsNonAdjacentTyargs,"Type arguments must be placed directly adjacent to the type name, e.g. \"C<'T>\", not \"C <'T>\"" +1189,parsNonAdjacentTypars,"Remove spaces between the type name and type parameter, e.g. \"type C<'T>\", not type \"C <'T>\". Type parameters must be placed directly adjacent to the type name." +1190,parsNonAdjacentTyargs,"Remove spaces between the type name and type parameter, e.g. \"C<'T>\", not \"C <'T>\". Type parameters must be placed directly adjacent to the type name." parsNonAtomicType,"The use of the type syntax 'int C' and 'C ' is not permitted here. Consider adjusting this type to be written in the form 'C'" # 1191,tastUndefinedTyconItemField,"The type %s did not contain the field '%s'" # 1192,tastUndefinedTyconItemUnionCase,"The type %s did not contain the union case '%s'" @@ -1293,7 +1295,10 @@ descriptionUnavailable,"(description unavailable...)" 3171,tcGeneratedTypesShouldBeInternalOrPrivate,"The provided types generated by this use of a type provider may not be used from other F# assemblies and should be marked internal or private. Consider using 'type internal TypeName = ...' or 'type private TypeName = ...'." 3172,chkGetterAndSetterHaveSamePropertyType,"A property's getter and setter must have the same type. Property '%s' has getter of type '%s' but setter of type '%s'." 3173,tcRuntimeSuppliedMethodCannotBeUsedInUserCode,"Array method '%s' is supplied by the runtime and cannot be directly used in code. For operations with array elements consider using family of GetArray/SetArray functions from LanguagePrimitives.IntrinsicFunctions module." -3174,tcUnionCaseConstructorDoesNotHaveFieldWithGivenName,"Union case/exception '%s' does not have field named '%s'." +3174,tcUnionCaseConstructorDoesNotHaveFieldWithGivenName,"The union case '%s' does not have a field named '%s'." +3174,tcExceptionConstructorDoesNotHaveFieldWithGivenName,"The exception '%s' does not have a field named '%s'." +3174,tcActivePatternsDoNotHaveFields,"Active patterns do not have fields. This syntax is invalid." +3174,tcConstructorDoesNotHaveFieldWithGivenName,"The constructor does not have a field named '%s'." 3175,tcUnionCaseFieldCannotBeUsedMoreThanOnce,"Union case/exception field '%s' cannot be used more than once." 3176,tcFieldNameIsUsedModeThanOnce,"Named field '%s' is used more than once." 3176,tcFieldNameConflictsWithGeneratedNameForAnonymousField,"Named field '%s' conflicts with autogenerated name for anonymous field." @@ -1338,6 +1343,8 @@ tcGlobalsSystemTypeNotFound,"The system type '%s' was required but no referenced 3213,typrelMemberHasMultiplePossibleDispatchSlots,"The member '%s' matches multiple overloads of the same method.\nPlease restrict it to one of the following:%s." 3214,methodIsNotStatic,"Method or object constructor '%s' is not static" 3215,parsUnexpectedSymbolEqualsInsteadOfIn,"Unexpected symbol '=' in expression. Did you intend to use 'for x in y .. z do' instead?" +tcAnonRecdCcuMismatch,"Two anonymous record types are from different assemblies '%s' and '%s'" +tcAnonRecdFieldNameMismatch,"Two anonymous record types have mismatched sets of field names '%s' and '%s'" keywordDescriptionAbstract,"Indicates a method that either has no implementation in the type in which it is declared or that is virtual and has a default implementation." keyworkDescriptionAnd,"Used in mutually recursive bindings, in property declarations, and with multiple constraints on generic parameters." keywordDescriptionAs,"Used to give the current class object an object name. Also used to give a name to a whole pattern within a pattern match." @@ -1370,7 +1377,7 @@ keywordDescriptionInterface,"Used to declare and implement interfaces." keywordDescriptionInternal,"Used to specify that a member is visible inside an assembly but not outside it." keywordDescriptionLazy,"Used to specify a computation that is to be performed only when a result is needed." keywordDescriptionLet,"Used to associate, or bind, a name to a value or function." -keywordDescriptionLetBang,"Used in asynchronous workflows to bind a name to the result of an asynchronous computation, or, in other computation expressions, used to bind a name to a result, which is of the computation type." +keywordDescriptionLetBang,"Used in computation expressions to bind a name to the result of another computation expression." keywordDescriptionMatch,"Used to branch by comparing a value to a pattern." keywordDescriptionMatchBang,"Used in computation expressions to pattern match directly over the result of another computation expression." keywordDescriptionMember,"Used to declare a property or method in an object type." @@ -1387,8 +1394,8 @@ keywordDescriptionOverride,"Used to implement a version of an abstract or virtua keywordDescriptionPrivate,"Restricts access to a member to code in the same type or module." keywordDescriptionPublic,"Allows access to a member from outside the type." keywordDescriptionRec,"Used to indicate that a function is recursive." -keywordDescriptionReturn,"Used to indicate a value to provide as the result of a computation expression." -keywordDescriptionReturnBang,"Used to indicate a computation expression that, when evaluated, provides the result of the containing computation expression." +keywordDescriptionReturn,"Used to provide a value for the result of the containing computation expression." +keywordDescriptionReturnBang,"Used to provide a value for the result of the containing computation expression, where that value itself comes from the result another computation expression." keywordDescriptionSelect,"Used in query expressions to specify what fields or columns to extract. Note that this is a contextual keyword, which means that it is not actually a reserved word and it only acts like a keyword in appropriate context." keywordDescriptionStatic,"Used to indicate a method or property that can be called without an instance of a type, or a value member that is shared among all instances of a type." keywordDescriptionStruct,"Used to declare a structure type. Also used in generic parameter constraints. Used for OCaml compatibility in module definitions." @@ -1397,8 +1404,8 @@ keywordDescriptionTo,"Used in for loops to indicate a range." keywordDescriptionTry,"Used to introduce a block of code that might generate an exception. Used together with with or finally." keywordDescriptionType,"Used to declare a class, record, structure, discriminated union, enumeration type, unit of measure, or type abbreviation." keywordDescriptionUpcast,"Used to convert to a type that is higher in the inheritance chain." -keywordDescriptionUse,"Used instead of let for values that require Dispose to be called to free resources." -keywordDescriptionUseBang,"Used instead of let! in asynchronous workflows and other computation expressions for values that require Dispose to be called to free resources." +keywordDescriptionUse,"Used instead of let for values that implement IDisposable"" +keywordDescriptionUseBang,"Used instead of let! in computation expressions for computation expression results that implement IDisposable." keywordDescriptionVal,"Used in a signature to indicate a value, or in a type to declare a member, in limited situations." keywordDescriptionVoid,"Indicates the .NET void type. Used when interoperating with other .NET languages." keywordDescriptionWhen,"Used for Boolean conditions (when guards) on pattern matches and to introduce a constraint clause for a generic type parameter." @@ -1431,12 +1438,20 @@ notAFunctionButMaybeDeclaration,"This value is not a function and cannot be appl 3226,tcByrefReturnImplicitlyDereferenced,"A byref pointer returned by a function or method is implicitly dereferenced as of F# 4.5. To acquire the return value as a pointer, use the address-of operator, e.g. '&f(x)' or '&obj.Method(arg1, arg2)'." 3227,tcByRefLikeNotStruct,"A type annotated with IsByRefLike must also be a struct. Consider adding the [] attribute to the type." 3228,chkNoByrefAddressOfValueFromExpression,"The address of a value returned from the expression cannot be used at this point. This is to ensure the address of the local value does not escape its scope." -3229,chkNoReturnOfLimitedSpan,"The Span or IsByRefLike expression cannot be returned from this function or method, because it is composed using elements that may escape their scope." -3230,chkNoWriteToLimitedSpan,"This value can't be assigned because the target '%s' may refer to non-stack-local memory, while the expression being assigned is assessed to potentially refer to stack-local memory. This is to help prevent pointers to stack-bound memory escaping their scope." -3231,tastValueMustBeLocal,"A value defined in a module must be mutable in order to take its address, e.g. 'let mutable x = ...'" -3232,tcIsReadOnlyNotStruct,"A type annotated with IsReadOnly must also be a struct. Consider adding the [] attribute to the type." -3234,chkStructsMayNotReturnAddressesOfContents,"Struct members cannot return the address of fields of the struct by reference" -3235,chkNoByrefLikeFunctionCall,"The function or method call cannot be used at this point, because one argument that is a byref of a non-stack-local Span or IsByRefLike type is used with another argument that is a stack-local Span or IsByRefLike type. This is to ensure the address of the local value does not escape its scope." -3236,chkNoSpanLikeVariable,"The Span or IsByRefLike variable '%s' cannot be used at this point. This is to ensure the address of the local value does not escape its scope." -3237,chkNoSpanLikeValueFromExpression,"A Span or IsByRefLike value returned from the expression cannot be used at ths point. This is to ensure the address of the local value does not escape its scope." -3238,tastCantTakeAddressOfExpression,"Cannot take the address of the value returned from the expression. Assign the returned value to a let-bound value before taking the address." +3229,chkNoWriteToLimitedSpan,"This value can't be assigned because the target '%s' may refer to non-stack-local memory, while the expression being assigned is assessed to potentially refer to stack-local memory. This is to help prevent pointers to stack-bound memory escaping their scope." +3230,tastValueMustBeLocal,"A value defined in a module must be mutable in order to take its address, e.g. 'let mutable x = ...'" +3231,tcIsReadOnlyNotStruct,"A type annotated with IsReadOnly must also be a struct. Consider adding the [] attribute to the type." +3232,chkStructsMayNotReturnAddressesOfContents,"Struct members cannot return the address of fields of the struct by reference" +3233,chkNoByrefLikeFunctionCall,"The function or method call cannot be used at this point, because one argument that is a byref of a non-stack-local Span or IsByRefLike type is used with another argument that is a stack-local Span or IsByRefLike type. This is to ensure the address of the local value does not escape its scope." +3234,chkNoSpanLikeVariable,"The Span or IsByRefLike variable '%s' cannot be used at this point. This is to ensure the address of the local value does not escape its scope." +3235,chkNoSpanLikeValueFromExpression,"A Span or IsByRefLike value returned from the expression cannot be used at ths point. This is to ensure the address of the local value does not escape its scope." +3236,tastCantTakeAddressOfExpression,"Cannot take the address of the value returned from the expression. Assign the returned value to a let-bound value before taking the address." +3237,tcCannotCallExtensionMethodInrefToByref,"Cannot call the byref extension method '%s. The first parameter requires the value to be mutable or a non-readonly byref type." +3238,tcByrefsMayNotHaveTypeExtensions,"Byref types are not allowed to have optional type extensions." +3239,tcCannotPartiallyApplyExtensionMethodForByref,"Cannot partially apply the extension method '%s' because the first parameter is a byref type." +3242,tcTypeDoesNotInheritAttribute,"This type does not inherit Attribute, it will not work correctly with other .NET languages." +3243,parsInvalidAnonRecdExpr,"Invalid anonymous record expression" +3244,parsInvalidAnonRecdType,"Invalid anonymous record type" +3245,tcCopyAndUpdateNeedsRecordType,"The input to a copy-and-update expression that creates an anonymous record must be either an anonymous record or a record" +3300,chkInvalidFunctionParameterType,"The parameter '%s' has an invalid type '%s'. This is not permitted by the rules of Common IL." +3301,chkInvalidFunctionReturnType,"The function or method has an invalid return type '%s'. This is not permitted by the rules of Common IL." diff --git a/src/fsharp/FSStrings.resx b/src/fsharp/FSStrings.resx index 5a99d5e9e7..05cd75cc66 100755 --- a/src/fsharp/FSStrings.resx +++ b/src/fsharp/FSStrings.resx @@ -396,6 +396,9 @@ symbol '[' + + symbol '{|' + symbol '[|' @@ -411,6 +414,9 @@ symbol '|]' + + symbol '|}' + symbol '>}' diff --git a/src/fsharp/FSharp.Compiler.nuget/Directory.Build.props b/src/fsharp/FSharp.Compiler.nuget/Directory.Build.props new file mode 100644 index 0000000000..8093275dba --- /dev/null +++ b/src/fsharp/FSharp.Compiler.nuget/Directory.Build.props @@ -0,0 +1,11 @@ + + + + + + + netcoreapp2.1 + Microsoft.FSharp.Compiler.nuspec + + + diff --git a/src/fsharp/FSharp.Compiler.nuget/Directory.Build.targets b/src/fsharp/FSharp.Compiler.nuget/Directory.Build.targets new file mode 100644 index 0000000000..2721c93a90 --- /dev/null +++ b/src/fsharp/FSharp.Compiler.nuget/Directory.Build.targets @@ -0,0 +1,18 @@ + + + + -rtm-$(NuGetPackageVersionSuffix) + $(FSPackageVersion)$(PreReleaseSuffix) + + + + + + + + + + + + + diff --git a/src/fsharp/FSharp.Compiler.nuget/Microsoft.FSharp.Compiler.Prerelease.csproj b/src/fsharp/FSharp.Compiler.nuget/Microsoft.FSharp.Compiler.Prerelease.csproj new file mode 100644 index 0000000000..692e5aba1b --- /dev/null +++ b/src/fsharp/FSharp.Compiler.nuget/Microsoft.FSharp.Compiler.Prerelease.csproj @@ -0,0 +1,8 @@ + + + + Microsoft.FSharp.Compiler + true + + + diff --git a/src/fsharp/FSharp.Compiler.nuget/Microsoft.FSharp.Compiler.csproj b/src/fsharp/FSharp.Compiler.nuget/Microsoft.FSharp.Compiler.csproj new file mode 100644 index 0000000000..abb19e418f --- /dev/null +++ b/src/fsharp/FSharp.Compiler.nuget/Microsoft.FSharp.Compiler.csproj @@ -0,0 +1,8 @@ + + + + Microsoft.FSharp.Compiler + false + + + diff --git a/src/fsharp/FSharp.Compiler.nuget/Testing.FSharp.Compiler.csproj b/src/fsharp/FSharp.Compiler.nuget/Testing.FSharp.Compiler.csproj new file mode 100644 index 0000000000..aaee9c7394 --- /dev/null +++ b/src/fsharp/FSharp.Compiler.nuget/Testing.FSharp.Compiler.csproj @@ -0,0 +1,8 @@ + + + + Testing.FSharp.Compiler + true + + + diff --git a/src/fsharp/FindUnsolved.fs b/src/fsharp/FindUnsolved.fs index e78e41212d..9c38f26a2a 100755 --- a/src/fsharp/FindUnsolved.fs +++ b/src/fsharp/FindUnsolved.fs @@ -1,9 +1,7 @@ // Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. -//------------------------------------------------------------------------- -// Find unsolved, uninstantiated type variables -//------------------------------------------------------------------------- +/// Find unsolved, uninstantiated type variables module internal Microsoft.FSharp.Compiler.FindUnsolved open Microsoft.FSharp.Compiler @@ -16,24 +14,24 @@ open Microsoft.FSharp.Compiler.TypeRelations type env = Nix +/// The environment and collector type cenv = { g: TcGlobals amap: Import.ImportMap denv: DisplayEnv mutable unsolved: Typars } +/// Walk types, collecting type variables let accTy cenv _env ty = - (freeInType CollectTyparsNoCaching (tryNormalizeMeasureInType cenv.g ty)).FreeTypars |> Zset.iter (fun tp -> - if (tp.Rigidity <> TyparRigidity.Rigid) then - cenv.unsolved <- tp :: cenv.unsolved) + let normalizedTy = tryNormalizeMeasureInType cenv.g ty + (freeInType CollectTyparsNoCaching normalizedTy).FreeTypars |> Zset.iter (fun tp -> + if (tp.Rigidity <> TyparRigidity.Rigid) then + cenv.unsolved <- tp :: cenv.unsolved) let accTypeInst cenv env tyargs = - tyargs |> List.iter (accTy cenv env) + tyargs |> List.iter (accTy cenv env) -//-------------------------------------------------------------------------- -// walk exprs etc -//-------------------------------------------------------------------------- - +/// Walk expressions, collecting type variables let rec accExpr (cenv:cenv) (env:env) expr = let expr = stripExpr expr match expr with @@ -62,7 +60,6 @@ let rec accExpr (cenv:cenv) (env:env) expr = accTypeInst cenv env tyargs accExpr cenv env f accExprs cenv env argsl - // REVIEW: fold the next two cases together | Expr.Lambda(_,_ctorThisValOpt,_baseValOpt,argvs,_body,m,rty) -> let topValInfo = ValReprInfo ([],[argvs |> List.map (fun _ -> ValReprInfo.unnamedTopArg1)],ValReprInfo.unnamedRetVal) let ty = mkMultiLambdaTy m argvs rty @@ -136,6 +133,7 @@ and accLambdas cenv env topValInfo e ety = accExpr cenv env e and accExprs cenv env exprs = exprs |> List.iter (accExpr cenv env) + and accTargets cenv env m ty targets = Array.iter (accTarget cenv env m ty) targets and accTarget cenv env _m _ty (TTarget(_vs,e,_)) = accExpr cenv env e @@ -192,10 +190,6 @@ and accBind cenv env (bind:Binding) = and accBinds cenv env xs = xs |> List.iter (accBind cenv env) -//-------------------------------------------------------------------------- -// check tycons -//-------------------------------------------------------------------------- - let accTyconRecdField cenv env _tycon (rfield:RecdField) = accAttribs cenv env rfield.PropertyAttribs accAttribs cenv env rfield.FieldAttribs @@ -205,17 +199,12 @@ let accTycon cenv env (tycon:Tycon) = abstractSlotValsOfTycons [tycon] |> List.iter (accVal cenv env) tycon.AllFieldsArray |> Array.iter (accTyconRecdField cenv env tycon) if tycon.IsUnionTycon then (* This covers finite unions. *) - tycon.UnionCasesAsList |> List.iter (fun uc -> + tycon.UnionCasesArray |> Array.iter (fun uc -> accAttribs cenv env uc.Attribs - uc.RecdFields |> List.iter (accTyconRecdField cenv env tycon)) - + uc.RecdFieldsArray |> Array.iter (accTyconRecdField cenv env tycon)) let accTycons cenv env tycons = List.iter (accTycon cenv env) tycons -//-------------------------------------------------------------------------- -// check modules -//-------------------------------------------------------------------------- - let rec accModuleOrNamespaceExpr cenv env x = match x with | ModuleOrNamespaceExprWithSig(_mty, def, _m) -> accModuleOrNamespaceDef cenv env def @@ -231,7 +220,9 @@ and accModuleOrNamespaceDef cenv env x = | TMDefDo(e,_m) -> accExpr cenv env e | TMAbstract(def) -> accModuleOrNamespaceExpr cenv env def | TMDefs(defs) -> accModuleOrNamespaceDefs cenv env defs + and accModuleOrNamespaceBinds cenv env xs = List.iter (accModuleOrNamespaceBind cenv env) xs + and accModuleOrNamespaceBind cenv env x = match x with | ModuleOrNamespaceBinding.Binding bind -> accBind cenv env bind diff --git a/src/fsharp/IlxGen.fs b/src/fsharp/IlxGen.fs index 496f4531e5..d027afabeb 100755 --- a/src/fsharp/IlxGen.fs +++ b/src/fsharp/IlxGen.fs @@ -400,13 +400,15 @@ and GenTyAppAux amap m tyenv repr tinst = let ty = IL.instILType ilTypeInst ty ty | CompiledTypeRepr.ILAsmNamed (tref, boxity, ilTypeOpt) -> - match ilTypeOpt with - | None -> - let ilTypeInst = GenTypeArgsAux amap m tyenv tinst - mkILTy boxity (mkILTySpec (tref,ilTypeInst)) - | Some ilType -> - ilType // monomorphic types include a cached ilType to avoid reallocation of an ILType node + GenILTyAppAux amap m tyenv (tref, boxity, ilTypeOpt) tinst +and GenILTyAppAux amap m tyenv (tref, boxity, ilTypeOpt) tinst = + match ilTypeOpt with + | None -> + let ilTypeInst = GenTypeArgsAux amap m tyenv tinst + mkILTy boxity (mkILTySpec (tref,ilTypeInst)) + | Some ilType -> + ilType // monomorphic types include a cached ilType to avoid reallocation of an ILType node and GenNamedTyAppAux (amap:ImportMap) m tyenv ptrsOK tcref tinst = let g = amap.g @@ -439,6 +441,10 @@ and GenTypeAux amap m (tyenv: TypeReprEnv) voidOK ptrsOK ty = | TType_tuple (tupInfo, args) -> GenTypeAux amap m tyenv VoidNotOK ptrsOK (mkCompiledTupleTy g (evalTupInfoIsStruct tupInfo) args) | TType_fun (dty, returnTy) -> EraseClosures.mkILFuncTy g.ilxPubCloEnv (GenTypeArgAux amap m tyenv dty) (GenTypeArgAux amap m tyenv returnTy) + | TType_anon (anonInfo, tinst) -> + let tref = anonInfo.ILTypeRef + let boxity = if evalAnonInfoIsStruct anonInfo then ILBoxity.AsValue else ILBoxity.AsObject + GenILTyAppAux amap m tyenv (tref, boxity, None) tinst | TType_ucase (ucref, args) -> let cuspec,idx = GenUnionCaseSpec amap m tyenv ucref args @@ -471,8 +477,8 @@ and GenUnionRef (amap: ImportMap) m (tcref: TyconRef) = let tycon = tcref.Deref assert(not tycon.IsTypeAbbrev) match tycon.UnionTypeInfo with - | None -> failwith "GenUnionRef m" - | Some funion -> + | ValueNone -> failwith "GenUnionRef m" + | ValueSome funion -> cached funion.CompiledRepresentation (fun () -> let tyenvinner = TypeReprEnv.ForTycon tycon match tcref.CompiledRepresentation with @@ -541,14 +547,7 @@ and GenParamTypes amap m tyenv isSlotSig tys = tys |> List.map (GenParamType amap m tyenv isSlotSig) and GenTypeArgs amap m tyenv tyargs = GenTypeArgsAux amap m tyenv tyargs - -let GenericParamHasConstraint (gp: ILGenericParameterDef) = - gp.Constraints.Length <> 0 || - gp.Variance <> NonVariant || - gp.HasReferenceTypeConstraint || - gp.HasNotNullableValueTypeConstraint || - gp.HasDefaultConstructorConstraint - +and GenTypePermitVoidAux amap m tyenv ty = GenTypeAux amap m tyenv VoidOK PtrTypesNotOK ty // Static fields generally go in a private InitializationCodeAndBackingFields section. This is to ensure all static // fields are initialized only in their class constructors (we generate one primary @@ -580,8 +579,7 @@ let GenRecdFieldRef m cenv tyenv (rfref:RecdFieldRef) tyargs = GenType cenv.amap m tyenvinner rfref.RecdField.FormalType) let GenExnType amap m tyenv (ecref:TyconRef) = GenTyApp amap m tyenv ecref.CompiledRepresentation [] - - + //-------------------------------------------------------------------------- // Closure summaries //-------------------------------------------------------------------------- @@ -642,7 +640,7 @@ type ValStorage = | Arg of int /// Indicates that the value is stored in local of the method being generated. NamedLocalIlxClosureInfo is normally empty. /// It is non-empty for 'local type functions', see comments on definition of NamedLocalIlxClosureInfo. - | Local of int * NamedLocalIlxClosureInfo ref option + | Local of idx: int * realloc: bool * NamedLocalIlxClosureInfo ref option and OptionalShadowLocal = | NoShadowLocal @@ -739,8 +737,8 @@ let AddStorageForVal (g: TcGlobals) (v,s) eenv = // Passing an empty remap is sufficient for FSharp.Core.dll because it turns out the remapped type signature can // still be resolved. match tryRescopeVal g.fslibCcu Remap.Empty v with - | None -> eenv - | Some vref -> + | ValueNone -> eenv + | ValueSome vref -> match vref.TryDeref with | ValueNone -> //let msg = sprintf "could not dereference external value reference to something in FSharp.Core.dll during code generation, v.MangledName = '%s', v.Range = %s" v.MangledName (stringOfRange v.Range) @@ -766,7 +764,7 @@ let StorageForVal m v eenv = try eenv.valsInScope.[v] with :? KeyNotFoundException -> assert false - errorR(Error(FSComp.SR.ilUndefinedValue(showL(vspecAtBindL v)),m)) + errorR(Error(FSComp.SR.ilUndefinedValue(showL(valAtBindL v)),m)) notlazy (Arg 668(* random value for post-hoc diagnostic analysis on generated tree *) ) v.Force() @@ -860,7 +858,6 @@ let ComputeFieldSpecForVal(optIntraAssemblyInfo:IlxGenIntraAssemblyInfo option, else generate() - let IsValCompiledAsMethod g (v:Val) = match v.ValReprInfo with | None -> false @@ -1029,7 +1026,7 @@ and AddBindingsForModuleTopVals _g allocVal _cloc eenv vs = let AddIncrementalLocalAssemblyFragmentToIlxGenEnv (amap:ImportMap, isIncrementalFragment, g, ccu, fragName, intraAssemblyInfo, eenv, typedImplFiles) = let cloc = CompLocForFragment fragName ccu let allocVal = ComputeAndAddStorageForLocalTopVal (amap, g, intraAssemblyInfo, true, NoShadowLocal) - (eenv, typedImplFiles) ||> List.fold (fun eenv (TImplFile(qname,_,mexpr,_,_)) -> + (eenv, typedImplFiles) ||> List.fold (fun eenv (TImplFile(qname, _, mexpr, _, _, _)) -> let cloc = { cloc with clocTopImplQualifiedName = qname.Text } if isIncrementalFragment then match mexpr with @@ -1166,7 +1163,7 @@ and TypeDefsBuilder() = || not tdef.Fields.AsList.IsEmpty || not tdef.Events.AsList.IsEmpty || not tdef.Properties.AsList.IsEmpty - || not tdef.Methods.AsList.IsEmpty then + || not (Array.isEmpty tdef.Methods.AsArray) then yield tdef ] member b.FindTypeDefBuilder(nm) = @@ -1183,14 +1180,20 @@ and TypeDefsBuilder() = let idx = if addAtEnd then (countDown <- countDown - 1; countDown) else tdefs.Count tdefs.Add (tdef.Name, (idx, (new TypeDefBuilder(tdef, tdefDiscards), eliminateIfEmpty))) +type AnonTypeGenerationTable() = + let dict = Dictionary(HashIdentity.Structural) + member __.Table = dict + /// Assembly generation buffers -type AssemblyBuilder(cenv:cenv) as mgbuf = +type AssemblyBuilder(cenv:cenv, anonTypeTable: AnonTypeGenerationTable) as mgbuf = // The Abstract IL table of types let gtdefs= new TypeDefsBuilder() // The definitions of top level values, as quotations. - let mutable reflectedDefinitions : System.Collections.Generic.Dictionary = System.Collections.Generic.Dictionary(HashIdentity.Reference) + let mutable reflectedDefinitions : Dictionary = Dictionary(HashIdentity.Reference) + let mutable extraBindingsToGenerate = [] + // A memoization table for generating value types for big constant arrays - let vtgenerator= + let rawDataValueTypeGenerator = new MemoizationTable<(CompileLocation * int) , ILTypeSpec> ((fun (cloc,size) -> let name = CompilerGeneratedName ("T" + string(newUnique()) + "_" + string size + "Bytes") // Type names ending ...$T_37Bytes @@ -1202,6 +1205,129 @@ type AssemblyBuilder(cenv:cenv) as mgbuf = vtspec), keyComparer=HashIdentity.Structural) + let generateAnonType genToStringMethod (isStruct, ilTypeRef, nms) = + + let flds = [ for (i,nm) in Array.indexed nms -> (nm, nm + "@", ILType.TypeVar (uint16 i)) ] + // Note that this alternative below would give the same names as C#, but the generated + // comparison/equality doesn't know about these names. + //let flds = [ for (i,nm) in Array.indexed nms -> (nm, "<" + nm + ">" + "i__Field", ILType.TypeVar (uint16 i)) ] + + let ilGenericParams = + [ for nm in nms -> + { Name = sprintf "<%s>j__TPar" nm + Constraints = [] + Variance=NonVariant + CustomAttrsStored = storeILCustomAttrs emptyILCustomAttrs + HasReferenceTypeConstraint=false + HasNotNullableValueTypeConstraint=false + HasDefaultConstructorConstraint= false + MetadataIndex = NoMetadataIdx } ] + + let ilTy = mkILFormalNamedTy (if isStruct then ILBoxity.AsValue else ILBoxity.AsObject) ilTypeRef ilGenericParams + + // Generate the IL fields + let ilFieldDefs = + mkILFields + [ for (_, fldName, fldTy) in flds -> + let fdef = mkILInstanceField (fldName, fldTy, None, ILMemberAccess.Private) + fdef.With(customAttrs = mkILCustomAttrs [ cenv.g.DebuggerBrowsableNeverAttribute ]) ] + + // Generate property definitions for the fields compiled as properties + let ilProperties = + mkILProperties + [ for (i,(propName, _fldName, fldTy)) in List.indexed flds -> + ILPropertyDef(name=propName, + attributes=PropertyAttributes.None, + setMethod=None, + getMethod=Some(mkILMethRef(ilTypeRef,ILCallingConv.Instance,"get_" + propName,0,[],fldTy )), + callingConv=ILCallingConv.Instance.ThisConv, + propertyType=fldTy, + init= None, + args=[], + customAttrs=mkILCustomAttrs [ mkCompilationMappingAttrWithSeqNum cenv.g (int SourceConstructFlags.Field) i ]) ] + + let ilMethods = + [ for (propName, fldName, fldTy) in flds -> + mkLdfldMethodDef ("get_" + propName,ILMemberAccess.Public,false,ilTy,fldName,fldTy) + yield! genToStringMethod ilTy ] + + let ilBaseTy = (if isStruct then cenv.g.iltyp_ValueType else cenv.g.ilg.typ_Object) + + let ilCtorDef = mkILSimpleStorageCtorWithParamNames(None, (if isStruct then None else Some ilBaseTy.TypeSpec), ilTy, [], flds, ILMemberAccess.Public) + let ilCtorRef = mkRefToILMethod(ilTypeRef, ilCtorDef) + let ilMethodRefs = [| for mdef in ilMethods -> mkRefToILMethod(ilTypeRef, mdef) |] + + if ilTypeRef.Scope.IsLocalRef then + + // Create a tycon that looks exactly like a record definition, to help drive the generation of equality/comparison code + let m = range0 + let tps = + [ for nm in nms -> + let stp = Typar(mkSynId m ("T"+nm),TyparStaticReq.NoStaticReq,true) + NewTypar (TyparKind.Type, TyparRigidity.WarnIfNotRigid,stp,false,TyparDynamicReq.Yes,[],true,true) ] + + let tycon = + let lmtyp = MaybeLazy.Strict (NewEmptyModuleOrNamespaceType ModuleOrType) + let cpath = CompPath(ilTypeRef.Scope,[]) + NewTycon(Some cpath, ilTypeRef.Name, m, taccessPublic, taccessPublic, TyparKind.Type, LazyWithContext.NotLazy tps, XmlDoc.Empty, false, false, false, lmtyp) + + if isStruct then + tycon.SetIsStructRecordOrUnion(true) + + tycon.entity_tycon_repr <- + TRecdRepr (MakeRecdFieldsTable + [ for (tp, (propName, _fldName, _fldTy)) in (List.zip tps flds) -> + NewRecdField false None (mkSynId m propName) false (mkTyparTy tp) true false [] [] XmlDoc.Empty taccessPublic false ]) + + let tcref = mkLocalTyconRef tycon + let _,typ = generalizeTyconRef tcref + let tcaug = tcref.TypeContents + + tcaug.tcaug_interfaces <- + [ (cenv.g.mk_IStructuralComparable_ty,true,m) + (cenv.g.mk_IComparable_ty,true,m) + (mkAppTy cenv.g.system_GenericIComparable_tcref [typ],true,m) + (cenv.g.mk_IStructuralEquatable_ty,true,m) + (mkAppTy cenv.g.system_GenericIEquatable_tcref [typ],true,m) ] + + let vspec1,vspec2 = AugmentWithHashCompare.MakeValsForEqualsAugmentation cenv.g tcref + let evspec1,evspec2,evspec3 = AugmentWithHashCompare.MakeValsForEqualityWithComparerAugmentation cenv.g tcref + let cvspec1,cvspec2 = AugmentWithHashCompare.MakeValsForCompareAugmentation cenv.g tcref + let cvspec3 = AugmentWithHashCompare.MakeValsForCompareWithComparerAugmentation cenv.g tcref + + tcaug.SetCompare (mkLocalValRef cvspec1, mkLocalValRef cvspec2) + tcaug.SetCompareWith (mkLocalValRef cvspec3) + tcaug.SetEquals (mkLocalValRef vspec1, mkLocalValRef vspec2) + tcaug.SetHashAndEqualsWith (mkLocalValRef evspec1, mkLocalValRef evspec2, mkLocalValRef evspec3) + + // Build the ILTypeDef. We don't rely on the normal record generation process because we want very specific field names + + let ilTypeDefAttribs = mkILCustomAttrs [ cenv.g.CompilerGeneratedAttribute; mkCompilationMappingAttr cenv.g (int SourceConstructFlags.RecordType) ] + + let ilInterfaceTys = [ for (ity,_,_) in tcaug.tcaug_interfaces -> GenType cenv.amap m (TypeReprEnv.ForTypars tps) ity ] + + let ilTypeDef = + mkILGenericClass (ilTypeRef.Name, ILTypeDefAccess.Public, ilGenericParams, ilBaseTy, ilInterfaceTys, + mkILMethods (ilCtorDef :: ilMethods), ilFieldDefs, emptyILTypeDefs, + ilProperties, mkILEvents [], ilTypeDefAttribs, + ILTypeInit.BeforeField) + + let ilTypeDef = ilTypeDef.WithSealed(true).WithSerializable(true) + + mgbuf.AddTypeDef(ilTypeRef, ilTypeDef, false, true, None) + + let extraBindings = + [ yield! AugmentWithHashCompare.MakeBindingsForCompareAugmentation cenv.g tycon + yield! AugmentWithHashCompare.MakeBindingsForCompareWithComparerAugmentation cenv.g tycon + yield! AugmentWithHashCompare.MakeBindingsForEqualityWithComparerAugmentation cenv.g tycon + yield! AugmentWithHashCompare.MakeBindingsForEqualsAugmentation cenv.g tycon ] + + let optimizedExtraBindings = extraBindings |> List.map (fun (TBind(a,b,c)) -> TBind(a,cenv.optimizeDuringCodeGen b,c)) + + extraBindingsToGenerate <- optimizedExtraBindings @ extraBindingsToGenerate + + (ilCtorRef,ilMethodRefs,ilTy) + let mutable explicitEntryPointInfo : ILTypeRef option = None /// static init fields on script modules. @@ -1221,14 +1347,32 @@ type AssemblyBuilder(cenv:cenv) as mgbuf = scriptInitFspecs |> List.iter IntializeCompiledScript | None -> () - - member mgbuf.GenerateRawDataValueType(cloc,size) = // Byte array literals require a ValueType of size the required number of bytes. // With fsi.exe, S.R.Emit TypeBuilder CreateType has restrictions when a ValueType VT is nested inside a type T, and T has a field of type VT. // To avoid this situation, these ValueTypes are generated under the private implementation rather than in the current cloc. [was bug 1532]. let cloc = CompLocForPrivateImplementationDetails cloc - vtgenerator.Apply((cloc,size)) + rawDataValueTypeGenerator.Apply((cloc,size)) + + member mgbuf.GenerateAnonType(genToStringMethod, anonInfo:AnonRecdTypeInfo) = + let isStruct = evalAnonInfoIsStruct anonInfo + let key = anonInfo.Stamp + match anonTypeTable.Table.TryGetValue key with + | true, res -> res + | _ -> + let info = generateAnonType genToStringMethod (isStruct,anonInfo.ILTypeRef,anonInfo.SortedNames) + anonTypeTable.Table.[key] <- info + info + + member mgbuf.LookupAnonType(anonInfo:AnonRecdTypeInfo) = + match anonTypeTable.Table.TryGetValue anonInfo.Stamp with + | true, res -> res + | _ -> failwithf "the anonymous record %A has not been generated in the pre-phase of generating this module" anonInfo.ILTypeRef + + member mgbuf.GrabExtraBindingsToGenerate() = + let result = extraBindingsToGenerate + extraBindingsToGenerate <- [] + result member mgbuf.AddTypeDef(tref:ILTypeRef, tdef, eliminateIfEmpty, addAtEnd, tdefDiscards) = gtdefs.FindNestedTypeDefsBuilder(tref.Enclosing).AddTypeDef(tdef, eliminateIfEmpty, addAtEnd, tdefDiscards) @@ -1281,7 +1425,6 @@ type AssemblyBuilder(cenv:cenv) as mgbuf = member mgbuf.cenv = cenv member mgbuf.GetExplicitEntryPointInfo() = explicitEntryPointInfo - /// Record the types of the things on the evaluation stack. /// Used for the few times we have to flush the IL evaluation stack and to compute maxStack. @@ -1303,8 +1446,7 @@ let FeeFeeInstr (cenv:cenv) doc = type CodeGenBuffer(m:range, mgbuf: AssemblyBuilder, methodName, - alreadyUsedArgs:int, - alreadyUsedLocals:int) = + alreadyUsedArgs:int) = let locals = new ResizeArray<((string * (Mark * Mark)) list * ILType * bool)>(10) let codebuf = new ResizeArray(200) @@ -1466,16 +1608,13 @@ type CodeGenBuffer(m:range, j member cgbuf.ReallocLocal(cond,ranges,ty,isFixed) = - let j = - match ResizeArray.tryFindIndexi cond locals with - | Some j -> - let (prevRanges,_,isFixed) = locals.[j] - locals.[j] <- ((ranges@prevRanges),ty,isFixed) - j - | None -> - cgbuf.AllocLocal(ranges,ty,isFixed) - let j = j + alreadyUsedLocals - j + match ResizeArray.tryFindIndexi cond locals with + | Some j -> + let (prevRanges,_,isFixed) = locals.[j] + locals.[j] <- ((ranges@prevRanges),ty,isFixed) + j, true + | None -> + cgbuf.AllocLocal(ranges,ty,isFixed), false member cgbuf.Close() = @@ -1581,8 +1720,8 @@ let discardAndReturnVoid = DiscardThen ReturnVoid // the bodies of methods in a couple of places //------------------------------------------------------------------------- -let CodeGenThen cenv mgbuf (entryPointInfo,methodName,eenv,alreadyUsedArgs,alreadyUsedLocals,codeGenFunction,m) = - let cgbuf = new CodeGenBuffer(m,mgbuf,methodName,alreadyUsedArgs,alreadyUsedLocals) +let CodeGenThen cenv mgbuf (entryPointInfo,methodName,eenv,alreadyUsedArgs,codeGenFunction,m) = + let cgbuf = new CodeGenBuffer(m,mgbuf,methodName,alreadyUsedArgs) let start = CG.GenerateMark cgbuf "mstart" let innerVals = entryPointInfo |> List.map (fun (v,kind) -> (v,(kind,start))) @@ -1625,10 +1764,10 @@ let CodeGenThen cenv mgbuf (entryPointInfo,methodName,eenv,alreadyUsedArgs,alrea localDebugSpecs, hasSequencePoints) -let CodeGenMethod cenv mgbuf (entryPointInfo,methodName,eenv,alreadyUsedArgs,alreadyUsedLocals,codeGenFunction,m) = +let CodeGenMethod cenv mgbuf (entryPointInfo,methodName,eenv,alreadyUsedArgs,codeGenFunction,m) = let locals,maxStack,lab2pc,instrs,exns,localDebugSpecs,hasSequencePoints = - CodeGenThen cenv mgbuf (entryPointInfo,methodName,eenv,alreadyUsedArgs,alreadyUsedLocals,codeGenFunction,m) + CodeGenThen cenv mgbuf (entryPointInfo,methodName,eenv,alreadyUsedArgs,codeGenFunction,m) let code = IL.buildILCode methodName lab2pc instrs exns localDebugSpecs @@ -1899,13 +2038,17 @@ let rec GenExpr (cenv:cenv) (cgbuf:CodeGenBuffer) eenv sp expr sequel = | Expr.Val(v,_,m) -> GenGetVal cenv cgbuf eenv (v,m) sequel | Expr.Op(op,tyargs,args,m) -> - begin match op,args,tyargs with + match op,args,tyargs with | TOp.ExnConstr(c),_,_ -> GenAllocExn cenv cgbuf eenv (c,args,m) sequel | TOp.UnionCase(c),_,_ -> GenAllocUnionCase cenv cgbuf eenv (c,tyargs,args,m) sequel | TOp.Recd(isCtor,tycon),_,_ -> GenAllocRecd cenv cgbuf eenv isCtor (tycon,tyargs,args,m) sequel + | TOp.AnonRecd(anonInfo),_,_ -> + GenAllocAnonRecd cenv cgbuf eenv (anonInfo,tyargs,args,m) sequel + | TOp.AnonRecdGet (anonInfo,n),[e],_ -> + GenGetAnonRecdField cenv cgbuf eenv (anonInfo,e,tyargs,n,m) sequel | TOp.TupleFieldGet (tupInfo,n),[e],_ -> GenGetTupleField cenv cgbuf eenv (tupInfo,e,tyargs,n,m) sequel | TOp.ExnFieldGet(ecref,n),[e],_ -> @@ -1985,7 +2128,6 @@ let rec GenExpr (cenv:cenv) (cgbuf:CodeGenBuffer) eenv sp expr sequel = cgbuf.SetMarkToHere (Mark label) GenUnitThenSequel cenv eenv m eenv.cloc cgbuf sequel | _ -> error(InternalError("Unexpected operator node expression",expr.Range)) - end | Expr.StaticOptimization(constraints,e2,e3,m) -> GenStaticOptimization cenv cgbuf eenv (constraints,e2,e3,m) sequel | Expr.Obj(_,ty,_,_,[meth],[],m) when isDelegateTy cenv.g ty -> @@ -2000,9 +2142,9 @@ let rec GenExpr (cenv:cenv) (cgbuf:CodeGenBuffer) eenv sp expr sequel = and GenExprs cenv cgbuf eenv es = List.iter (fun e -> GenExpr cenv cgbuf eenv SPSuppress e Continue) es -and CodeGenMethodForExpr cenv mgbuf (spReq,entryPointInfo,methodName,eenv,alreadyUsedArgs,alreadyUsedLocals,expr0,sequel0) = +and CodeGenMethodForExpr cenv mgbuf (spReq,entryPointInfo,methodName,eenv,alreadyUsedArgs,expr0,sequel0) = let _,code = - CodeGenMethod cenv mgbuf (entryPointInfo,methodName,eenv,alreadyUsedArgs,alreadyUsedLocals, + CodeGenMethod cenv mgbuf (entryPointInfo,methodName,eenv,alreadyUsedArgs, (fun cgbuf eenv -> GenExpr cenv cgbuf eenv spReq expr0 sequel0), expr0.Range) code @@ -2230,6 +2372,24 @@ and GenAllocRecd cenv cgbuf eenv ctorInfo (tcref,argtys,args,m) sequel = (mkILCtorMethSpecForTy (ty,relevantFields |> List.map (fun f -> GenType cenv.amap m tyenvinner f.FormalType) ))) GenSequel cenv eenv.cloc cgbuf sequel +and GenAllocAnonRecd cenv cgbuf eenv (anonInfo: AnonRecdTypeInfo, tyargs, args, m) sequel = + let anonCtor, _anonMethods, anonType = cgbuf.mgbuf.LookupAnonType(anonInfo) + let boxity = anonType.Boxity + GenExprs cenv cgbuf eenv args + let ilTypeArgs = GenTypeArgs cenv.amap m eenv.tyenv tyargs + let anonTypeWithInst = mkILTy boxity (mkILTySpec(anonType.TypeSpec.TypeRef,ilTypeArgs)) + CG.EmitInstr cgbuf (pop args.Length) (Push [anonTypeWithInst]) (mkNormalNewobj (mkILMethSpec(anonCtor,boxity,ilTypeArgs,[]))) + GenSequel cenv eenv.cloc cgbuf sequel + +and GenGetAnonRecdField cenv cgbuf eenv (anonInfo: AnonRecdTypeInfo, e, tyargs, n, m) sequel = + let _anonCtor, anonMethods, anonType = cgbuf.mgbuf.LookupAnonType(anonInfo) + let boxity = anonType.Boxity + let ilTypeArgs = GenTypeArgs cenv.amap m eenv.tyenv tyargs + let anonMethod = anonMethods.[n] + let anonFieldType = ilTypeArgs.[n] + GenExpr cenv cgbuf eenv SPSuppress e Continue + CG.EmitInstr cgbuf (pop 1) (Push [anonFieldType]) (mkNormalCall (mkILMethSpec(anonMethod,boxity,ilTypeArgs,[]))) + GenSequel cenv eenv.cloc cgbuf sequel and GenNewArraySimple cenv cgbuf eenv (elems,elemTy,m) sequel = let ilElemTy = GenType cenv.amap m eenv.tyenv elemTy @@ -2685,7 +2845,7 @@ and GenApp cenv cgbuf eenv (f,fty,tyargs,args,m) sequel = // Only save arguments that have effects if Optimizer.ExprHasEffect cenv.g laterArg then let ilTy = laterArg |> tyOfExpr cenv.g |> GenType cenv.amap m eenv.tyenv - let loc,eenv = AllocLocal cenv cgbuf eenv true (ilxgenGlobalNng.FreshCompilerGeneratedName ("arg",m), ilTy, false) scopeMarks + let loc, _realloc, eenv = AllocLocal cenv cgbuf eenv true (ilxgenGlobalNng.FreshCompilerGeneratedName ("arg",m), ilTy, false) scopeMarks GenExpr cenv cgbuf eenv SPSuppress laterArg Continue EmitSetLocal cgbuf loc Choice1Of2 (ilTy,loc),eenv @@ -2841,7 +3001,7 @@ and GenTry cenv cgbuf eenv scopeMarks (e1,m,resty,spTry) = let afterHandler = CG.GenerateDelayMark cgbuf "afterHandler" let eenvinner = {eenvinner with withinSEH = true} let ilResultTy = GenType cenv.amap m eenvinner.tyenv resty - let whereToSave,eenvinner = AllocLocal cenv cgbuf eenvinner true (ilxgenGlobalNng.FreshCompilerGeneratedName ("tryres",m),ilResultTy, false) (startTryMark,endTryMark) + let whereToSave, _realloc, eenvinner = AllocLocal cenv cgbuf eenvinner true (ilxgenGlobalNng.FreshCompilerGeneratedName ("tryres",m),ilResultTy, false) (startTryMark,endTryMark) // Generate the body of the try. In the normal case (SequencePointAtTry) we generate a sequence point // both on the 'try' keyword and on the start of the expression in the 'try'. For inlined code and @@ -3001,7 +3161,7 @@ and GenForLoop cenv cgbuf eenv (spFor,v,e1,dir,e2,loopBody,m) sequel = let finishIdx,eenvinner = if isFSharpStyle then - let v,eenvinner = AllocLocal cenv cgbuf eenvinner true (ilxgenGlobalNng.FreshCompilerGeneratedName ("endLoop",m), cenv.g.ilg.typ_Int32, false) (start,finish) + let v, _realloc, eenvinner = AllocLocal cenv cgbuf eenvinner true (ilxgenGlobalNng.FreshCompilerGeneratedName ("endLoop",m), cenv.g.ilg.typ_Int32, false) (start,finish) v, eenvinner else -1,eenvinner @@ -3394,7 +3554,7 @@ and GenGetValAddr cenv cgbuf eenv (v: ValRef, m) sequel = let ilTy = GenTypeOfVal cenv eenv vspec let storage = StorageForValRef m v eenv match storage with - | Local (idx,None) -> + | Local (idx, _, None) -> CG.EmitInstrs cgbuf (pop 0) (Push [ILType.Byref ilTy]) [ I_ldloca (uint16 idx) ] | Arg idx -> CG.EmitInstrs cgbuf (pop 0) (Push [ILType.Byref ilTy]) [ I_ldarga (uint16 idx) ] @@ -3404,7 +3564,7 @@ and GenGetValAddr cenv cgbuf eenv (v: ValRef, m) sequel = EmitGetStaticFieldAddr cgbuf ilTy fspec | Env (_,_,ilField,_) -> CG.EmitInstrs cgbuf (pop 0) (Push [ILType.Byref ilTy]) [ mkLdarg0; mkNormalLdflda ilField ] - | Local (_,Some _) | StaticProperty _ | Method _ | Env _ | Null -> + | Local (_, _, Some _) | StaticProperty _ | Method _ | Env _ | Null -> errorR(Error(FSComp.SR.ilAddressOfValueHereIsInvalid(v.DisplayName),m)) CG.EmitInstrs cgbuf (pop 1) (Push [ILType.Byref ilTy]) [ I_ldarga (uint16 669 (* random value for post-hoc diagnostic analysis on generated tree *) ) ] ; @@ -3429,32 +3589,33 @@ and GenDefaultValue cenv cgbuf eenv (ty,m) = CG.EmitInstr cgbuf (pop 0) (Push [ilTy]) AI_ldnull else match tryDestAppTy cenv.g ty with - | Some tcref when (tyconRefEq cenv.g cenv.g.system_SByte_tcref tcref || - tyconRefEq cenv.g cenv.g.system_Int16_tcref tcref || - tyconRefEq cenv.g cenv.g.system_Int32_tcref tcref || - tyconRefEq cenv.g cenv.g.system_Bool_tcref tcref || - tyconRefEq cenv.g cenv.g.system_Byte_tcref tcref || - tyconRefEq cenv.g cenv.g.system_Char_tcref tcref || - tyconRefEq cenv.g cenv.g.system_UInt16_tcref tcref || - tyconRefEq cenv.g cenv.g.system_UInt32_tcref tcref) -> + | ValueSome tcref when (tyconRefEq cenv.g cenv.g.system_SByte_tcref tcref || + tyconRefEq cenv.g cenv.g.system_Int16_tcref tcref || + tyconRefEq cenv.g cenv.g.system_Int32_tcref tcref || + tyconRefEq cenv.g cenv.g.system_Bool_tcref tcref || + tyconRefEq cenv.g cenv.g.system_Byte_tcref tcref || + tyconRefEq cenv.g cenv.g.system_Char_tcref tcref || + tyconRefEq cenv.g cenv.g.system_UInt16_tcref tcref || + tyconRefEq cenv.g cenv.g.system_UInt32_tcref tcref) -> CG.EmitInstr cgbuf (pop 0) (Push [ilTy]) iLdcZero - | Some tcref when (tyconRefEq cenv.g cenv.g.system_Int64_tcref tcref || - tyconRefEq cenv.g cenv.g.system_UInt64_tcref tcref) -> + | ValueSome tcref when (tyconRefEq cenv.g cenv.g.system_Int64_tcref tcref || + tyconRefEq cenv.g cenv.g.system_UInt64_tcref tcref) -> CG.EmitInstr cgbuf (pop 0) (Push [ilTy]) (iLdcInt64 0L) - | Some tcref when (tyconRefEq cenv.g cenv.g.system_Single_tcref tcref) -> + | ValueSome tcref when (tyconRefEq cenv.g cenv.g.system_Single_tcref tcref) -> CG.EmitInstr cgbuf (pop 0) (Push [ilTy]) (iLdcSingle 0.0f) - | Some tcref when (tyconRefEq cenv.g cenv.g.system_Double_tcref tcref) -> + | ValueSome tcref when (tyconRefEq cenv.g cenv.g.system_Double_tcref tcref) -> CG.EmitInstr cgbuf (pop 0) (Push [ilTy]) (iLdcDouble 0.0) | _ -> let ilTy = GenType cenv.amap m eenv.tyenv ty LocalScope "ilzero" cgbuf (fun scopeMarks -> - let locIdx, _ = AllocLocal cenv cgbuf eenv true (ilxgenGlobalNng.FreshCompilerGeneratedName ("default",m), ilTy, false) scopeMarks + let locIdx, realloc, _ = AllocLocal cenv cgbuf eenv true (ilxgenGlobalNng.FreshCompilerGeneratedName ("default",m), ilTy, false) scopeMarks // "initobj" (Generated by EmitInitLocal) doesn't work on byref types // But ilzero(&ty) only gets generated in the built-in get-address function so // we can just rely on zeroinit of all IL locals. - match ilTy with - | ILType.Byref _ -> () - | _ -> EmitInitLocal cgbuf ilTy locIdx + if realloc then + match ilTy with + | ILType.Byref _ -> () + | _ -> EmitInitLocal cgbuf ilTy locIdx EmitGetLocal cgbuf ilTy locIdx ) @@ -3599,7 +3760,7 @@ and GenObjectMethod cenv eenvinner (cgbuf:CodeGenBuffer) useMethodImpl tmethod = // Args are stored starting at #1 let eenvForMeth = AddStorageForLocalVals cenv.g (methodParams |> List.mapi (fun i v -> (v,Arg i))) eenvUnderTypars - let ilMethodBody = CodeGenMethodForExpr cenv cgbuf.mgbuf (SPAlways,[],nameOfOverridenMethod,eenvForMeth,0,0,methodBodyExpr,(if slotSigHasVoidReturnTy slotsig then discardAndReturnVoid else Return)) + let ilMethodBody = CodeGenMethodForExpr cenv cgbuf.mgbuf (SPAlways,[],nameOfOverridenMethod,eenvForMeth,0,methodBodyExpr,(if slotSigHasVoidReturnTy slotsig then discardAndReturnVoid else Return)) let nameOfOverridingMethod,methodImplGenerator = GenMethodImpl cenv eenvinner (useMethodImpl,slotsig) methodBodyExpr.Range @@ -3635,8 +3796,7 @@ and GenObjectExpr cenv cgbuf eenvouter expr (baseType,baseValOpt,basecall,overri let ilTyForOverriding = mkILBoxedTy ilCloTypeRef ilCloGenericActuals let eenvinner = bindBaseOrThisVarOpt cenv eenvinner baseValOpt - let ilCtorBody = CodeGenMethodForExpr cenv cgbuf.mgbuf (SPAlways,[],cloName,eenvinner,1,0,basecall,discardAndReturnVoid) - + let ilCtorBody = CodeGenMethodForExpr cenv cgbuf.mgbuf (SPAlways,[],cloName,eenvinner,1,basecall,discardAndReturnVoid) let genMethodAndOptionalMethodImpl tmethod useMethodImpl = [ for ((useMethodImpl,methodImplGeneratorFunction,methTyparsOfOverridingMethod),mdef) in GenObjectMethod cenv eenvinner cgbuf useMethodImpl tmethod do @@ -3673,7 +3833,7 @@ and GenSequenceExpr cenv (cgbuf:CodeGenBuffer) eenvouter (nextEnumeratorValRef:V // pretend that the state variables are bound let eenvouter = - eenvouter |> AddStorageForLocalVals cenv.g (stateVars |> List.map (fun v -> v.Deref,Local(0,None))) + eenvouter |> AddStorageForLocalVals cenv.g (stateVars |> List.map (fun v -> v.Deref, Local(0, false, None))) // Get the free variables. Make a lambda to pretend that the 'nextEnumeratorValRef' is bound (it is an argument to GenerateNext) let (cloAttribs,_,_,cloFreeTyvars,cloFreeVars,ilCloTypeRef:ILTypeRef,ilCloFreeVars,eenvinner) = @@ -3697,15 +3857,9 @@ and GenSequenceExpr cenv (cgbuf:CodeGenBuffer) eenvouter (nextEnumeratorValRef:V let getFreshMethod = let _,mbody = - CodeGenMethod cenv cgbuf.mgbuf ([],"GetFreshEnumerator",eenvinner,1,0, + CodeGenMethod cenv cgbuf.mgbuf ([],"GetFreshEnumerator",eenvinner,1, (fun cgbuf eenv -> for fv in cloFreeVars do -(* TODO: Emit CompareExchange - if (System.Threading.Interlocked.CompareExchange(&__state, 1, 0) = 0) then - (x :> IEnumerator<'T>) - else - ... -*) /// State variables always get zero-initialized if stateVarsSet.Contains fv then GenDefaultValue cenv cgbuf eenv (fv.Type,m) @@ -3720,22 +3874,22 @@ and GenSequenceExpr cenv (cgbuf:CodeGenBuffer) eenvouter (nextEnumeratorValRef:V let closeMethod = // Note: We suppress the first sequence point in the body of this method since it is the initial state machine jump let spReq = SPSuppress - mkILNonGenericVirtualMethod("Close",ILMemberAccess.Public, [], mkILReturn ILType.Void, MethodBody.IL (CodeGenMethodForExpr cenv cgbuf.mgbuf (spReq,[],"Close",eenvinner,1,0,closeExpr,discardAndReturnVoid))) + mkILNonGenericVirtualMethod("Close",ILMemberAccess.Public, [], mkILReturn ILType.Void, MethodBody.IL (CodeGenMethodForExpr cenv cgbuf.mgbuf (spReq,[],"Close",eenvinner,1,closeExpr,discardAndReturnVoid))) let checkCloseMethod = // Note: We suppress the first sequence point in the body of this method since it is the initial state machine jump let spReq = SPSuppress - mkILNonGenericVirtualMethod("get_CheckClose",ILMemberAccess.Public, [], mkILReturn cenv.g.ilg.typ_Bool, MethodBody.IL (CodeGenMethodForExpr cenv cgbuf.mgbuf (spReq,[],"get_CheckClose",eenvinner,1,0,checkCloseExpr,Return))) + mkILNonGenericVirtualMethod("get_CheckClose",ILMemberAccess.Public, [], mkILReturn cenv.g.ilg.typ_Bool, MethodBody.IL (CodeGenMethodForExpr cenv cgbuf.mgbuf (spReq,[],"get_CheckClose",eenvinner,1,checkCloseExpr,Return))) let generateNextMethod = // Note: We suppress the first sequence point in the body of this method since it is the initial state machine jump let spReq = SPSuppress // the 'next enumerator' byref arg is at arg position 1 let eenvinner = eenvinner |> AddStorageForLocalVals cenv.g [ (nextEnumeratorValRef.Deref, Arg 1) ] - mkILNonGenericVirtualMethod("GenerateNext",ILMemberAccess.Public, [mkILParamNamed("next",ILType.Byref ilCloEnumerableTy)], mkILReturn cenv.g.ilg.typ_Int32, MethodBody.IL (CodeGenMethodForExpr cenv cgbuf.mgbuf (spReq,[],"GenerateNext",eenvinner,2,0,generateNextExpr,Return))) + mkILNonGenericVirtualMethod("GenerateNext",ILMemberAccess.Public, [mkILParamNamed("next",ILType.Byref ilCloEnumerableTy)], mkILReturn cenv.g.ilg.typ_Int32, MethodBody.IL (CodeGenMethodForExpr cenv cgbuf.mgbuf (spReq,[],"GenerateNext",eenvinner,2,generateNextExpr,Return))) let lastGeneratedMethod = - mkILNonGenericVirtualMethod("get_LastGenerated",ILMemberAccess.Public, [], mkILReturn ilCloSeqElemTy, MethodBody.IL (CodeGenMethodForExpr cenv cgbuf.mgbuf (SPSuppress,[],"get_LastGenerated",eenvinner,1,0,exprForValRef m currvref,Return))) + mkILNonGenericVirtualMethod("get_LastGenerated",ILMemberAccess.Public, [], mkILReturn ilCloSeqElemTy, MethodBody.IL (CodeGenMethodForExpr cenv cgbuf.mgbuf (SPSuppress,[],"get_LastGenerated",eenvinner,1,exprForValRef m currvref,Return))) |> AddNonUserCompilerGeneratedAttribs cenv.g let ilCtorBody = @@ -3802,13 +3956,14 @@ and GenLambdaClosure cenv (cgbuf:CodeGenBuffer) eenv isLocalTypeFunc selfv expr | Expr.Lambda (_,_,_,_,_,m,_) | Expr.TyLambda(_,_,_,m,_) -> - let cloinfo,body,eenvinner = GetIlxClosureInfo cenv m isLocalTypeFunc selfv eenv expr + let cloinfo,body,eenvinner = GetIlxClosureInfo cenv m isLocalTypeFunc selfv eenv expr let entryPointInfo = match selfv with | Some v -> [(v, BranchCallClosure (cloinfo.cloArityInfo))] | _ -> [] - let ilCloBody = CodeGenMethodForExpr cenv cgbuf.mgbuf (SPAlways,entryPointInfo,cloinfo.cloName,eenvinner,1,0,body,Return) + + let ilCloBody = CodeGenMethodForExpr cenv cgbuf.mgbuf (SPAlways,entryPointInfo,cloinfo.cloName,eenvinner,1,body,Return) let ilCloTypeRef = cloinfo.cloSpec.TypeRef let cloTypeDefs = if isLocalTypeFunc then @@ -3869,7 +4024,7 @@ and GenTypeOfVal cenv eenv (v:Val) = and GenFreevar cenv m eenvouter tyenvinner (fv:Val) = match StorageForVal m fv eenvouter with // Local type functions - | Local(_,Some _) | Env(_,_,_,Some _) -> cenv.g.ilg.typ_Object + | Local(_, _, Some _) | Env(_,_,_,Some _) -> cenv.g.ilg.typ_Object #if DEBUG // Check for things that should never make it into the free variable set. Only do this in debug for performance reasons | (StaticField _ | StaticProperty _ | Method _ | Null) -> error(InternalError("GenFreevar: compiler error: unexpected unrealized value",fv.Range)) @@ -3957,7 +4112,7 @@ and GetIlxClosureFreeVars cenv m selfv eenvouter takenNames expr = (cloFreeVars,ilCloFreeVars) ||> List.mapi2 (fun i v fv -> let localCloInfo = match StorageForVal m v eenvouter with - | Local(_,localCloInfo) + | Local(_, _, localCloInfo) | Env(_,_,_,localCloInfo) -> localCloInfo | _ -> None let ilField = mkILFieldSpecInTy (ilCloTyInner,fv.fvName,fv.fvType) @@ -3971,7 +4126,7 @@ and GetIlxClosureFreeVars cenv m selfv eenvouter takenNames expr = (cloAttribs,cloInternalFreeTyvars,cloContractFreeTyvars,cloFreeTyvars,cloFreeVars,ilCloTypeRef,Array.ofList ilCloFreeVars,eenvinner) -and GetIlxClosureInfo cenv m isLocalTypeFunc selfv eenvouter expr = +and GetIlxClosureInfo cenv m isLocalTypeFunc selfv eenvouter expr = let returnTy = match expr with | Expr.Lambda (_,_,_,_,_,_,returnTy) | Expr.TyLambda(_,_,_,_,returnTy) -> returnTy @@ -4171,7 +4326,7 @@ and GenDelegateExpr cenv cgbuf eenvouter expr (TObjExprMethod((TSlotSig(_,delega let ilDelegeeParams,ilDelegeeRet = GenActualSlotsig m cenv envForDelegeeUnderTypars slotsig methTyparsOfOverridingMethod tmvs let envForDelegeeMeth = AddStorageForLocalVals cenv.g (List.mapi (fun i v -> (v,Arg (i+numthis))) tmvs) envForDelegeeUnderTypars - let ilMethodBody = CodeGenMethodForExpr cenv cgbuf.mgbuf (SPAlways,[],delegeeMethName,envForDelegeeMeth,1,0,body,(if slotSigHasVoidReturnTy slotsig then discardAndReturnVoid else Return)) + let ilMethodBody = CodeGenMethodForExpr cenv cgbuf.mgbuf (SPAlways,[],delegeeMethName,envForDelegeeMeth,1,body,(if slotSigHasVoidReturnTy slotsig then discardAndReturnVoid else Return)) let delegeeInvokeMeth = mkILNonGenericInstanceMethod (delegeeMethName,ILMemberAccess.Assembly, @@ -4625,7 +4780,7 @@ and GenLetRecFixup cenv cgbuf eenv (ilxCloSpec:IlxClosureSpec,e,ilField:ILFieldS GenExpr cenv cgbuf eenv SPSuppress e2 Continue CG.EmitInstrs cgbuf (pop 2) Push0 [ mkNormalStfld (mkILFieldSpec(ilField.FieldRef,ilxCloSpec.ILType)) ] -and GenLetRecBindings cenv cgbuf eenv (allBinds: Bindings,m) = +and GenLetRecBindings cenv (cgbuf:CodeGenBuffer) eenv (allBinds: Bindings,m) = // Fix up recursion for non-toplevel recursive bindings let bindsPossiblyRequiringFixup = allBinds |> List.filter (fun b -> @@ -4772,7 +4927,7 @@ and GenBindingAfterSequencePoint cenv cgbuf eenv sp (TBind(vspec,rhsExpr,_)) sta cgbuf.mgbuf.AddOrMergePropertyDef(ilGetterMethSpec.MethodRef.DeclaringTypeRef, ilPropDef,m) let ilMethodDef = - let ilMethodBody = MethodBody.IL(CodeGenMethodForExpr cenv cgbuf.mgbuf (SPSuppress, [], ilGetterMethSpec.Name, eenv, 0, 0, rhsExpr, Return)) + let ilMethodBody = MethodBody.IL(CodeGenMethodForExpr cenv cgbuf.mgbuf (SPSuppress, [], ilGetterMethSpec.Name, eenv, 0, rhsExpr, Return)) (mkILStaticMethod ([], ilGetterMethSpec.Name, access, [], mkILReturn ilTy, ilMethodBody)).WithSpecialName |> AddNonUserCompilerGeneratedAttribs cenv.g @@ -4865,9 +5020,15 @@ and GenBindingAfterSequencePoint cenv cgbuf eenv sp (TBind(vspec,rhsExpr,_)) sta GenSetStorage m cgbuf storage | _ -> - GenBindingRhs cenv cgbuf eenv SPSuppress vspec rhsExpr - CommitStartScope cgbuf startScopeMarkOpt - GenStoreVal cgbuf eenv vspec.Range vspec + let storage = StorageForVal m vspec eenv + match storage, rhsExpr with + // locals are zero-init, no need to initialize them + | Local (_, realloc, _), Expr.Const(Const.Zero,_,_) when not realloc -> + CommitStartScope cgbuf startScopeMarkOpt + | _ -> + GenBindingRhs cenv cgbuf eenv SPSuppress vspec rhsExpr + CommitStartScope cgbuf startScopeMarkOpt + GenStoreVal cgbuf eenv vspec.Range vspec //------------------------------------------------------------------------- // Generate method bindings @@ -5115,28 +5276,35 @@ and ComputeFlagFixupsForMemberBinding cenv (v:Val,memberInfo:ValMemberInfo) = else memberInfo.ImplementedSlotSigs |> List.map (fun slotsig -> let oty = slotsig.ImplementedType - let otcref,_ = destAppTy cenv.g oty + let otcref = tcrefOfAppTy cenv.g oty let tcref = v.MemberApparentEntity - let useMethodImpl = - // REVIEW: it would be good to get rid of this special casing of Compare and GetHashCode during code generation - let isCompare = - (Option.isSome tcref.GeneratedCompareToValues && typeEquiv cenv.g oty cenv.g.mk_IComparable_ty) || - (Option.isSome tcref.GeneratedCompareToValues && tyconRefEq cenv.g cenv.g.system_GenericIComparable_tcref otcref) - - let isGenericEquals = - (Option.isSome tcref.GeneratedHashAndEqualsWithComparerValues && tyconRefEq cenv.g cenv.g.system_GenericIEquatable_tcref otcref) - - let isStructural = - (Option.isSome tcref.GeneratedCompareToWithComparerValues && typeEquiv cenv.g oty cenv.g.mk_IStructuralComparable_ty) || - (Option.isSome tcref.GeneratedHashAndEqualsWithComparerValues && typeEquiv cenv.g oty cenv.g.mk_IStructuralEquatable_ty) - isInterfaceTy cenv.g oty && not isCompare && not isStructural && not isGenericEquals + let useMethodImpl = + // REVIEW: it would be good to get rid of this special casing of Compare and GetHashCode during code generation + isInterfaceTy cenv.g oty && + (let isCompare = + Option.isSome tcref.GeneratedCompareToValues && + (typeEquiv cenv.g oty cenv.g.mk_IComparable_ty || + tyconRefEq cenv.g cenv.g.system_GenericIComparable_tcref otcref) + + not isCompare) && + (let isGenericEquals = + Option.isSome tcref.GeneratedHashAndEqualsWithComparerValues && tyconRefEq cenv.g cenv.g.system_GenericIEquatable_tcref otcref + + not isGenericEquals) && + (let isStructural = + (Option.isSome tcref.GeneratedCompareToWithComparerValues && typeEquiv cenv.g oty cenv.g.mk_IStructuralComparable_ty) || + (Option.isSome tcref.GeneratedHashAndEqualsWithComparerValues && typeEquiv cenv.g oty cenv.g.mk_IStructuralEquatable_ty) + + not isStructural) let nameOfOverridingMethod = GenNameOfOverridingMethod cenv (useMethodImpl,slotsig) - (if useMethodImpl then fixupMethodImplFlags >> renameMethodDef nameOfOverridingMethod - else fixupVirtualSlotFlags >> renameMethodDef nameOfOverridingMethod)) + if useMethodImpl then + fixupMethodImplFlags >> renameMethodDef nameOfOverridingMethod + else + fixupVirtualSlotFlags >> renameMethodDef nameOfOverridingMethod) and ComputeMethodImplAttribs cenv (_v:Val) attrs = let implflags = @@ -5231,7 +5399,7 @@ and GenMethodForBinding // This is the main code generation for most methods false, - MethodBody.IL(CodeGenMethodForExpr cenv cgbuf.mgbuf (SPAlways,tailCallInfo, mspec.Name, eenvForMeth, 0, 0, bodyExpr, sequel)), + MethodBody.IL(CodeGenMethodForExpr cenv cgbuf.mgbuf (SPAlways,tailCallInfo, mspec.Name, eenvForMeth, 0, bodyExpr, sequel)), false // Do not generate DllImport attributes into the code - they are implicit from the P/Invoke @@ -5253,7 +5421,7 @@ and GenMethodForBinding let securityAttributes,attrs = attrs |> List.partition (fun a -> IsSecurityAttribute cenv.g cenv.amap cenv.casApplied a m) - let permissionSets = CreatePermissionSets cenv.g cenv.amap eenv securityAttributes + let permissionSets = CreatePermissionSets cenv eenv securityAttributes let secDecls = if List.isEmpty securityAttributes then emptyILSecurityDecls else mkILSecurityDecls permissionSets @@ -5487,16 +5655,24 @@ and EmitGetStaticField cgbuf ty fspec = CG.EmitInstr cgbuf (pop 0) (Push [ty]) ( and GenSetStorage m cgbuf storage = match storage with - | Local (idx,_) -> EmitSetLocal cgbuf idx + | Local (idx, _, _) -> + EmitSetLocal cgbuf idx + | StaticField (_, _, hasLiteralAttr, ilContainerTy, _, _, _, ilSetterMethRef, _) -> if hasLiteralAttr then errorR(Error(FSComp.SR.ilLiteralFieldsCannotBeSet(),m)) CG.EmitInstr cgbuf (pop 1) Push0 (I_call(Normalcall,mkILMethSpecForMethRefInTy(ilSetterMethRef,ilContainerTy,[]),None)) + | StaticProperty (ilGetterMethSpec,_) -> error(Error(FSComp.SR.ilStaticMethodIsNotLambda(ilGetterMethSpec.Name),m)) + | Method (_,_,mspec,m,_,_,_) -> error(Error(FSComp.SR.ilStaticMethodIsNotLambda(mspec.Name),m)) - | Null -> CG.EmitInstr cgbuf (pop 1) Push0 AI_pop - | Arg _ -> error(Error(FSComp.SR.ilMutableVariablesCannotEscapeMethod(),m)) + + | Null -> + CG.EmitInstr cgbuf (pop 1) Push0 AI_pop + + | Arg _ -> + error(Error(FSComp.SR.ilMutableVariablesCannotEscapeMethod(),m)) | Env (_,_,ilField,_) -> // Note: ldarg0 has already been emitted in GenSetVal @@ -5516,7 +5692,7 @@ and CommitGetStorageSequel cenv cgbuf eenv m ty localCloInfo storeSequel = and GenGetStorageAndSequel cenv cgbuf eenv m (ty,ilTy) storage storeSequel = match storage with - | Local (idx,localCloInfo) -> + | Local (idx, _, localCloInfo) -> EmitGetLocal cgbuf ilTy idx CommitGetStorageSequel cenv cgbuf eenv m ty localCloInfo storeSequel @@ -5585,11 +5761,12 @@ and AllocLocal cenv cgbuf eenv compgen (v,ty,isFixed) (scopeMarks: Mark * Mark) // The debug range for the local let ranges = if compgen then [] else [(v,scopeMarks)] // Get an index for the local - let j = - if cenv.opts.localOptimizationsAreOn - then cgbuf.ReallocLocal((fun i (_,ty',isFixed') -> not isFixed' && not isFixed && not (IntMap.mem i eenv.liveLocals) && (ty = ty')),ranges,ty,isFixed) - else cgbuf.AllocLocal(ranges,ty,isFixed) - j, { eenv with liveLocals = IntMap.add j () eenv.liveLocals } + let j, realloc = + if cenv.opts.localOptimizationsAreOn then + cgbuf.ReallocLocal((fun i (_,ty',isFixed') -> not isFixed' && not isFixed && not (IntMap.mem i eenv.liveLocals) && (ty = ty')),ranges,ty,isFixed) + else + cgbuf.AllocLocal(ranges,ty,isFixed), false + j, realloc, { eenv with liveLocals = IntMap.add j () eenv.liveLocals } and AllocLocalVal cenv cgbuf v eenv repr scopeMarks = let repr,eenv = @@ -5604,12 +5781,12 @@ and AllocLocalVal cenv cgbuf v eenv repr scopeMarks = let cloinfo,_,_ = GetIlxClosureInfo cenv v.Range true None eenvinner (Option.get repr) cloinfo - let idx,eenv = AllocLocal cenv cgbuf eenv v.IsCompilerGenerated (v.CompiledName, cenv.g.ilg.typ_Object, false) scopeMarks - Local (idx,Some(ref (NamedLocalIlxClosureInfoGenerator cloinfoGenerate))),eenv + let idx, realloc, eenv = AllocLocal cenv cgbuf eenv v.IsCompilerGenerated (v.CompiledName, cenv.g.ilg.typ_Object, false) scopeMarks + Local (idx, realloc, Some(ref (NamedLocalIlxClosureInfoGenerator cloinfoGenerate))),eenv else (* normal local *) - let idx,eenv = AllocLocal cenv cgbuf eenv v.IsCompilerGenerated (v.CompiledName, GenTypeOfVal cenv eenv v, v.IsFixed) scopeMarks - Local (idx,None),eenv + let idx, realloc, eenv = AllocLocal cenv cgbuf eenv v.IsCompilerGenerated (v.CompiledName, GenTypeOfVal cenv eenv v, v.IsFixed) scopeMarks + Local (idx,realloc, None),eenv let eenv = AddStorageForVal cenv.g (v,notlazy repr) eenv Some repr, eenv @@ -5626,7 +5803,7 @@ and AllocStorageForBinds cenv cgbuf scopeMarks eenv binds = match reprOpt with | Some repr -> match repr with - | Local(_,Some g) + | Local(_, _, Some g) | Env(_,_,_,Some g) -> match !g with | NamedLocalIlxClosureInfoGenerator f -> g := NamedLocalIlxClosureInfoGenerated (f eenv) @@ -5677,7 +5854,10 @@ and AllocTopValWithinExpr cenv cgbuf cloc scopeMarks v eenv = /// - and because IL requires empty stack following a forward br (jump). and EmitSaveStack cenv cgbuf eenv m scopeMarks = let savedStack = (cgbuf.GetCurrentStack()) - let savedStackLocals,eenvinner = List.mapFold (fun eenv ty -> AllocLocal cenv cgbuf eenv true (ilxgenGlobalNng.FreshCompilerGeneratedName ("spill",m), ty, false) scopeMarks) eenv savedStack + let savedStackLocals,eenvinner = + (eenv, savedStack) ||> List.mapFold (fun eenv ty -> + let idx, _realloc, eenv = AllocLocal cenv cgbuf eenv true (ilxgenGlobalNng.FreshCompilerGeneratedName ("spill",m), ty, false) scopeMarks + idx, eenv) List.iter (EmitSetLocal cgbuf) savedStackLocals cgbuf.AssertEmptyStack() (savedStack,savedStackLocals),eenvinner (* need to return, it marks locals "live" *) @@ -5802,18 +5982,18 @@ and GenCompilationArgumentCountsAttr cenv (v:Val) = () ] // Create a permission set for a list of security attributes -and CreatePermissionSets g amap eenv (securityAttributes : Attrib list) = +and CreatePermissionSets cenv eenv (securityAttributes : Attrib list) = [for ((Attrib(tcref,_,actions,_,_,_,_)) as attr) in securityAttributes do let action = match actions with | [AttribInt32Arg act] -> act | _ -> failwith "internal error: unrecognized security action" let secaction = (List.assoc action (Lazy.force ILSecurityActionRevMap)) let tref = tcref.CompiledRepresentationForNamedType - let ilattr = GenAttr amap g eenv attr + let ilattr = GenAttr cenv.amap cenv.g eenv attr let _, ilNamedArgs = - match TryDecodeILAttribute g tref (mkILCustomAttrs [ilattr]) with + match TryDecodeILAttribute cenv.g tref (mkILCustomAttrs [ilattr]) with | Some(ae,na) -> ae, na | _ -> [],[] let setArgs = ilNamedArgs |> List.map (fun (n,ilt,_,ilae) -> (n,ilt,ilae)) - yield IL.mkPermissionSet g.ilg (secaction, [(tref, setArgs)])] + yield IL.mkPermissionSet cenv.g.ilg (secaction, [(tref, setArgs)])] //-------------------------------------------------------------------------- // Generate the set of modules for an assembly, and the declarations in each module @@ -5919,7 +6099,14 @@ and GenModuleBinding cenv (cgbuf:CodeGenBuffer) (qname:QualifiedNameOfFile) lazy /// Generate the namespace fragments in a single file -and GenTopImpl cenv mgbuf mainInfoOpt eenv (TImplFile(qname, _, mexpr, hasExplicitEntryPoint, isScript), optimizeDuringCodeGen) = +and GenTopImpl cenv (mgbuf: AssemblyBuilder) mainInfoOpt eenv (TImplFile(qname, _, mexpr, hasExplicitEntryPoint, isScript, anonRecdTypes), optimizeDuringCodeGen) = + + let m = qname.Range + + // Generate all the anonymous record types mentioned anywhere in this module + for anonInfo in anonRecdTypes.Values do + mgbuf.GenerateAnonType((fun ilThisTy -> GenToStringMethod cenv eenv ilThisTy m), anonInfo) |> ignore + let eenv = {eenv with cloc = { eenv.cloc with clocTopImplQualifiedName = qname.Text } } cenv.optimizeDuringCodeGen <- optimizeDuringCodeGen @@ -5949,7 +6136,6 @@ and GenTopImpl cenv mgbuf mainInfoOpt eenv (TImplFile(qname, _, mexpr, hasExplic let lazyInitInfo = new ResizeArray ILInstr list -> ILInstr list -> unit>() // codegen .cctor/main for outer module - let m = qname.Range let clocCcu = CompLocForCcu cenv.viewCcu // This method name is only used internally in ilxgen.fs to aid debugging @@ -5965,7 +6151,7 @@ and GenTopImpl cenv mgbuf mainInfoOpt eenv (TImplFile(qname, _, mexpr, hasExplic // topInstrs is ILInstr[] and contains the abstract IL for this file's top-level actions. topCode is the ILMethodBody for that same code. let topInstrs,topCode = CodeGenMethod cenv mgbuf - ([],methodName,eenv,0,0, + ([],methodName,eenv,0, (fun cgbuf eenv -> GenModuleExpr cenv cgbuf qname lazyInitInfo eenv mexpr CG.EmitInstr cgbuf (pop 0) Push0 I_ret),m) @@ -5975,8 +6161,6 @@ and GenTopImpl cenv mgbuf mainInfoOpt eenv (TImplFile(qname, _, mexpr, hasExplic // Library file (mainInfoOpt = None) : optional .cctor if topCode has initialization effect // Final file, explicit entry point (mainInfoOpt = Some _, GetExplicitEntryPointInfo() = Some) : main + optional .cctor if topCode has initialization effect // Final file, implicit entry point (mainInfoOpt = Some _, GetExplicitEntryPointInfo() = None) : main + initialize + optional .cctor calling initialize - - let doesSomething = CheckCodeDoesSomething topCode.Code // Make a FEEFEE instruction to mark hidden code regions @@ -6155,12 +6339,11 @@ and GenAbstractBinding cenv eenv tref (vref:ValRef) = else [],[],[] -and GenTypeDef cenv mgbuf lazyInitInfo eenv m (tycon:Tycon) = - let genToString ilThisTy = - [ - match (eenv.valsInScope.TryFind cenv.g.sprintf_vref.Deref, - eenv.valsInScope.TryFind cenv.g.new_format_vref.Deref) with - | Some(Lazy(Method(_,_,sprintfMethSpec,_,_,_,_))), Some(Lazy(Method(_,_,newFormatMethSpec,_,_,_,_))) -> +/// Generate a ToString method that calls 'sprintf "%A"' +and GenToStringMethod cenv eenv ilThisTy m = + [ match (eenv.valsInScope.TryFind cenv.g.sprintf_vref.Deref, + eenv.valsInScope.TryFind cenv.g.new_format_vref.Deref) with + | Some(Lazy(Method(_,_,sprintfMethSpec,_,_,_,_))), Some(Lazy(Method(_,_,newFormatMethSpec,_,_,_,_))) -> // The type returned by the 'sprintf' call let funcTy = EraseClosures.mkILFuncTy cenv.g.ilxPubCloEnv ilThisTy cenv.g.ilg.typ_String // Give the instantiation of the printf format object, i.e. a Format`5 object compatible with StringFormat @@ -6194,9 +6377,9 @@ and GenTypeDef cenv mgbuf lazyInitInfo eenv m (tycon:Tycon) = None)) let mdef = mdef.With(customAttrs = mkILCustomAttrs [ cenv.g.CompilerGeneratedAttribute ]) yield mdef - | None,_ -> () - | _,None -> () - | _ -> ()] + | _ -> () ] + +and GenTypeDef cenv mgbuf lazyInitInfo eenv m (tycon:Tycon) = let tcref = mkLocalTyconRef tycon if tycon.IsTypeAbbrev then () else match tycon.TypeReprInfo with @@ -6308,7 +6491,7 @@ and GenTypeDef cenv mgbuf lazyInitInfo eenv m (tycon:Tycon) = let generateDebugProxies = (not (tyconRefEq cenv.g tcref cenv.g.unit_tcr_canon) && not (HasFSharpAttribute cenv.g cenv.g.attrib_DebuggerTypeProxyAttribute tycon.Attribs)) - let permissionSets = CreatePermissionSets cenv.g cenv.amap eenv securityAttrs + let permissionSets = CreatePermissionSets cenv eenv securityAttrs let secDecls = if List.isEmpty securityAttrs then emptyILSecurityDecls else mkILSecurityDecls permissionSets let ilDebugDisplayAttributes = @@ -6344,7 +6527,7 @@ and GenTypeDef cenv mgbuf lazyInitInfo eenv m (tycon:Tycon) = (match ilTypeDefKind with ILTypeDefKind.ValueType -> true | _ -> false) && // All structs are sequential by default // Structs with no instance fields get size 1, pack 0 - tycon.AllFieldsAsList |> List.forall (fun f -> f.IsStatic) + tycon.AllFieldsArray |> Array.forall (fun f -> f.IsStatic) isEmptyStruct && cenv.opts.workAroundReflectionEmitBugs && not tycon.TyparsNoRange.IsEmpty @@ -6352,7 +6535,7 @@ and GenTypeDef cenv mgbuf lazyInitInfo eenv m (tycon:Tycon) = let isCLIMutable = (TryFindFSharpBoolAttribute cenv.g cenv.g.attrib_CLIMutableAttribute tycon.Attribs = Some true) let fieldSummaries = - [ for fspec in tycon.AllFieldsAsList do + [ for fspec in tycon.AllFieldsArray do let useGenuineField = useGenuineField tycon fspec @@ -6561,7 +6744,7 @@ and GenTypeDef cenv mgbuf lazyInitInfo eenv m (tycon:Tycon) = yield mkILSimpleStorageCtor(None, Some cenv.g.ilg.typ_Object.TypeSpec, ilThisTy, [], [], reprAccess) if not (tycon.HasMember cenv.g "ToString" []) then - yield! genToString ilThisTy + yield! GenToStringMethod cenv eenv ilThisTy m | TFSharpObjectRepr r when tycon.IsFSharpDelegateTycon -> // Build all the methods that go with a delegate type @@ -6576,12 +6759,11 @@ and GenTypeDef cenv mgbuf lazyInitInfo eenv m (tycon:Tycon) = | [[tsp]] when isUnitTy cenv.g tsp.Type -> [] (* suppress unit arg *) | paraml -> paraml GenActualSlotsig m cenv eenvinner (TSlotSig(nm,ty,ctps,mtps,paraml,returnTy)) [] [] - for ilMethodDef in mkILDelegateMethods reprAccess cenv.g.ilg (cenv.g.iltyp_AsyncCallback, cenv.g.iltyp_IAsyncResult) (p,r) do - yield ilMethodDef + yield! mkILDelegateMethods reprAccess cenv.g.ilg (cenv.g.iltyp_AsyncCallback, cenv.g.iltyp_IAsyncResult) (p,r) | _ -> () | TUnionRepr _ when not (tycon.HasMember cenv.g "ToString" []) -> - yield! genToString ilThisTy + yield! GenToStringMethod cenv eenv ilThisTy m | _ -> () ] let ilMethods = methodDefs @ augmentOverrideMethodDefs @ abstractMethodDefs @@ -6670,7 +6852,7 @@ and GenTypeDef cenv mgbuf lazyInitInfo eenv m (tycon:Tycon) = // All structs are sequential by default // Structs with no instance fields get size 1, pack 0 - if tycon.AllFieldsAsList |> List.exists (fun f -> not f.IsStatic) || + if tycon.AllFieldsArray |> Array.exists (fun f -> not f.IsStatic) || // Reflection emit doesn't let us emit 'pack' and 'size' for generic structs. // In that case we generate a dummy field instead (cenv.opts.workAroundReflectionEmitBugs && not tycon.TyparsNoRange.IsEmpty) @@ -6907,7 +7089,26 @@ let CodegenAssembly cenv eenv mgbuf fileImpls = if not (isNil fileImpls) then let a,b = List.frontAndBack fileImpls let eenv = List.fold (GenTopImpl cenv mgbuf None) eenv a - let _eenv = GenTopImpl cenv mgbuf cenv.opts.mainMethodInfo eenv b + let eenv = GenTopImpl cenv mgbuf cenv.opts.mainMethodInfo eenv b + + // Some constructs generate residue types and bindings. Generate these now. They don't result in any + // top-level initialization code. + begin + let extraBindings = mgbuf.GrabExtraBindingsToGenerate() + //printfn "#extraBindings = %d" extraBindings.Length + if extraBindings.Length > 0 then + let mexpr = TMDefs [ for b in extraBindings -> TMDefLet(b,range0) ] + let _emptyTopInstrs,_emptyTopCode = + CodeGenMethod cenv mgbuf ([],"unused",eenv,0, (fun cgbuf eenv -> + let lazyInitInfo = ResizeArray() + let qname = QualifiedNameOfFile(mkSynId range0 "unused") + LocalScope "module" cgbuf (fun scopeMarks -> + let eenv = AddBindingsForModuleDef (fun cloc v -> AllocTopValWithinExpr cenv cgbuf cloc scopeMarks v) eenv.cloc eenv mexpr + GenModuleDef cenv cgbuf qname lazyInitInfo eenv mexpr)),range0) + //printfn "#_emptyTopInstrs = %d" _emptyTopInstrs.Length + () + end + mgbuf.AddInitializeScriptsInOrderToEntryPoint() //------------------------------------------------------------------------- @@ -6932,15 +7133,17 @@ type IlxGenResults = { ilTypeDefs: ILTypeDef list ilAssemAttrs : ILAttribute list ilNetModuleAttrs: ILAttribute list + topAssemblyAttrs : Attribs + permissionSets : ILSecurityDecl list quotationResourceInfo: (ILTypeRef list * byte[]) list } -let GenerateCode (cenv, eenv, TypedAssemblyAfterOptimization fileImpls, assemAttribs, moduleAttribs) = +let GenerateCode (cenv, anonTypeTable, eenv, TypedAssemblyAfterOptimization fileImpls, assemAttribs, moduleAttribs) = use unwindBuildPhase = PushThreadBuildPhaseUntilUnwind BuildPhase.IlxGen // Generate the implementations into the mgbuf - let mgbuf= new AssemblyBuilder(cenv) + let mgbuf = new AssemblyBuilder(cenv, anonTypeTable) let eenv = { eenv with cloc = CompLocForFragment cenv.opts.fragName cenv.viewCcu } // Generate the PrivateImplementationDetails type @@ -6953,6 +7156,7 @@ let GenerateCode (cenv, eenv, TypedAssemblyAfterOptimization fileImpls, assemAtt let tdefs,reflectedDefinitions = mgbuf.Close() + // Generate the quotations let quotationResourceInfo = match reflectedDefinitions with @@ -6989,9 +7193,16 @@ let GenerateCode (cenv, eenv, TypedAssemblyAfterOptimization fileImpls, assemAtt let ilNetModuleAttrs = GenAttrs cenv eenv moduleAttribs + let casApplied = new Dictionary() + let securityAttrs, topAssemblyAttrs = assemAttribs |> List.partition (fun a -> IsSecurityAttribute cenv.g cenv.amap casApplied a rangeStartup) + // remove any security attributes from the top-level assembly attribute list + let permissionSets = CreatePermissionSets cenv eenv securityAttrs + { ilTypeDefs= tdefs ilAssemAttrs = ilAssemAttrs ilNetModuleAttrs = ilNetModuleAttrs + topAssemblyAttrs = topAssemblyAttrs + permissionSets = permissionSets quotationResourceInfo = quotationResourceInfo } @@ -7091,37 +7302,13 @@ let ClearGeneratedValue (ctxt: ExecutionContext) (_g:TcGlobals) eenv (v:Val) = #endif () -(* -let LookupGeneratedInfo (ctxt: ExecutionContext) (g:TcGlobals) eenv (v:Val) = - try - match StorageForVal v.Range v eenv with - | StaticField (fspec, _, hasLiteralAttr, ilContainerTy, _, _, ilGetterMethRef, _, _) -> - let staticTy = ctxt.LookupTypeRef ilContainerTy.TypeRef - if hasLiteralAttr then - Some (staticTy.GetField(fspec.Name) :> MemberInfo) - else - Some (staticTy.GetMethod(ilGetterMethRef.Name,[||]) :> MemberInfo) - | Null -> None - | Local _ -> None - | Method _ -> None - | Arg _ -> None - | Env _ -> None - with - e -> -#if DEBUG - printf "ilxGen.lookupGenertedInfo for v=%s caught exception:\n%A\n\n" v.LogicalName e -#endif - None - - -*) - /// The published API from the ILX code generator type IlxAssemblyGenerator(amap: ImportMap, tcGlobals: TcGlobals, tcVal : ConstraintSolver.TcValF, ccu: Tast.CcuThunk) = // The incremental state held by the ILX code generator let mutable ilxGenEnv = GetEmptyIlxGenEnv tcGlobals.ilg ccu + let anonTypeTable = AnonTypeGenerationTable() let intraAssemblyInfo = { StaticFieldInfo = new Dictionary<_,_>(HashIdentity.Structural) } let casApplied = new Dictionary() @@ -7146,7 +7333,7 @@ type IlxAssemblyGenerator(amap: ImportMap, tcGlobals: TcGlobals, tcVal : Constra intraAssemblyInfo = intraAssemblyInfo opts = codeGenOpts optimizeDuringCodeGen = (fun x -> x) } - GenerateCode (cenv, ilxGenEnv, typedAssembly, assemAttribs, moduleAttribs) + GenerateCode (cenv, anonTypeTable, ilxGenEnv, typedAssembly, assemAttribs, moduleAttribs) /// Invert the compilation of the given value and clear the storage of the value member __.ClearGeneratedValue (ctxt, v) = ClearGeneratedValue ctxt tcGlobals ilxGenEnv v @@ -7154,5 +7341,4 @@ type IlxAssemblyGenerator(amap: ImportMap, tcGlobals: TcGlobals, tcVal : Constra /// Invert the compilation of the given value and return its current dynamic value and its compiled System.Type member __.LookupGeneratedValue (ctxt, v) = LookupGeneratedValue amap ctxt ilxGenEnv v - /// Create the CAS permission sets for an assembly fragment - member __.CreatePermissionSets attribs = CreatePermissionSets tcGlobals amap ilxGenEnv attribs + diff --git a/src/fsharp/IlxGen.fsi b/src/fsharp/IlxGen.fsi index 25c727eca8..6d50da1bfd 100755 --- a/src/fsharp/IlxGen.fsi +++ b/src/fsharp/IlxGen.fsi @@ -62,6 +62,10 @@ type public IlxGenResults = ilAssemAttrs : ILAttribute list /// The generated IL/ILX .NET module attributes ilNetModuleAttrs : ILAttribute list + /// The attributes for the assembly in F# form + topAssemblyAttrs : Attribs + /// The security attributes to attach to the assembly + permissionSets : ILSecurityDecl list /// The generated IL/ILX resources associated with F# quotations quotationResourceInfo : (ILTypeRef list * byte[]) list } @@ -88,9 +92,6 @@ type public IlxAssemblyGenerator = /// Generate ILX code for an assembly fragment member GenerateCode : IlxGenOptions * TypedAssemblyAfterOptimization * Attribs * Attribs -> IlxGenResults - /// Create the CAS permission sets for an assembly fragment - member CreatePermissionSets : Attrib list -> ILSecurityDecl list - /// Invert the compilation of the given value and clear the storage of the value member ClearGeneratedValue : ExecutionContext * Val -> unit diff --git a/src/fsharp/InfoReader.fs b/src/fsharp/InfoReader.fs index 3b9963bad9..e04485887e 100644 --- a/src/fsharp/InfoReader.fs +++ b/src/fsharp/InfoReader.fs @@ -81,8 +81,8 @@ let rec GetImmediateIntrinsicMethInfosOfTypeAux (optFilter,ad) g amap m origTy m |> List.filter (fun minfo -> not minfo.IsInstance) else match tryDestAppTy g metadataTy with - | None -> [] - | Some tcref -> + | ValueNone -> [] + | ValueSome tcref -> SelectImmediateMemberVals g optFilter (TrySelectMemberVal g optFilter origTy None) tcref let minfos = minfos |> List.filter (IsMethInfoAccessible amap m ad) minfos @@ -169,8 +169,8 @@ let rec GetImmediateIntrinsicPropInfosOfTypeAux (optFilter,ad) g amap m origTy m GetImmediateIntrinsicPropInfosOfTypeAux (optFilter,ad) g amap m origTy betterMetadataTy else match tryDestAppTy g metadataTy with - | None -> [] - | Some tcref -> + | ValueNone -> [] + | ValueSome tcref -> let propCollector = new PropertyCollector(g, amap, m, origTy, optFilter, ad) SelectImmediateMemberVals g None (fun membInfo vref -> propCollector.Collect(membInfo, vref); None) tcref |> ignore propCollector.Close() @@ -188,11 +188,11 @@ let IsIndexerType g amap ty = isArray1DTy g ty || isListTy g ty || match tryDestAppTy g ty with - | Some tcref -> + | ValueSome tcref -> let _, entityTy = generalizeTyconRef tcref let props = GetImmediateIntrinsicPropInfosOfType (None, AccessibleFromSomeFSharpCode) g amap range0 entityTy props |> List.exists (fun x -> x.PropertyName = "Item") - | None -> false + | ValueNone -> false /// Sets of methods up the hierarchy, ignoring duplicates by name and sig. @@ -268,8 +268,8 @@ type InfoReader(g: TcGlobals, amap: Import.ImportMap) = /// Get the F#-declared record fields or class 'val' fields of a type let GetImmediateIntrinsicRecdOrClassFieldsOfType (optFilter, _ad) _m ty = match tryDestAppTy g ty with - | None -> [] - | Some tcref -> + | ValueNone -> [] + | ValueSome tcref -> // Note;secret fields are not allowed in lookups here, as we're only looking // up user-visible fields in name resolution. match optFilter with @@ -417,17 +417,17 @@ type InfoReader(g: TcGlobals, amap: Import.ImportMap) = /// Try and find a record or class field for a type. member x.TryFindRecdOrClassFieldInfoOfType (nm,m,ty) = match recdOrClassFieldInfoCache.Apply((Some nm,AccessibleFromSomewhere),m,ty) with - | [] -> None - | [single] -> Some single + | [] -> ValueNone + | [single] -> ValueSome single | flds -> // multiple fields with the same name can come from different classes, // so filter them by the given type name match tryDestAppTy g ty with - | None -> None - | Some tcref -> + | ValueNone -> ValueNone + | ValueSome tcref -> match flds |> List.filter (fun rfinfo -> tyconRefEq g tcref rfinfo.TyconRef) with - | [] -> None - | [single] -> Some single + | [] -> ValueNone + | [single] -> ValueSome single | _ -> failwith "unexpected multiple fields with same name" // Because it should have been already reported as duplicate fields /// Try and find an item with the given name in a type. @@ -469,8 +469,8 @@ let rec GetIntrinsicConstructorInfosOfTypeAux (infoReader:InfoReader) m origTy m GetIntrinsicConstructorInfosOfTypeAux infoReader m origTy betterMetadataTy else match tryDestAppTy g metadataTy with - | None -> [] - | Some tcref -> + | ValueNone -> [] + | ValueSome tcref -> tcref.MembersOfFSharpTyconByName |> NameMultiMap.find ".ctor" |> List.choose(fun vref -> diff --git a/src/fsharp/InnerLambdasToTopLevelFuncs.fs b/src/fsharp/InnerLambdasToTopLevelFuncs.fs index da5c49f4bb..c783c1efe1 100755 --- a/src/fsharp/InnerLambdasToTopLevelFuncs.fs +++ b/src/fsharp/InnerLambdasToTopLevelFuncs.fs @@ -1280,9 +1280,9 @@ module Pass4_RewriteAssembly = let rhs,z = TransModuleDef penv z rhs ModuleOrNamespaceBinding.Module(nm,rhs),z - let TransImplFile penv z (TImplFile(fragName,pragmas,moduleExpr,hasExplicitEntryPoint,isScript)) = + let TransImplFile penv z (TImplFile(fragName,pragmas,moduleExpr,hasExplicitEntryPoint,isScript,anonRecdTypes)) = let moduleExpr,z = TransModuleExpr penv z moduleExpr - (TImplFile(fragName,pragmas,moduleExpr,hasExplicitEntryPoint,isScript)),z + (TImplFile(fragName,pragmas,moduleExpr,hasExplicitEntryPoint,isScript,anonRecdTypes)),z //------------------------------------------------------------------------- // pass5: copyExpr diff --git a/src/fsharp/LexFilter.fs b/src/fsharp/LexFilter.fs index f8b7f951c2..c67aa06cb4 100755 --- a/src/fsharp/LexFilter.fs +++ b/src/fsharp/LexFilter.fs @@ -342,7 +342,7 @@ let rec isSeqBlockElementContinuator token = // ... // ), <------- NOTE RPAREN HERE // Shortcut.CtrlO) - | END | AND | WITH | THEN | RPAREN | RBRACE | RBRACK | BAR_RBRACK | RQUOTE _ -> true + | END | AND | WITH | THEN | RPAREN | RBRACE | BAR_RBRACE | RBRACK | BAR_RBRACK | RQUOTE _ -> true // The following arise during reprocessing of the inserted tokens when we hit a DONE | ORIGHT_BLOCK_END | OBLOCKEND | ODECLEND -> true @@ -370,7 +370,7 @@ let isAtomicExprEndToken token = | UINT8 _ | UINT16 _ | UINT32 _ | UINT64 _ | UNATIVEINT _ | DECIMAL _ | BIGNUM _ | STRING _ | BYTEARRAY _ | CHAR _ | IEEE32 _ | IEEE64 _ - | RPAREN | RBRACK | RBRACE | BAR_RBRACK | END + | RPAREN | RBRACK | RBRACE | BAR_RBRACE | BAR_RBRACK | END | NULL | FALSE | TRUE | UNDERSCORE -> true | _ -> false @@ -381,6 +381,7 @@ let parenTokensBalance t1 t2 = match t1,t2 with | (LPAREN,RPAREN) | (LBRACE,RBRACE) + | (LBRACE_BAR,BAR_RBRACE) | (LBRACK,RBRACK) | (INTERFACE,END) | (CLASS,END) @@ -676,7 +677,6 @@ type LexFilterImpl (lightSyntaxStatus:LightSyntaxStatus, compilingFsLib, lexer, | _,(CtxtSeqBlock _ :: CtxtParen((LBRACE | LBRACK | LBRACK_BAR),_) :: CtxtVanilla _ :: CtxtSeqBlock _ :: rest) -> unindentationLimit false rest - // MAJOR PERMITTED UNDENTATION This is allowing: // if x then y else // let x = 3 + 4 @@ -752,8 +752,8 @@ type LexFilterImpl (lightSyntaxStatus:LightSyntaxStatus, compilingFsLib, lexer, // 'if ... else [' limited by 'if' // 'if ... else [|' limited by 'if' | _,(CtxtParen ((SIG | STRUCT | BEGIN),_) :: CtxtSeqBlock _ :: (CtxtModuleBody (_,false) as limitCtxt) :: _) - | _,(CtxtParen ((BEGIN | LPAREN | LBRACK | LBRACE | LBRACK_BAR) ,_) :: CtxtSeqBlock _ :: CtxtThen _ :: (CtxtIf _ as limitCtxt) :: _) - | _,(CtxtParen ((BEGIN | LPAREN | LBRACK | LBRACE | LBRACK_BAR) ,_) :: CtxtSeqBlock _ :: CtxtElse _ :: (CtxtIf _ as limitCtxt) :: _) + | _,(CtxtParen ((BEGIN | LPAREN | LBRACK | LBRACE | LBRACE_BAR | LBRACK_BAR) ,_) :: CtxtSeqBlock _ :: CtxtThen _ :: (CtxtIf _ as limitCtxt) :: _) + | _,(CtxtParen ((BEGIN | LPAREN | LBRACK | LBRACE | LBRACE_BAR | LBRACK_BAR | LBRACK_LESS) ,_) :: CtxtSeqBlock _ :: CtxtElse _ :: (CtxtIf _ as limitCtxt) :: _) // 'f ... (' in seqblock limited by 'f' // 'f ... {' in seqblock limited by 'f' NOTE: this is covered by the more generous case above @@ -770,7 +770,7 @@ type LexFilterImpl (lightSyntaxStatus:LightSyntaxStatus, compilingFsLib, lexer, // REVIEW: document these | _,(CtxtSeqBlock _ :: CtxtParen((BEGIN | LPAREN | LBRACK | LBRACK_BAR),_) :: CtxtVanilla _ :: (CtxtSeqBlock _ as limitCtxt) :: _) - | (CtxtSeqBlock _),(CtxtParen ((BEGIN | LPAREN | LBRACE | LBRACK | LBRACK_BAR) ,_) :: CtxtSeqBlock _ :: ((CtxtTypeDefns _ | CtxtLetDecl _ | CtxtMemberBody _ | CtxtWithAsLet _) as limitCtxt) :: _) + | (CtxtSeqBlock _),(CtxtParen ((BEGIN | LPAREN | LBRACE | LBRACE_BAR | LBRACK | LBRACK_BAR) ,_) :: CtxtSeqBlock _ :: ((CtxtTypeDefns _ | CtxtLetDecl _ | CtxtMemberBody _ | CtxtWithAsLet _) as limitCtxt) :: _) -> PositionWithColumn(limitCtxt.StartPos,limitCtxt.StartCol + 1) // Permitted inner-construct (e.g. "then" block and "else" block in overall @@ -917,10 +917,15 @@ type LexFilterImpl (lightSyntaxStatus:LightSyntaxStatus, compilingFsLib, lexer, // fx // fx // f x>x + // f<{| C : int |}>x // fx // fx | DEFAULT | COLON | COLON_GREATER | STRUCT | NULL | DELEGATE | AND | WHEN | DOT_DOT + | NEW + | LBRACE_BAR + | SEMICOLON + | BAR_RBRACE | INFIX_AT_HAT_OP "^" | INFIX_AT_HAT_OP "^-" | INFIX_STAR_DIV_MOD_OP "/" @@ -995,7 +1000,7 @@ type LexFilterImpl (lightSyntaxStatus:LightSyntaxStatus, compilingFsLib, lexer, // WITH balances except in the following contexts.... Phew - an overused keyword! | WITH , ( ((CtxtMatch _ | CtxtException _ | CtxtMemberHead _ | CtxtInterfaceHead _ | CtxtTry _ | CtxtTypeDefns _ | CtxtMemberBody _) :: _) // This is the nasty record/object-expression case - | (CtxtSeqBlock _ :: CtxtParen(LBRACE,_) :: _) ) + | (CtxtSeqBlock _ :: CtxtParen((LBRACE | LBRACE_BAR),_) :: _) ) | FINALLY , (CtxtTry _ :: _) -> true @@ -1166,6 +1171,7 @@ type LexFilterImpl (lightSyntaxStatus:LightSyntaxStatus, compilingFsLib, lexer, | RPAREN | GREATER true | RBRACE + | BAR_RBRACE | RBRACK | BAR_RBRACK | WITH @@ -1204,7 +1210,7 @@ type LexFilterImpl (lightSyntaxStatus:LightSyntaxStatus, compilingFsLib, lexer, while not offsideStack.IsEmpty && (not(nextOuterMostInterestingContextIsNamespaceOrModule(offsideStack))) && (match offsideStack.Head with // open-parens of sorts - | CtxtParen((LPAREN|LBRACK|LBRACE|LBRACK_BAR),_) -> true + | CtxtParen((LPAREN|LBRACK|LBRACE|LBRACE_BAR|LBRACK_BAR),_) -> true // seq blocks | CtxtSeqBlock _ -> true // vanillas @@ -1297,9 +1303,9 @@ type LexFilterImpl (lightSyntaxStatus:LightSyntaxStatus, compilingFsLib, lexer, hwTokenFetch(useBlockRule) // Balancing rule. Encountering a ')' or '}' balances with a '(' or '{', even if not offside - | ((END | RPAREN | RBRACE | RBRACK | BAR_RBRACK | RQUOTE _ | GREATER true) as t2), (CtxtParen (t1,_) :: _) + | ((END | RPAREN | RBRACE | BAR_RBRACE | RBRACK | BAR_RBRACK | RQUOTE _ | GREATER true) as t2), (CtxtParen (t1,_) :: _) when parenTokensBalance t1 t2 -> - if debug then dprintf "RPAREN/RBRACE/RBRACK/BAR_RBRACK/RQUOTE/END at %a terminates CtxtParen()\n" outputPos tokenStartPos + if debug then dprintf "RPAREN/RBRACE/BAR_RBRACE/RBRACK/BAR_RBRACK/RQUOTE/END at %a terminates CtxtParen()\n" outputPos tokenStartPos popCtxt() // Queue a dummy token at this position to check if any closing rules apply delayToken(tokenTup.UseLocation(ODUMMY(token))) @@ -1792,7 +1798,7 @@ type LexFilterImpl (lightSyntaxStatus:LightSyntaxStatus, compilingFsLib, lexer, // '{ id1 = 1 // M.id2 = ... ' ~~~> CtxtSeqBlock | EQUALS, ((CtxtWithAsLet _) :: _) // This detects 'with = '. - | EQUALS, ((CtxtVanilla (_,true)) :: (CtxtSeqBlock _) :: (CtxtWithAsLet _ | CtxtParen(LBRACE,_)) :: _) -> + | EQUALS, ((CtxtVanilla (_,true)) :: (CtxtSeqBlock _) :: (CtxtWithAsLet _ | CtxtParen((LBRACE | LBRACE_BAR),_)) :: _) -> if debug then dprintf "CtxtLetDecl/CtxtWithAsLet: EQUALS, pushing CtxtSeqBlock\n" // We don't insert begin/end block tokens for single-line bindings since we can't properly distinguish single-line *) // record update expressions such as "{ t with gbuckets=Array.copy t.gbuckets; gcount=t.gcount }" *) @@ -1816,7 +1822,7 @@ type LexFilterImpl (lightSyntaxStatus:LightSyntaxStatus, compilingFsLib, lexer, returnToken tokenLexbufState token // '(' tokens are balanced with ')' tokens and also introduce a CtxtSeqBlock - | (BEGIN | LPAREN | SIG | LBRACE | LBRACK | LBRACK_BAR | LQUOTE _ | LESS true), _ -> + | (BEGIN | LPAREN | SIG | LBRACE | LBRACE_BAR | LBRACK | LBRACK_BAR | LQUOTE _ | LESS true), _ -> if debug then dprintf "LPAREN etc., pushes CtxtParen, pushing CtxtSeqBlock, tokenStartPos = %a\n" outputPos tokenStartPos pushCtxt tokenTup (CtxtParen (token,tokenStartPos)) pushCtxtSeqBlock(false,NoAddBlockEnd) @@ -1842,7 +1848,7 @@ type LexFilterImpl (lightSyntaxStatus:LightSyntaxStatus, compilingFsLib, lexer, // comprehension/match | (CtxtWhile _ | CtxtFor _ | CtxtWhen _ | CtxtMatchClauses _ | CtxtFun _) :: _ -> true // comprehension - | (CtxtSeqBlock _ :: CtxtParen ((LBRACK | LBRACE | LBRACK_BAR), _) :: _) -> true + | (CtxtSeqBlock _ :: CtxtParen ((LBRACK | LBRACE | LBRACE_BAR | LBRACK_BAR), _) :: _) -> true // comprehension | (CtxtSeqBlock _ :: (CtxtDo _ | CtxtWhile _ | CtxtFor _ | CtxtWhen _ | CtxtMatchClauses _ | CtxtTry _ | CtxtThen _ | CtxtElse _) :: _) -> true | _ -> false) -> @@ -1893,7 +1899,7 @@ type LexFilterImpl (lightSyntaxStatus:LightSyntaxStatus, compilingFsLib, lexer, returnToken tokenLexbufState token | WITH, (((CtxtException _ | CtxtTypeDefns _ | CtxtMemberHead _ | CtxtInterfaceHead _ | CtxtMemberBody _) as limCtxt) :: _) - | WITH, ((CtxtSeqBlock _) as limCtxt :: CtxtParen(LBRACE,_) :: _) -> + | WITH, ((CtxtSeqBlock _) as limCtxt :: CtxtParen((LBRACE | LBRACE_BAR),_) :: _) -> let lookaheadTokenTup = peekNextTokenTup() let lookaheadTokenStartPos = startPosOfTokenTup lookaheadTokenTup match lookaheadTokenTup.Token with diff --git a/src/fsharp/LowerCallsAndSeqs.fs b/src/fsharp/LowerCallsAndSeqs.fs index 6fc9b6065e..15904bfabd 100755 --- a/src/fsharp/LowerCallsAndSeqs.fs +++ b/src/fsharp/LowerCallsAndSeqs.fs @@ -52,11 +52,11 @@ let InterceptExpr g cont expr = /// known arity to lambda expressions and beta-var-reduces to bind /// any known arguments. The results are later optimized by the peephole /// optimizer in opt.fs -let LowerImplFile g ass = +let LowerImplFile g assembly = RewriteImplFile { PreIntercept = Some(InterceptExpr g) PreInterceptBinding=None PostTransform= (fun _ -> None) - IsUnderQuotations=false } ass + IsUnderQuotations=false } assembly //---------------------------------------------------------------------------- @@ -84,13 +84,18 @@ type LoweredSeqFirstPhaseResult = { /// The code to run in the second phase, to rebuild the expressions, once all code labels and their mapping to program counters have been determined /// 'nextVar' is the argument variable for the GenerateNext method that represents the byref argument that holds the "goto" destination for a tailcalling sequence expression phase2 : ((* pc: *) ValRef * (* current: *) ValRef * (* nextVar: *) ValRef * Map -> Expr * Expr * Expr) + /// The labels allocated for one portion of the sequence expression labels : int list + /// any actual work done in Close significantClose : bool /// The state variables allocated for one portion of the sequence expression (i.e. the local let-bound variables which become state variables) - stateVars: ValRef list } + stateVars: ValRef list + + /// The vars captured by the non-synchronous path + capturedVars: FreeVars } let isVarFreeInExpr v e = Zset.contains v (freeInExpr CollectTyparsAndLocals e).FreeLocals @@ -174,6 +179,17 @@ let LowerSeqExpr g amap overallExpr = | Expr.App(Expr.Val (vref,_,_),_f0ty,[elemTy],[e],_m) when valRefEq g vref g.seq_vref -> Some (e,elemTy) | _ -> None + let RepresentBindingAsLocal (bind: Binding) res2 m = + // printfn "found letrec state variable %s" bind.Var.DisplayName + { res2 with + phase2 = (fun ctxt -> + let generate2,dispose2,checkDispose2 = res2.phase2 ctxt + let generate = mkLetBind m bind generate2 + let dispose = dispose2 + let checkDispose = checkDispose2 + generate,dispose,checkDispose) + stateVars = res2.stateVars } + let RepresentBindingAsStateMachineLocal (bind: Binding) res2 m = // printfn "found letrec state variable %s" bind.Var.DisplayName let (TBind(v,e,sp)) = bind @@ -243,17 +259,28 @@ let LowerSeqExpr g amap overallExpr = labels=[label] stateVars=[] significantClose = false + capturedVars = emptyFreeVars } - | SeqDelay(e,_elemTy) -> + | SeqDelay(delayedExpr,_elemTy) -> // printfn "found Seq.delay" - Lower isWholeExpr isTailCall noDisposeContinuationLabel currentDisposeContinuationLabel e // note, using 'isWholeExpr' here prevents 'seq { yield! e }' and 'seq { 0 .. 1000 }' from being compiled + // note, using 'isWholeExpr' here prevents 'seq { yield! e }' and 'seq { 0 .. 1000 }' from being compiled + Lower isWholeExpr isTailCall noDisposeContinuationLabel currentDisposeContinuationLabel delayedExpr | SeqAppend(e1,e2,m) -> // printfn "found Seq.append" - match Lower false false noDisposeContinuationLabel currentDisposeContinuationLabel e1, - Lower false isTailCall noDisposeContinuationLabel currentDisposeContinuationLabel e2 with + let res1 = Lower false false noDisposeContinuationLabel currentDisposeContinuationLabel e1 + let res2 = Lower false isTailCall noDisposeContinuationLabel currentDisposeContinuationLabel e2 + match res1, res2 with | Some res1, Some res2 -> + + let capturedVars = + if res1.labels.IsEmpty then + res2.capturedVars + else + // All of 'e2' is needed after resuming at any of the labels + unionFreeVars res1.capturedVars (freeInExpr CollectLocals e2) + Some { phase2 = (fun ctxt -> let generate1,dispose1,checkDispose1 = res1.phase2 ctxt let generate2,dispose2,checkDispose2 = res2.phase2 ctxt @@ -265,29 +292,43 @@ let LowerSeqExpr g amap overallExpr = generate,dispose,checkDispose) labels= res1.labels @ res2.labels stateVars = res1.stateVars @ res2.stateVars - significantClose = res1.significantClose || res2.significantClose } + significantClose = res1.significantClose || res2.significantClose + capturedVars = capturedVars } | _ -> None - | SeqWhile(e1,e2,m) -> + | SeqWhile(guardExpr,bodyExpr,m) -> // printfn "found Seq.while" - match Lower false false noDisposeContinuationLabel currentDisposeContinuationLabel e2 with + let resBody = Lower false false noDisposeContinuationLabel currentDisposeContinuationLabel bodyExpr + match resBody with | Some res2 -> + let capturedVars = + if res2.labels.IsEmpty then + res2.capturedVars // the whole loopis synchronous, no labels + else + freeInExpr CollectLocals expr // everything is needed on subsequent iterations + Some { phase2 = (fun ctxt -> let generate2,dispose2,checkDispose2 = res2.phase2 ctxt - let generate = mkWhile g (SequencePointAtWhileLoop e1.Range,NoSpecialWhileLoopMarker,e1,generate2,m) + let generate = mkWhile g (SequencePointAtWhileLoop guardExpr.Range,NoSpecialWhileLoopMarker,guardExpr,generate2,m) let dispose = dispose2 let checkDispose = checkDispose2 generate,dispose,checkDispose) labels = res2.labels stateVars = res2.stateVars - significantClose = res2.significantClose } + significantClose = res2.significantClose + capturedVars = capturedVars } | _ -> None | SeqUsing(resource,v,body,elemTy,m) -> // printfn "found Seq.using" - Lower false isTailCall noDisposeContinuationLabel currentDisposeContinuationLabel (mkLet (SequencePointAtBinding body.Range) m v resource (mkCallSeqFinally g m elemTy body (mkUnitDelayLambda g m (mkCallDispose g m v.Type (exprForVal m v))))) + let reduction = + mkLet (SequencePointAtBinding body.Range) m v resource + (mkCallSeqFinally g m elemTy body + (mkUnitDelayLambda g m + (mkCallDispose g m v.Type (exprForVal m v)))) + Lower false isTailCall noDisposeContinuationLabel currentDisposeContinuationLabel reduction | SeqFor(inp,v,body,genElemTy,m) -> // printfn "found Seq.for" @@ -298,18 +339,21 @@ let LowerSeqExpr g amap overallExpr = // while enum.MoveNext() do // let v = enum.Current // body ]] - Lower false isTailCall noDisposeContinuationLabel currentDisposeContinuationLabel - (mkCallSeqUsing g m inpEnumTy genElemTy (callNonOverloadedMethod g amap m "GetEnumerator" (mkSeqTy g inpElemTy) [inp]) - (mkLambdaNoType g m enumv + let reduction = + mkCallSeqUsing g m inpEnumTy genElemTy (callNonOverloadedMethod g amap m "GetEnumerator" (mkSeqTy g inpElemTy) [inp]) + (mkLambdaNoType g m enumv (mkCallSeqGenerated g m genElemTy (mkUnitDelayLambda g m (callNonOverloadedMethod g amap m "MoveNext" inpEnumTy [enume])) (mkInvisibleLet m v (callNonOverloadedMethod g amap m "get_Current" inpEnumTy [enume]) - (mkCoerceIfNeeded g (mkSeqTy g genElemTy) (tyOfExpr g body) body))))) + (mkCoerceIfNeeded g (mkSeqTy g genElemTy) (tyOfExpr g body) body)))) + Lower false isTailCall noDisposeContinuationLabel currentDisposeContinuationLabel reduction | SeqTryFinally(e1,compensation,m) -> // printfn "found Seq.try/finally" let innerDisposeContinuationLabel = IL.generateCodeLabel() - match Lower false false noDisposeContinuationLabel innerDisposeContinuationLabel e1 with + let resBody = Lower false false noDisposeContinuationLabel innerDisposeContinuationLabel e1 + match resBody with | Some res1 -> + let capturedVars = unionFreeVars res1.capturedVars (freeInExpr CollectLocals compensation) Some { phase2 = (fun ((pcv,_currv,_,pcMap) as ctxt) -> let generate1,dispose1,checkDispose1 = res1.phase2 ctxt let generate = @@ -348,7 +392,8 @@ let LowerSeqExpr g amap overallExpr = generate,dispose,checkDispose) labels = innerDisposeContinuationLabel :: res1.labels stateVars = res1.stateVars - significantClose = true } + significantClose = true + capturedVars = capturedVars } | _ -> None @@ -361,7 +406,8 @@ let LowerSeqExpr g amap overallExpr = generate,dispose,checkDispose) labels = [] stateVars = [] - significantClose = false } + significantClose = false + capturedVars = emptyFreeVars } | Expr.Sequential(x1,x2,NormalSeq,ty,m) -> match Lower false isTailCall noDisposeContinuationLabel currentDisposeContinuationLabel x2 with @@ -376,13 +422,18 @@ let LowerSeqExpr g amap overallExpr = generate,dispose,checkDispose) } | None -> None - | Expr.Let(bind,e2,m,_) + | Expr.Let(bind,bodyExpr,m,_) // Restriction: compilation of sequence expressions containing non-toplevel constrained generic functions is not supported when bind.Var.IsCompiledAsTopLevel || not (IsGenericValWithGenericContraints g bind.Var) -> - match Lower false isTailCall noDisposeContinuationLabel currentDisposeContinuationLabel e2 with + + let resBody = Lower false isTailCall noDisposeContinuationLabel currentDisposeContinuationLabel bodyExpr + match resBody with | Some res2 -> if bind.Var.IsCompiledAsTopLevel then Some (RepresentBindingsAsLifted (mkLetBind m bind) res2) + elif not (res2.capturedVars.FreeLocals.Contains(bind.Var)) then + // printfn "found state variable %s" bind.Var.DisplayName + Some (RepresentBindingAsLocal bind res2 m) else // printfn "found state variable %s" bind.Var.DisplayName Some (RepresentBindingAsStateMachineLocal bind res2 m) @@ -421,12 +472,18 @@ let LowerSeqExpr g amap overallExpr = *) | Expr.Match (spBind,exprm,pt,targets,m,ty) when targets |> Array.forall (fun (TTarget(vs,_e,_spTarget)) -> isNil vs) -> // lower all the targets. abandon if any fail to lower - let tgl = targets |> Array.map (fun (TTarget(_vs,e,_spTarget)) -> Lower false isTailCall noDisposeContinuationLabel currentDisposeContinuationLabel e) |> Array.toList + let tglArray = targets |> Array.map (fun (TTarget(_vs,targetExpr,_spTarget)) -> Lower false isTailCall noDisposeContinuationLabel currentDisposeContinuationLabel targetExpr) // LIMITATION: non-trivial pattern matches involving or-patterns or active patterns where bindings can't be // transferred to the r.h.s. are not yet compiled. - if tgl |> List.forall Option.isSome then - let tgl = List.map Option.get tgl + if tglArray |> Array.forall Option.isSome then + let tglArray = Array.map Option.get tglArray + let tgl = Array.toList tglArray let labs = tgl |> List.collect (fun res -> res.labels) + let (capturedVars, _) = + ((emptyFreeVars, false), Array.zip targets tglArray) + ||> Array.fold (fun (fvs, seenLabel) ((TTarget(_vs,e,_spTarget)), res) -> + if seenLabel then unionFreeVars fvs (freeInExpr CollectLocals e), true + else res.capturedVars, not res.labels.IsEmpty) let stateVars = tgl |> List.collect (fun res -> res.stateVars) let significantClose = tgl |> List.exists (fun res -> res.significantClose) Some { phase2 = (fun ctxt -> @@ -443,7 +500,8 @@ let LowerSeqExpr g amap overallExpr = generate,dispose,checkDispose) labels=labs stateVars = stateVars - significantClose = significantClose } + significantClose = significantClose + capturedVars = capturedVars } else None @@ -454,12 +512,12 @@ let LowerSeqExpr g amap overallExpr = // Note, however, this leads to a loss of tailcalls: the case not // handled correctly yet is sequence expressions that use yield! in the last position // This can give rise to infinite iterator chains when implemented by the naive expansion to - // for x in e yield e. For example consider this: + // �for x in e yield e�. For example consider this: // // let rec rwalk x = { yield x // yield! rwalk (x + rand()) } // - // This is the moral equivalent of a tailcall optimization. These also dont compile well + // This is the moral equivalent of a tailcall optimization. These also don�t compile well // in the C# compilation model | arbitrarySeqExpr -> @@ -502,7 +560,8 @@ let LowerSeqExpr g amap overallExpr = generate,dispose,checkDispose) labels=[label] stateVars=[] - significantClose = false } + significantClose = false + capturedVars = emptyFreeVars } else let v,ve = mkCompGenLocal m "v" inpElemTy Lower false isTailCall noDisposeContinuationLabel currentDisposeContinuationLabel (mkCallSeqCollect g m inpElemTy inpElemTy (mkLambdaNoType g m v (mkCallSeqSingleton g m inpElemTy ve)) arbitrarySeqExpr) diff --git a/src/fsharp/MSBuildReferenceResolver.fs b/src/fsharp/MSBuildReferenceResolver.fs index 804c6b7408..c2a9d2133b 100644 --- a/src/fsharp/MSBuildReferenceResolver.fs +++ b/src/fsharp/MSBuildReferenceResolver.fs @@ -41,62 +41,52 @@ module internal Microsoft.FSharp.Compiler.MSBuildReferenceResolver // ATTENTION!: the following code needs to be updated every time we are switching to the new MSBuild version because new .NET framework version was released // 1. List of frameworks // 2. DeriveTargetFrameworkDirectoriesFor45Plus - // 3. HighestInstalledNetFrameworkVersion + // 3. HighestInstalledRefAssembliesOrDotNETFramework // 4. GetPathToDotNetFrameworkImlpementationAssemblies [] - let private Net10 = "v1.0" + let private Net45 = "v4.5" [] - let private Net11 = "v1.1" + let private Net451 = "v4.5.1" [] - let private Net20 = "v2.0" + let private Net452 = "v4.5.2" // not available in Dev15 MSBuild version [] - let private Net30 = "v3.0" + let private Net46 = "v4.6" [] - let private Net35 = "v3.5" + let private Net461 = "v4.6.1" [] - let private Net40 = "v4.0" + let private Net462 = "v4.6.2" [] - let private Net45 = "v4.5" + let private Net47 = "v4.7" [] - let private Net451 = "v4.5.1" - - /// The list of supported .NET Framework version numbers, using the monikers of the Reference Assemblies folder. - let SupportedNetFrameworkVersions = set [ Net20; Net30; Net35; Net40; Net45; Net451; (*SL only*) "v5.0" ] - - //[] - //let private Net452 = "v4.5.2" // not available in Dev15 MSBuild version + let private Net471 = "v4.7.1" -#if MSBUILD_AT_LEAST_14 [] - let private Net46 = "v4.6" + let private Net472 = "v4.7.2" - [] - let private Net461 = "v4.6.1" -#endif + let SupportedDesktopFrameworkVersions = [ Net472; Net471; Net47; Net462; Net461; Net46; Net452; Net451; Net45 ] - /// Get the path to the .NET Framework implementation assemblies by using ToolLocationHelper.GetPathToDotNetFramework. + /// Get the path to the .NET Framework implementation assemblies by using ToolLocationHelper.GetPathToDotNetFramework /// This is only used to specify the "last resort" path for assembly resolution. let GetPathToDotNetFrameworkImlpementationAssemblies(v) = let v = match v with - | Net11 -> Some TargetDotNetFrameworkVersion.Version11 - | Net20 -> Some TargetDotNetFrameworkVersion.Version20 - | Net30 -> Some TargetDotNetFrameworkVersion.Version30 - | Net35 -> Some TargetDotNetFrameworkVersion.Version35 - | Net40 -> Some TargetDotNetFrameworkVersion.Version40 | Net45 -> Some TargetDotNetFrameworkVersion.Version45 | Net451 -> Some TargetDotNetFrameworkVersion.Version451 -#if MSBUILD_AT_LEAST_14 - //| Net452 -> Some TargetDotNetFrameworkVersion.Version452 // not available in Dev15 MSBuild version +#if MSBUILD_AT_LEAST_15 + | Net452 -> Some TargetDotNetFrameworkVersion.Version452 | Net46 -> Some TargetDotNetFrameworkVersion.Version46 | Net461 -> Some TargetDotNetFrameworkVersion.Version461 + | Net462 -> Some TargetDotNetFrameworkVersion.Version462 + | Net47 -> Some TargetDotNetFrameworkVersion.Version47 + | Net471 -> Some TargetDotNetFrameworkVersion.Version471 + | Net472 -> Some TargetDotNetFrameworkVersion.Version472 #endif | _ -> assert false; None match v with @@ -106,7 +96,6 @@ module internal Microsoft.FSharp.Compiler.MSBuildReferenceResolver | x -> [x] | _ -> [] - let GetPathToDotNetFrameworkReferenceAssemblies(version) = #if NETSTANDARD1_6 || NETSTANDARD2_0 ignore version @@ -118,41 +107,59 @@ module internal Microsoft.FSharp.Compiler.MSBuildReferenceResolver | x -> [x] #endif - /// Use MSBuild to determine the version of the highest installed framework. - let HighestInstalledNetFrameworkVersion() = - try -#if MSBUILD_AT_LEAST_14 - if box (ToolLocationHelper.GetPathToDotNetFramework(TargetDotNetFrameworkVersion.Version461)) <> null then Net461 - elif box (ToolLocationHelper.GetPathToDotNetFramework(TargetDotNetFrameworkVersion.Version46)) <> null then Net46 - // 4.5.2 enumeration is not available in Dev15 MSBuild version - //elif box (ToolLocationHelper.GetPathToDotNetFramework(TargetDotNetFrameworkVersion.Version452)) <> null then Net452 - elif box (ToolLocationHelper.GetPathToDotNetFramework(TargetDotNetFrameworkVersion.Version451)) <> null then Net451 + /// Use MSBuild to determine the version of the highest installed set of reference assemblies, failing that grab the highest installed framework version + let HighestInstalledRefAssembliesOrDotNETFramework () = + let getHighestInstalledDotNETFramework () = + try +// The Mono build still uses an ancient version of msbuild from around Dev 14 +#if MSBUILD_AT_LEAST_15 + if box (ToolLocationHelper.GetPathToDotNetFramework(TargetDotNetFrameworkVersion.Version472)) <> null then Net472 + elif box (ToolLocationHelper.GetPathToDotNetFramework(TargetDotNetFrameworkVersion.Version471)) <> null then Net471 + elif box (ToolLocationHelper.GetPathToDotNetFramework(TargetDotNetFrameworkVersion.Version47)) <> null then Net47 + elif box (ToolLocationHelper.GetPathToDotNetFramework(TargetDotNetFrameworkVersion.Version462)) <> null then Net462 + elif box (ToolLocationHelper.GetPathToDotNetFramework(TargetDotNetFrameworkVersion.Version461)) <> null then Net461 + elif box (ToolLocationHelper.GetPathToDotNetFramework(TargetDotNetFrameworkVersion.Version461)) <> null then Net461 + elif box (ToolLocationHelper.GetPathToDotNetFramework(TargetDotNetFrameworkVersion.Version46)) <> null then Net46 + elif box (ToolLocationHelper.GetPathToDotNetFramework(TargetDotNetFrameworkVersion.Version452)) <> null then Net452 + elif box (ToolLocationHelper.GetPathToDotNetFramework(TargetDotNetFrameworkVersion.Version451)) <> null then Net451 #else - if box (ToolLocationHelper.GetPathToDotNetFramework(TargetDotNetFrameworkVersion.Version451)) <> null then Net451 + if box (ToolLocationHelper.GetPathToDotNetFramework(TargetDotNetFrameworkVersion.Version451)) <> null then Net451 +#endif + elif box (ToolLocationHelper.GetPathToDotNetFramework(TargetDotNetFrameworkVersion.Version45)) <> null then Net45 + else Net45 // version is 4.5 assumed since this code is running. + with _ -> Net45 + +#if !FX_RESHAPED_REFLECTION + // 1. First look to see if we can find the highest installed set of dotnet reference assemblies, if yes then select that framework + // 2. Otherwise ask msbuild for the highestinstalled framework + let checkFrameworkForReferenceAssemblies (dotNetVersion:string) = + if not (String.IsNullOrEmpty(dotNetVersion)) then + try + let v = if dotNetVersion.StartsWith("v") then dotNetVersion.Substring(1) else dotNetVersion + let frameworkName = new System.Runtime.Versioning.FrameworkName(".NETFramework", new Version(v)) + match ToolLocationHelper.GetPathToReferenceAssemblies(frameworkName) |> Seq.tryHead with + | Some p -> if Directory.Exists(p) then true else false + | None -> false + with _ -> false + else false + match SupportedDesktopFrameworkVersions |> Seq.tryFind(fun v -> checkFrameworkForReferenceAssemblies v) with + | Some v -> v + | None -> getHighestInstalledDotNETFramework() +#else + getHighestInstalledDotNETFramework() #endif - elif box (ToolLocationHelper.GetPathToDotNetFramework(TargetDotNetFrameworkVersion.Version45)) <> null then Net45 - else Net45 // version is 4.5 assumed since this code is running. - with _ -> Net45 - /// Derive the target framework directories. + /// Derive the target framework directories. let DeriveTargetFrameworkDirectories (targetFrameworkVersion:string, logMessage) = let targetFrameworkVersion = if not(targetFrameworkVersion.StartsWith("v",StringComparison.Ordinal)) then "v"+targetFrameworkVersion else targetFrameworkVersion - let result = - if targetFrameworkVersion.StartsWith(Net10, StringComparison.Ordinal) then ReplaceVariablesForLegacyFxOnWindows([@"{WindowsFramework}\v1.0.3705"]) - elif targetFrameworkVersion.StartsWith(Net11, StringComparison.Ordinal) then ReplaceVariablesForLegacyFxOnWindows([@"{WindowsFramework}\v1.1.4322"]) - elif targetFrameworkVersion.StartsWith(Net20, StringComparison.Ordinal) then ReplaceVariablesForLegacyFxOnWindows([@"{WindowsFramework}\v2.0.50727"]) - elif targetFrameworkVersion.StartsWith(Net30, StringComparison.Ordinal) then ReplaceVariablesForLegacyFxOnWindows([@"{ReferenceAssemblies}\v3.0"; @"{WindowsFramework}\v3.0"; @"{WindowsFramework}\v2.0.50727"]) - elif targetFrameworkVersion.StartsWith(Net35, StringComparison.Ordinal) then ReplaceVariablesForLegacyFxOnWindows([@"{ReferenceAssemblies}\v3.5"; @"{WindowsFramework}\v3.5"; @"{ReferenceAssemblies}\v3.0"; @"{WindowsFramework}\v3.0"; @"{WindowsFramework}\v2.0.50727"]) - else GetPathToDotNetFrameworkReferenceAssemblies(targetFrameworkVersion) - - let result = result |> Array.ofList - logMessage (sprintf "Derived target framework directories for version %s are: %s" targetFrameworkVersion (String.Join(",", result))) + let result = GetPathToDotNetFrameworkReferenceAssemblies(targetFrameworkVersion) |> Array.ofList + logMessage (sprintf "Derived target framework directories for version %s are: %s" targetFrameworkVersion (String.Join(",", result))) result - + /// Describes the location where the reference was found, used only for debug and tooltip output type ResolvedFrom = | AssemblyFolders @@ -364,7 +371,7 @@ module internal Microsoft.FSharp.Compiler.MSBuildReferenceResolver let Resolver = { new ReferenceResolver.Resolver with - member __.HighestInstalledNetFrameworkVersion() = HighestInstalledNetFrameworkVersion() + member __.HighestInstalledNetFrameworkVersion() = HighestInstalledRefAssembliesOrDotNETFramework() member __.DotNetFrameworkReferenceAssembliesRootDirectory = DotNetFrameworkReferenceAssembliesRootDirectory /// Perform the resolution on rooted and unrooted paths, and then combine the results. diff --git a/src/fsharp/MethodCalls.fs b/src/fsharp/MethodCalls.fs index d51bbe953c..de5271eb67 100644 --- a/src/fsharp/MethodCalls.fs +++ b/src/fsharp/MethodCalls.fs @@ -346,9 +346,9 @@ type CalledMeth<'T> Choice1Of2(AssignedItemSetter(id, AssignedILFieldSetter(finfo), e)) | _ -> match infoReader.TryFindRecdOrClassFieldInfoOfType(nm, m, returnedObjTy) with - | Some rfinfo -> + | ValueSome rfinfo -> Choice1Of2(AssignedItemSetter(id, AssignedRecdFieldSetter(rfinfo), e)) - | None -> + | _ -> Choice2Of2(arg)) let names = namedCallerArgs |> List.map (fun (CallerNamedArg(nm, _)) -> nm.idText) @@ -585,7 +585,7 @@ let TakeObjAddrForMethodCall g amap (minfo:MethInfo) isMutable m objArgs f = let hasCallInfo = ccallInfo.IsSome let mustTakeAddress = hasCallInfo || minfo.ObjArgNeedsAddress(amap, m) let objArgTy = tyOfExpr g objArgExpr - let wrap, objArgExpr', _readonly, _writeonly = mkExprAddrOfExpr g mustTakeAddress hasCallInfo isMutable objArgExpr None m + let wrap, objArgExpr', isReadOnly, _isWriteOnly = mkExprAddrOfExpr g mustTakeAddress hasCallInfo isMutable objArgExpr None m // Extension members and calls to class constraints may need a coercion for their object argument let objArgExpr' = @@ -595,6 +595,16 @@ let TakeObjAddrForMethodCall g amap (minfo:MethInfo) isMutable m objArgs f = else objArgExpr' + // Check to see if the extension member uses the extending type as a byref. + // If so, make sure we don't allow readonly/immutable values to be passed byref from an extension member. + // An inref will work though. + if isReadOnly && mustTakeAddress && minfo.IsExtensionMember then + minfo.TryObjArgByrefType(amap, m, minfo.FormalMethodInst) + |> Option.iter (fun ty -> + if not (isInByrefTy g ty) then + errorR(Error(FSComp.SR.tcCannotCallExtensionMethodInrefToByref(minfo.DisplayName), m))) + + wrap, [objArgExpr'] | _ -> diff --git a/src/fsharp/NameResolution.fs b/src/fsharp/NameResolution.fs index cf4d50c4a2..9434740d31 100644 --- a/src/fsharp/NameResolution.fs +++ b/src/fsharp/NameResolution.fs @@ -155,6 +155,9 @@ type Item = /// Represents the resolution of a name to an F# record field. | RecdField of RecdFieldInfo + /// Represents the resolution of a name to a field of an anonymous record type. + | AnonRecdField of AnonRecdTypeInfo * TTypes * int * range + // The following are never in the items table but are valid results of binding // an identifier in different circumstances. @@ -226,6 +229,7 @@ type Item = | Item.UnionCase(uinfo,_) -> DecompileOpName uinfo.UnionCase.DisplayName | Item.ExnCase tcref -> tcref.LogicalName | Item.RecdField rfinfo -> DecompileOpName rfinfo.RecdField.Name + | Item.AnonRecdField (anonInfo, _tys, i, _m) -> anonInfo.SortedNames.[i] | Item.NewDef id -> id.idText | Item.ILField finfo -> finfo.FieldName | Item.Event einfo -> einfo.EventName @@ -430,8 +434,7 @@ let private GetCSharpStyleIndexedExtensionMembersForTyconRef (amap:Import.Import // Method must be static, have 'Extension' attribute, must not be curried, must have at least one argument if not minfo.IsInstance && not minfo.IsExtensionMember && - minfo.NumArgs.Length = 1 && - minfo.NumArgs.Head >= 1 && + (match minfo.NumArgs with [x] when x >= 1 -> true | _ -> false) && MethInfoHasAttribute g m g.attrib_ExtensionAttribute minfo then let ilExtMem = ILExtMem (tcrefOfStaticClass, minfo, pri) @@ -693,9 +696,6 @@ let private AddPartsOfTyconRefToNameEnv bulkAddMode ownDefinition (g:TcGlobals) eIndexedExtensionMembers = eIndexedExtensionMembers eUnindexedExtensionMembers = eUnindexedExtensionMembers } -let TryFindPatternByName name {ePatItems = patternMap} = - NameMap.tryFind name patternMap - /// Add a set of type definitions to the name resolution environment let AddTyconRefsToNameEnv bulkAddMode ownDefinition g amap m root nenv tcrefs = if isNil tcrefs then nenv else @@ -985,10 +985,8 @@ type TypeNameResolutionStaticArgsInfo = // Get the first possible mangled name of the type, assuming the args are generic args member x.MangledNameForType nm = - if IsMangledGenericName nm || x.NumStaticArgs = 0 then nm - else nm+"`"+string x.NumStaticArgs - - + if x.NumStaticArgs = 0 || TryDemangleGenericNameAndPos nm <> ValueNone then nm + else nm + "`" + string x.NumStaticArgs [] /// Represents information which guides name resolution of types. @@ -1011,17 +1009,21 @@ type TypeNameResolutionInfo = /// be used to qualify access if needed let LookupTypeNameInEntityHaveArity nm (staticResInfo: TypeNameResolutionStaticArgsInfo) (mty:ModuleOrNamespaceType) = let attempt1 = mty.TypesByMangledName.TryFind (staticResInfo.MangledNameForType nm) - match attempt1 with - | Some _ as r -> r + match attempt1 with | None -> mty.TypesByMangledName.TryFind nm + | _ -> attempt1 /// Unqualified lookups of type names where the number of generic arguments is known /// from context, e.g. List. Rebindings due to 'open' may have rebound identifiers. let LookupTypeNameInEnvHaveArity fq nm numTyArgs (nenv:NameResolutionEnv) = - let key = if IsMangledGenericName nm then DecodeGenericTypeName nm else NameArityPair(nm,numTyArgs) - match nenv.TyconsByDemangledNameAndArity(fq).TryFind(key) with - | Some res -> Some res + let key = + match TryDemangleGenericNameAndPos nm with + | ValueSome pos -> DecodeGenericTypeName pos nm + | _ -> NameArityPair(nm,numTyArgs) + + match nenv.TyconsByDemangledNameAndArity(fq).TryFind key with | None -> nenv.TyconsByAccessNames(fq).TryFind nm |> Option.map List.head + | res -> res /// Implements unqualified lookups of type names where the number of generic arguments is NOT known /// from context. @@ -1040,16 +1042,18 @@ let LookupTypeNameInEnvHaveArity fq nm numTyArgs (nenv:NameResolutionEnv) = // In theory the full names such as ``RecordType`1`` can // also be used to qualify access if needed, though this is almost never needed. -let LookupTypeNameNoArity nm (byDemangledNameAndArity: LayeredMap) (byAccessNames: LayeredMultiMap) = - if IsMangledGenericName nm then - match byDemangledNameAndArity.TryFind (DecodeGenericTypeName nm) with - | Some res -> [res] - | None -> - match byAccessNames.TryFind nm with - | Some res -> res - | None -> [] - else - byAccessNames.[nm] +let LookupTypeNameNoArity nm (byDemangledNameAndArity: LayeredMap) (byAccessNames: LayeredMultiMap) = + match TryDemangleGenericNameAndPos nm with + | ValueSome pos -> + let demangled = DecodeGenericTypeName pos nm + match byDemangledNameAndArity.TryGetValue demangled with + | true, res -> [res] + | _ -> + match byAccessNames.TryGetValue nm with + | true, res -> res + | _ -> [] + | _ -> + byAccessNames.[nm] /// Qualified lookup of type names in the environment let LookupTypeNameInEnvNoArity fq nm (nenv: NameResolutionEnv) = @@ -1096,7 +1100,7 @@ let AddEntityForProvidedType (amap: Import.ImportMap, modref: ModuleOrNamespaceR let tycon = Construct.NewProvidedTycon(resolutionEnvironment, st, importProvidedType, isSuppressRelocate, m) modref.ModuleOrNamespaceType.AddProvidedTypeEntity(tycon) let tcref = modref.NestedTyconRef tycon - System.Diagnostics.Debug.Assert modref.TryDeref.IsSome + System.Diagnostics.Debug.Assert(ValueOptionInternal.isSome modref.TryDeref) tcref @@ -1208,7 +1212,7 @@ let GetNestedTypesOfType (ad, ncenv:NameResolver, optFilter, staticResInfo, chec //------------------------------------------------------------------------- /// Represents the kind of the occurrence when reporting a name in name resolution -[] +[] type ItemOccurence = /// This is a binding / declaration of the item | Binding @@ -1247,8 +1251,8 @@ type OpenDeclaration = IsOwnNamespace = isOwnNamespace } type FormatStringCheckContext = - { NormalizedSource: string - LineEndPositions: int[] } + { Source: string + LineStartPositions: int[] } /// An abstract type for reporting the results of name resolution and type checking. type ITypecheckResultsSink = @@ -1411,6 +1415,8 @@ let ItemsAreEffectivelyEqual g orig other = | (Item.ArgName (id,_, _), ValUse vref) | (ValUse vref, Item.ArgName (id, _, _)) -> ((id.idRange = vref.DefinitionRange || id.idRange = vref.SigRange) && id.idText = vref.DisplayName) + | Item.AnonRecdField(anon1, _, i1, _), Item.AnonRecdField(anon2, _, i2, _) -> Tastops.anonInfoEquiv anon1 anon2 && i1 = i2 + | ILFieldUse f1, ILFieldUse f2 -> ILFieldInfo.ILFieldInfosUseIdenticalDefinitions f1 f2 @@ -1490,17 +1496,24 @@ type TcSymbolUseData = /// This is a memory-critical data structure - allocations of this data structure and its immediate contents /// is one of the highest memory long-lived data structures in typical uses of IDEs. Not many of these objects /// are allocated (one per file), but they are large because the allUsesOfAllSymbols array is large. -type TcSymbolUses(g, capturedNameResolutions : ResizeArray, formatSpecifierLocations: (range * int)[]) = - +type TcSymbolUses(g, capturedNameResolutions : ResizeArray, formatSpecifierLocations: (range * int)[]) = + // Make sure we only capture the information we really need to report symbol uses - let allUsesOfSymbols = [| for cnr in capturedNameResolutions -> { Item=cnr.Item; ItemOccurence=cnr.ItemOccurence; DisplayEnv=cnr.DisplayEnv; Range=cnr.Range } |] + let allUsesOfSymbols = + capturedNameResolutions + |> ResizeArray.mapToSmallArrayChunks (fun cnr -> { Item=cnr.Item; ItemOccurence=cnr.ItemOccurence; DisplayEnv=cnr.DisplayEnv; Range=cnr.Range }) + let capturedNameResolutions = () do ignore capturedNameResolutions // don't capture this! member this.GetUsesOfSymbol(item) = - [| for symbolUse in allUsesOfSymbols do - if protectAssemblyExploration false (fun () -> ItemsAreEffectivelyEqual g item symbolUse.Item) then - yield symbolUse |] + // This member returns what is potentially a very large array, which may approach the size constraints of the Large Object Heap. + // This is unlikely in practice, though, because we filter down the set of all symbol uses to those specifically for the given `item`. + // Consequently we have a much lesser chance of ending up with an array large enough to be promoted to the LOH. + [| for symbolUseChunk in allUsesOfSymbols do + for symbolUse in symbolUseChunk do + if protectAssemblyExploration false (fun () -> ItemsAreEffectivelyEqual g item symbolUse.Item) then + yield symbolUse |] member this.AllUsesOfSymbols = allUsesOfSymbols @@ -1532,14 +1545,18 @@ type TcResultsSinkImpl(g, ?source: string) = let formatStringCheckContext = lazy source |> Option.map (fun source -> - let source = source.Replace("\r\n", "\n").Replace("\r", "\n") let positions = - source.Split('\n') - |> Seq.map (fun s -> String.length s + 1) - |> Seq.scan (+) 0 - |> Seq.toArray - { NormalizedSource = source - LineEndPositions = positions }) + [| + yield 0 + for i in 1..source.Length do + let c = source.[i-1] + if c = '\r' && i < source.Length && source.[i] = '\n' then () + elif c = '\r' then yield i + elif c = '\n' then yield i + yield source.Length + |] + { Source = source + LineStartPositions = positions }) member this.GetResolutions() = TcResolutions(capturedEnvs, capturedExprTypings, capturedNameResolutions, capturedMethodGroupResolutions) @@ -1693,6 +1710,7 @@ let CheckAllTyparsInferrable amap m item = | Item.UnionCase _ | Item.ExnCase _ | Item.RecdField _ + | Item.AnonRecdField _ | Item.NewDef _ | Item.ILField _ | Item.Event _ @@ -1846,15 +1864,15 @@ let rec ResolveLongIndentAsModuleOrNamespace sink atMostOne amap m first fullyQu let occurence = if isOpenDecl then ItemOccurence.Open else ItemOccurence.Use CallNameResolutionSink sink (m, nenv, item, item, emptyTyparInst, occurence, nenv.DisplayEnv, ad) - match moduleOrNamespaces.TryFind id.idText with - | Some modrefs -> + match moduleOrNamespaces.TryGetValue id.idText with + | true, modrefs -> /// Look through the sub-namespaces and/or modules let rec look depth (modref: ModuleOrNamespaceRef) (mty:ModuleOrNamespaceType) (lid:Ident list) = match lid with | [] -> success (depth,modref,mty) | id :: rest -> - match mty.ModulesAndNamespacesByDemangledName.TryFind id.idText with - | Some mspec -> + match mty.ModulesAndNamespacesByDemangledName.TryGetValue id.idText with + | true, mspec -> let subref = modref.NestedTyconRef mspec if IsEntityAccessible amap m ad subref then notifyNameResolution subref id.idRange @@ -1870,7 +1888,7 @@ let rec ResolveLongIndentAsModuleOrNamespace sink atMostOne amap m first fullyQu look 1 modref modref.ModuleOrNamespaceType rest else raze (namespaceNotFound.Force())) - | None -> raze (namespaceNotFound.Force()) + | _ -> raze (namespaceNotFound.Force()) let ResolveLongIndentAsModuleOrNamespaceThen sink atMostOne amap m fullyQualified (nenv:NameResolutionEnv) ad id rest isOpenDecl f = @@ -2046,13 +2064,22 @@ type LookupKind = /// Try to find a union case of a type, with the given name let TryFindUnionCaseOfType g ty nm = - if isAppTy g ty then - let tcref,tinst = destAppTy g ty + match tryAppTy g ty with + | ValueSome(tcref,tinst) -> match tcref.GetUnionCaseByName nm with + | None -> ValueNone + | Some ucase -> ValueSome(UnionCaseInfo(tinst,tcref.MakeNestedUnionCaseRef ucase)) + | _ -> + ValueNone + +/// Try to find a union case of a type, with the given name +let TryFindAnonRecdFieldOfType g typ nm = + match tryDestAnonRecdTy g typ with + | ValueSome (anonInfo, tys) -> + match anonInfo.SortedIds |> Array.tryFindIndex (fun x -> x.idText = nm) with + | Some i -> Some (Item.AnonRecdField(anonInfo, tys, i, anonInfo.SortedIds.[i].idRange)) | None -> None - | Some ucase -> Some(UnionCaseInfo(tinst,tcref.MakeNestedUnionCaseRef ucase)) - else - None + | ValueNone -> None let CoreDisplayName(pinfo:PropInfo) = match pinfo with @@ -2104,14 +2131,22 @@ let rec ResolveLongIdentInTypePrim (ncenv:NameResolver) nenv lookupKind (resInfo let unionCaseSearch = match lookupKind with | LookupKind.Expr | LookupKind.Pattern -> TryFindUnionCaseOfType g ty nm - | _ -> None + | _ -> ValueNone // Lookup: datatype constructors take precedence match unionCaseSearch with - | Some ucase -> + | ValueSome ucase -> OneResult (success(resInfo,Item.UnionCase(ucase,false),rest)) - | None -> - let isLookUpExpr = lookupKind = LookupKind.Expr + | ValueNone -> + let anonRecdSearch = + match lookupKind with + | LookupKind.Expr -> TryFindAnonRecdFieldOfType g ty nm + | _ -> None + match anonRecdSearch with + | Some item -> + OneResult (success(resInfo, item, rest)) + | None -> + let isLookUpExpr = (lookupKind = LookupKind.Expr) match TryFindIntrinsicNamedItemOfType ncenv.InfoReader (nm,ad) findFlag m ty with | Some (PropertyItem psets) when isLookUpExpr -> let pinfos = psets |> ExcludeHiddenOfPropInfos g ncenv.amap m @@ -2124,6 +2159,7 @@ let rec ResolveLongIdentInTypePrim (ncenv:NameResolver) nenv lookupKind (resInfo match DecodeFSharpEvent (pinfos@extensionPropInfos) ad g ncenv m with | Some x -> success [resInfo, x, rest] | None -> raze (UndefinedName (depth,FSComp.SR.undefinedNameFieldConstructorOrMember, id,NoSuggestions)) + | Some(MethodItem msets) when isLookUpExpr -> let minfos = msets |> ExcludeHiddenOfMethInfos g ncenv.amap m @@ -2136,8 +2172,10 @@ let rec ResolveLongIdentInTypePrim (ncenv:NameResolver) nenv lookupKind (resInfo | Some (EventItem (einfo :: _)) when isLookUpExpr -> success [resInfo,Item.Event einfo,rest] + | Some (RecdFieldItem (rfinfo)) when (match lookupKind with LookupKind.Expr | LookupKind.RecdField | LookupKind.Pattern -> true | _ -> false) -> success [resInfo,Item.RecdField(rfinfo),rest] + | _ -> let pinfos = ExtensionPropInfosOfTypeInScope ncenv.InfoReader nenv (optFilter, ad) m ty @@ -2199,7 +2237,7 @@ let rec ResolveLongIdentInTypePrim (ncenv:NameResolver) nenv lookupKind (resInfo match lookupKind with | LookupKind.Expr | LookupKind.Pattern -> if isAppTy g ty then - let tcref,_ = destAppTy g ty + let tcref = tcrefOfAppTy g ty tcref.UnionCasesArray |> Array.map (fun uc -> uc.DisplayName) else @@ -2257,12 +2295,12 @@ let (|AccessibleEntityRef|_|) amap m ad (modref: ModuleOrNamespaceRef) mspec = let rec ResolveExprLongIdentInModuleOrNamespace (ncenv:NameResolver) nenv (typeNameResInfo: TypeNameResolutionInfo) ad resInfo depth m modref (mty:ModuleOrNamespaceType) (id:Ident) (rest :Ident list) = // resInfo records the modules or namespaces actually relevant to a resolution let m = unionRanges m id.idRange - match mty.AllValsByLogicalName.TryFind(id.idText) with - | Some vspec when IsValAccessible ad (mkNestedValRef modref vspec) -> + match mty.AllValsByLogicalName.TryGetValue id.idText with + | true, vspec when IsValAccessible ad (mkNestedValRef modref vspec) -> success(resInfo,Item.Value (mkNestedValRef modref vspec),rest) | _-> - match mty.ExceptionDefinitionsByDemangledName.TryFind(id.idText) with - | Some excon when IsTyconReprAccessible ncenv.amap m ad (modref.NestedTyconRef excon) -> + match mty.ExceptionDefinitionsByDemangledName.TryGetValue id.idText with + | true, excon when IsTyconReprAccessible ncenv.amap m ad (modref.NestedTyconRef excon) -> success (resInfo,Item.ExnCase (modref.NestedTyconRef excon),rest) | _ -> // Something in a discriminated union without RequireQualifiedAccess attribute? @@ -2308,8 +2346,8 @@ let rec ResolveExprLongIdentInModuleOrNamespace (ncenv:NameResolver) nenv (typeN let moduleSearch() = match rest with | id2::rest2 -> - match mty.ModulesAndNamespacesByDemangledName.TryFind(id.idText) with - | Some(AccessibleEntityRef ncenv.amap m ad modref submodref) -> + match mty.ModulesAndNamespacesByDemangledName.TryGetValue id.idText with + | true, AccessibleEntityRef ncenv.amap m ad modref submodref -> let resInfo = resInfo.AddEntity(id.idRange,submodref) OneResult (ResolveExprLongIdentInModuleOrNamespace ncenv nenv typeNameResInfo ad resInfo (depth+1) m submodref submodref.ModuleOrNamespaceType id2 rest2) @@ -2394,10 +2432,10 @@ let rec ResolveExprLongIdentPrim sink (ncenv:NameResolver) first fullyQualified let typeError = ref None // Single identifier. Lookup the unqualified names in the environment let envSearch = - match nenv.eUnqualifiedItems.TryFind(id.idText) with + match nenv.eUnqualifiedItems.TryGetValue id.idText with // The name is a type name and it has not been clobbered by some other name - | Some (Item.UnqualifiedType tcrefs) -> + | true, Item.UnqualifiedType tcrefs -> // Do not use type names from the environment if an explicit type instantiation is // given and the number of type parameters do not match @@ -2414,9 +2452,9 @@ let rec ResolveExprLongIdentPrim sink (ncenv:NameResolver) first fullyQualified Some(item,rest) | Exception e -> typeError := Some e; None - | Some res -> + | true, res -> Some (FreshenUnqualifiedItem ncenv m res, []) - | None -> + | _ -> None match envSearch with @@ -2498,8 +2536,8 @@ let rec ResolveExprLongIdentPrim sink (ncenv:NameResolver) first fullyQualified match fullyQualified with | FullyQualified -> false | _ -> - match nenv.eUnqualifiedItems.TryFind(nm) with - | Some(Item.Value _) -> true + match nenv.eUnqualifiedItems.TryGetValue nm with + | true, Item.Value _ -> true | _ -> false if ValIsInEnv id.idText then @@ -2530,10 +2568,10 @@ let rec ResolveExprLongIdentPrim sink (ncenv:NameResolver) first fullyQualified | FullyQualified -> NoResultsOrUsefulErrors | OpenQualified -> - match nenv.eUnqualifiedItems.TryFind id.idText with - | Some (Item.UnqualifiedType _) - | None -> NoResultsOrUsefulErrors - | Some res -> OneSuccess (resInfo,FreshenUnqualifiedItem ncenv m res,rest) + match nenv.eUnqualifiedItems.TryGetValue id.idText with + | true, Item.UnqualifiedType _ + | false, _ -> NoResultsOrUsefulErrors + | true, res -> OneSuccess (resInfo,FreshenUnqualifiedItem ncenv m res,rest) moduleSearch ad () +++ tyconSearch ad +++ envSearch @@ -2597,17 +2635,17 @@ let rec ResolvePatternLongIdentInModuleOrNamespace (ncenv:NameResolver) nenv num let ucinfo = FreshenUnionCaseRef ncenv m ucref success (resInfo,Item.UnionCase(ucinfo,showDeprecated),rest) | _ -> - match mty.ExceptionDefinitionsByDemangledName.TryFind(id.idText) with - | Some exnc when IsEntityAccessible ncenv.amap m ad (modref.NestedTyconRef exnc) -> + match mty.ExceptionDefinitionsByDemangledName.TryGetValue id.idText with + | true, exnc when IsEntityAccessible ncenv.amap m ad (modref.NestedTyconRef exnc) -> success (resInfo,Item.ExnCase (modref.NestedTyconRef exnc),rest) | _ -> // An active pattern constructor in a module - match (ActivePatternElemsOfModuleOrNamespace modref).TryFind(id.idText) with - | Some ( APElemRef(_,vref,_) as apref) when IsValAccessible ad vref -> + match (ActivePatternElemsOfModuleOrNamespace modref).TryGetValue id.idText with + | true, (APElemRef(_,vref,_) as apref) when IsValAccessible ad vref -> success (resInfo,Item.ActivePatternCase apref,rest) | _ -> - match mty.AllValsByLogicalName.TryFind(id.idText) with - | Some vspec when IsValAccessible ad (mkNestedValRef modref vspec) -> + match mty.AllValsByLogicalName.TryGetValue id.idText with + | true, vspec when IsValAccessible ad (mkNestedValRef modref vspec) -> success(resInfo,Item.Value (mkNestedValRef modref vspec),rest) | _ -> let tcrefs = lazy ( @@ -2637,8 +2675,8 @@ let rec ResolvePatternLongIdentInModuleOrNamespace (ncenv:NameResolver) nenv num let moduleSearch() = match rest with | id2::rest2 -> - match mty.ModulesAndNamespacesByDemangledName.TryFind(id.idText) with - | Some(AccessibleEntityRef ncenv.amap m ad modref submodref) -> + match mty.ModulesAndNamespacesByDemangledName.TryGetValue id.idText with + | true, AccessibleEntityRef ncenv.amap m ad modref submodref -> let resInfo = resInfo.AddEntity(id.idRange,submodref) OneResult (ResolvePatternLongIdentInModuleOrNamespace ncenv nenv numTyArgsOpt ad resInfo (depth+1) m submodref submodref.ModuleOrNamespaceType id2 rest2) | _ -> @@ -2685,8 +2723,8 @@ let rec ResolvePatternLongIdentPrim sink (ncenv:NameResolver) fullyQualified war // Single identifiers in patterns - bind to constructors and active patterns // For the special case of // let C = x - match nenv.ePatItems.TryFind(id.idText) with - | Some res when not newDef -> FreshenUnqualifiedItem ncenv m res + match nenv.ePatItems.TryGetValue id.idText with + | true, res when not newDef -> FreshenUnqualifiedItem ncenv m res | _ -> // Single identifiers in patterns - variable bindings if not newDef && @@ -2832,8 +2870,8 @@ let rec private ResolveTypeLongIdentInModuleOrNamespace sink nenv (ncenv:NameRes | id2::rest2 -> let m = unionRanges m id.idRange let modulSearch = - match modref.ModuleOrNamespaceType.ModulesAndNamespacesByDemangledName.TryFind(id.idText) with - | Some(AccessibleEntityRef ncenv.amap m ad modref submodref) -> + match modref.ModuleOrNamespaceType.ModulesAndNamespacesByDemangledName.TryGetValue id.idText with + | true, AccessibleEntityRef ncenv.amap m ad modref submodref -> let item = Item.ModuleOrNamespaces [submodref] CallNameResolutionSink sink (id.idRange, nenv, item, item, emptyTyparInst, ItemOccurence.Use, nenv.DisplayEnv, ad) let resInfo = resInfo.AddEntity(id.idRange,submodref) @@ -2998,8 +3036,8 @@ let rec ResolveFieldInModuleOrNamespace (ncenv:NameResolver) nenv ad (resInfo:Re let modulSearch() = match rest with | id2::rest2 -> - match modref.ModuleOrNamespaceType.ModulesAndNamespacesByDemangledName.TryFind(id.idText) with - | Some(AccessibleEntityRef ncenv.amap m ad modref submodref) -> + match modref.ModuleOrNamespaceType.ModulesAndNamespacesByDemangledName.TryGetValue id.idText with + | true, AccessibleEntityRef ncenv.amap m ad modref submodref -> let resInfo = resInfo.AddEntity(id.idRange,submodref) ResolveFieldInModuleOrNamespace ncenv nenv ad resInfo (depth+1) m submodref submodref.ModuleOrNamespaceType id2 rest2 |> OneResult @@ -3033,9 +3071,9 @@ let SuggestLabelsOfRelatedRecords g (nenv:NameResolutionEnv) (id:Ident) (allFiel else let possibleRecords = [for fld in givenFields do - match Map.tryFind fld nenv.eFieldLabels with - | None -> () - | Some recordTypes -> yield! (recordTypes |> List.map (fun r -> r.TyconRef.DisplayName, fld)) ] + match nenv.eFieldLabels.TryGetValue fld with + | true, recordTypes -> yield! (recordTypes |> List.map (fun r -> r.TyconRef.DisplayName, fld)) + | _ -> () ] |> List.groupBy fst |> List.map (fun (r,fields) -> r, fields |> List.map snd) |> List.filter (fun (_,fields) -> givenFields.IsSubsetOf fields) @@ -3093,8 +3131,8 @@ let ResolveFieldPrim sink (ncenv:NameResolver) nenv ad ty (mp,id:Ident) allField if isAppTy g ty then match ncenv.InfoReader.TryFindRecdOrClassFieldInfoOfType(id.idText,m,ty) with - | Some (RecdFieldInfo(_,rfref)) -> [ResolutionInfo.Empty, FieldResolution(rfref,false)] - | None -> + | ValueSome (RecdFieldInfo(_,rfref)) -> [ResolutionInfo.Empty, FieldResolution(rfref,false)] + | _ -> if isRecdTy g ty then // record label doesn't belong to record type -> suggest other labels of same record let suggestLabels() = SuggestOtherLabelsOfSameRecordType g nenv ty id allFields @@ -3173,8 +3211,8 @@ let private ResolveExprDotLongIdent (ncenv:NameResolver) m ad nenv ty (id:Ident) if isAppTy ncenv.g ty then NoResultsOrUsefulErrors else - match nenv.eFieldLabels |> Map.tryFind id.idText with - | Some(rfref :: _) -> + match nenv.eFieldLabels.TryGetValue id.idText with + | true, rfref :: _ -> // NOTE (instantiationGenerator cleanup): we need to freshen here because we don't know the type. // But perhaps the caller should freshen?? let item = FreshenRecdFieldRef ncenv m rfref @@ -3403,27 +3441,25 @@ let ItemOfTy g x = let nm = if isAppTy g x then (tcrefOfAppTy g x).DisplayName else "?" Item.Types (nm,[x]) -// Filter out 'PrivateImplementationDetail' classes -let IsInterestingModuleName nm = - String.length nm >= 1 && - String.sub nm 0 1 <> "<" +// Filter out 'PrivateImplementationDetail' classes +let IsInterestingModuleName nm = not (System.String.IsNullOrEmpty nm) && nm.[0] <> '<' let rec PartialResolveLookupInModuleOrNamespaceAsModuleOrNamespaceThen f plid (modref:ModuleOrNamespaceRef) = let mty = modref.ModuleOrNamespaceType match plid with | [] -> f modref | id:: rest -> - match mty.ModulesAndNamespacesByDemangledName.TryFind(id) with - | Some mty -> PartialResolveLookupInModuleOrNamespaceAsModuleOrNamespaceThen f rest (modref.NestedTyconRef mty) - | None -> [] + match mty.ModulesAndNamespacesByDemangledName.TryGetValue id with + | true, mty -> PartialResolveLookupInModuleOrNamespaceAsModuleOrNamespaceThen f rest (modref.NestedTyconRef mty) + | _ -> [] let PartialResolveLongIndentAsModuleOrNamespaceThen (nenv:NameResolutionEnv) plid f = - match plid with + match plid with | id:: rest -> - match Map.tryFind id nenv.eModulesAndNamespaces with - | Some modrefs -> + match nenv.eModulesAndNamespaces.TryGetValue id with + | true, modrefs -> List.collect (PartialResolveLookupInModuleOrNamespaceAsModuleOrNamespaceThen f rest) modrefs - | None -> + | _ -> [] | [] -> [] @@ -3452,12 +3488,14 @@ let ResolveCompletionsInType (ncenv: NameResolver) nenv (completionTargets: Reso ncenv.InfoReader.GetRecordOrClassFieldsOfType(None,ad,m,ty) |> List.filter (fun rfref -> rfref.IsStatic = statics && IsFieldInfoAccessible ad rfref) - let ucinfos = - if completionTargets.ResolveAll && statics && isAppTy g ty then - let tc,tinst = destAppTy g ty - tc.UnionCasesAsRefList - |> List.filter (IsUnionCaseUnseen ad g ncenv.amap m >> not) - |> List.map (fun ucref -> Item.UnionCase(UnionCaseInfo(tinst,ucref),false)) + let ucinfos = + if completionTargets.ResolveAll && statics then + match tryAppTy g ty with + | ValueSome (tc,tinst) -> + tc.UnionCasesAsRefList + |> List.filter (IsUnionCaseUnseen ad g ncenv.amap m >> not) + |> List.map (fun ucref -> Item.UnionCase(UnionCaseInfo(tinst,ucref),false)) + | _ -> [] else [] let einfos = @@ -3509,13 +3547,11 @@ let ResolveCompletionsInType (ncenv: NameResolver) nenv (completionTargets: Reso yield einfo.RemoveMethod.DisplayName ] else [] - let suppressedMethNames = Zset.ofList String.order (pinfoMethNames @ einfoMethNames) - let pinfos = pinfosIncludingUnseen |> List.filter (fun x -> not (PropInfoIsUnseen m x)) - let minfoFilter (minfo:MethInfo) = + let minfoFilter (suppressedMethNames:Zset<_>) (minfo:MethInfo) = let isApplicableMeth = match completionTargets with | ResolveCompletionTargets.All x -> x @@ -3576,39 +3612,55 @@ let ResolveCompletionsInType (ncenv: NameResolver) nenv (completionTargets: Reso // REVIEW: add a name filter here in the common cases? let minfos = if completionTargets.ResolveAll then - let minfos = - AllMethInfosOfTypeInScope ncenv.InfoReader nenv (None,ad) PreferOverrides m ty - |> List.filter minfoFilter + let minfos = AllMethInfosOfTypeInScope ncenv.InfoReader nenv (None,ad) PreferOverrides m ty + if isNil minfos then + [] + else + let suppressedMethNames = Zset.ofList String.order (pinfoMethNames @ einfoMethNames) - let minfos = - let addersAndRemovers = - pinfoItems - |> List.collect (function Item.Event(FSEvent(_,_,addValRef,removeValRef)) -> [addValRef.LogicalName;removeValRef.LogicalName] | _ -> []) - |> set + let minfos = + minfos + |> List.filter (minfoFilter suppressedMethNames) - if addersAndRemovers.IsEmpty then minfos - else minfos |> List.filter (fun minfo -> not (addersAndRemovers.Contains minfo.LogicalName)) + if isNil minfos then + [] + else + let minfos = + let addersAndRemovers = + let hashSet = HashSet() + for item in pinfoItems do + match item with + | Item.Event(FSEvent(_,_,addValRef,removeValRef)) -> + hashSet.Add addValRef.LogicalName |> ignore + hashSet.Add removeValRef.LogicalName |> ignore + | _ -> () + hashSet + + if addersAndRemovers.Count = 0 then minfos + else minfos |> List.filter (fun minfo -> not (addersAndRemovers.Contains minfo.LogicalName)) #if !NO_EXTENSIONTYPING - // Filter out the ones with mangled names from applying static parameters - let minfos = - let methsWithStaticParams = - minfos - |> List.filter (fun minfo -> - match minfo.ProvidedStaticParameterInfo with - | Some (_methBeforeArguments, staticParams) -> staticParams.Length <> 0 - | _ -> false) - |> List.map (fun minfo -> minfo.DisplayName) - - if methsWithStaticParams.IsEmpty then minfos - else minfos |> List.filter (fun minfo -> - let nm = minfo.LogicalName - not (nm.Contains "," && methsWithStaticParams |> List.exists (fun m -> nm.StartsWithOrdinal(m)))) + // Filter out the ones with mangled names from applying static parameters + let minfos = + let methsWithStaticParams = + minfos + |> List.filter (fun minfo -> + match minfo.ProvidedStaticParameterInfo with + | Some (_methBeforeArguments, staticParams) -> staticParams.Length <> 0 + | _ -> false) + |> List.map (fun minfo -> minfo.DisplayName) + + if methsWithStaticParams.IsEmpty then minfos + else minfos |> List.filter (fun minfo -> + let nm = minfo.LogicalName + not (nm.Contains "," && methsWithStaticParams |> List.exists (fun m -> nm.StartsWithOrdinal(m)))) #endif - minfos + minfos + + else + [] - else [] // Partition methods into overload sets let rec partitionl (l:MethInfo list) acc = match l with @@ -3617,10 +3669,20 @@ let ResolveCompletionsInType (ncenv: NameResolver) nenv (completionTargets: Reso let nm = h.LogicalName partitionl t (NameMultiMap.add nm h acc) + let anonFields = + if statics then [] + else + match tryDestAnonRecdTy g ty with + | ValueSome (anonInfo, tys) -> + [ for (i,id) in Array.indexed anonInfo.SortedIds do + yield Item.AnonRecdField(anonInfo, tys, i, id.idRange) ] + | _ -> [] + // Build the results ucinfos @ List.map Item.RecdField rfinfos @ pinfoItems @ + anonFields @ List.map Item.ILField finfos @ List.map Item.Event einfos @ List.map (ItemOfTy g) nestedTypes @ @@ -3635,29 +3697,33 @@ let rec ResolvePartialLongIdentInType (ncenv: NameResolver) nenv isApplicableMet | id :: rest -> let rfinfos = - ncenv.InfoReader.GetRecordOrClassFieldsOfType(None,ad,m,ty) - |> List.filter (fun fref -> IsRecdFieldAccessible ncenv.amap m ad fref.RecdFieldRef) - |> List.filter (fun fref -> fref.RecdField.IsStatic = statics) + ncenv.InfoReader.GetRecordOrClassFieldsOfType(None,ad,m,ty) + |> List.filter (fun fref -> fref.Name = id && IsRecdFieldAccessible ncenv.amap m ad fref.RecdFieldRef && fref.RecdField.IsStatic = statics) let nestedTypes = ty |> GetNestedTypesOfType (ad, ncenv, Some id, TypeNameResolutionStaticArgsInfo.Indefinite, false, m) // e.g. .. - (rfinfos |> List.filter (fun x -> x.Name = id) - |> List.collect (fun x -> x.FieldType |> ResolvePartialLongIdentInType ncenv nenv isApplicableMeth m ad false rest)) @ + (rfinfos |> List.collect (fun x -> x.FieldType |> ResolvePartialLongIdentInType ncenv nenv isApplicableMeth m ad false rest)) @ // e.g. .. let FullTypeOfPinfo(pinfo:PropInfo) = - let rty = pinfo.GetPropertyType(amap,m) - let rty = if pinfo.IsIndexer then mkRefTupledTy g (pinfo.GetParamTypes(amap, m)) --> rty else rty - rty + let rty = pinfo.GetPropertyType(amap,m) + let rty = if pinfo.IsIndexer then mkRefTupledTy g (pinfo.GetParamTypes(amap, m)) --> rty else rty + rty + (ty |> AllPropInfosOfTypeInScope ncenv.InfoReader nenv (Some id,ad) IgnoreOverrides m - |> List.filter (fun x -> x.IsStatic = statics) - |> List.filter (IsPropInfoAccessible g amap m ad) + |> List.filter (fun pinfo -> pinfo.IsStatic = statics && IsPropInfoAccessible g amap m ad pinfo) |> List.collect (fun pinfo -> (FullTypeOfPinfo pinfo) |> ResolvePartialLongIdentInType ncenv nenv isApplicableMeth m ad false rest)) @ + (if statics then [] + else + match TryFindAnonRecdFieldOfType g ty id with + | Some (Item.AnonRecdField(_anonInfo, tys, i, _)) -> ResolvePartialLongIdentInType ncenv nenv isApplicableMeth m ad false rest tys.[i] + | _ -> []) @ + // e.g. .. (ncenv.InfoReader.GetEventInfosOfType(Some id,ad,m,ty) |> List.collect (PropTypOfEventInfo ncenv.InfoReader m ad >> ResolvePartialLongIdentInType ncenv nenv isApplicableMeth m ad false rest)) @ @@ -3689,9 +3755,10 @@ let InfosForTyconConstructors (ncenv:NameResolver) m ad (tcref:TyconRef) = | Item.CtorGroup(nm,ctorInfos) -> let ctors = ctorInfos - |> List.filter (IsMethInfoAccessible amap m ad) - |> List.filter (MethInfoIsUnseen g m ty >> not) - match ctors with + |> List.filter (fun minfo -> + IsMethInfoAccessible amap m ad minfo && + not (MethInfoIsUnseen g m ty minfo)) + match ctors with | [] -> [] | _ -> [Item.MakeCtorGroup(nm,ctors)] | item -> @@ -3699,9 +3766,23 @@ let InfosForTyconConstructors (ncenv:NameResolver) m ad (tcref:TyconRef) = | Exception _ -> [] /// import.fs creates somewhat fake modules for nested members of types (so that -/// types never contain other types) -let notFakeContainerModule tyconNames nm = - not (Set.contains nm tyconNames) +/// types never contain other types) +let inline notFakeContainerModule (tyconNames:HashSet<_>) nm = + not (tyconNames.Contains nm) + +let getFakeContainerModulesFromTycons (tycons:#seq) = + let hashSet = HashSet() + for tycon in tycons do + if tycon.IsILTycon then + hashSet.Add tycon.DisplayName |> ignore + hashSet + +let getFakeContainerModulesFromTyconRefs (tyconRefs:#seq) = + let hashSet = HashSet() + for tyconRef in tyconRefs do + if tyconRef.IsILTycon then + hashSet.Add tyconRef.DisplayName |> ignore + hashSet /// Check is a namespace or module contains something accessible let rec private EntityRefContainsSomethingAccessible (ncenv: NameResolver) m ad (modref:ModuleOrNamespaceRef) = @@ -3745,21 +3826,34 @@ let rec ResolvePartialLongIdentInModuleOrNamespace (ncenv: NameResolver) nenv is match plid with | [] -> let tycons = - mty.TypeDefinitions - |> List.filter (fun tcref -> not (tcref.LogicalName.Contains(","))) - |> List.filter (fun tycon -> not (IsTyconUnseen ad g ncenv.amap m (modref.NestedTyconRef tycon))) - - let ilTyconNames = - mty.TypesByAccessNames.Values - |> List.choose (fun (tycon:Tycon) -> if tycon.IsILTycon then Some tycon.DisplayName else None) - |> Set.ofList + mty.TypeDefinitions |> List.filter (fun tcref -> + not (tcref.LogicalName.Contains(",")) && + not (IsTyconUnseen ad g ncenv.amap m (modref.NestedTyconRef tcref))) + + let accessibleSubModules = + let moduleOrNamespaces = + mty.ModulesAndNamespacesByDemangledName + |> NameMap.range + + if isNil moduleOrNamespaces then [] else + + let ilTyconNames = getFakeContainerModulesFromTycons mty.TypesByAccessNames.Values + + moduleOrNamespaces + |> List.filter (fun x -> + let demangledName = x.DemangledModuleOrNamespaceName + notFakeContainerModule ilTyconNames demangledName && IsInterestingModuleName demangledName) + |> List.map modref.NestedTyconRef + |> List.filter (fun tyref -> + not (IsTyconUnseen ad g ncenv.amap m tyref) && + EntityRefContainsSomethingAccessible ncenv m ad tyref) + |> List.map ItemForModuleOrNamespaceRef // Collect up the accessible values in the module, excluding the members (mty.AllValsAndMembers |> Seq.toList |> List.choose (TryMkValRefInModRef modref) // if the assembly load set is incomplete and we get a None value here, then ignore the value - |> List.filter (fun v -> not v.IsMember) - |> List.filter (IsValUnseen ad g m >> not) + |> List.filter (fun vref -> not vref.IsMember && not (IsValUnseen ad g m vref)) |> List.map Item.Value) // Collect up the accessible discriminated union cases in the module @@ -3781,16 +3875,7 @@ let rec ResolvePartialLongIdentInModuleOrNamespace (ncenv: NameResolver) nenv is |> List.filter (IsTyconUnseen ad g ncenv.amap m >> not) |> List.map Item.ExnCase) - // Collect up the accessible sub-modules - @ (mty.ModulesAndNamespacesByDemangledName - |> NameMap.range - |> List.filter (fun x -> - let demangledName = x.DemangledModuleOrNamespaceName - notFakeContainerModule ilTyconNames demangledName && IsInterestingModuleName demangledName) - |> List.map modref.NestedTyconRef - |> List.filter (IsTyconUnseen ad g ncenv.amap m >> not) - |> List.filter (EntityRefContainsSomethingAccessible ncenv m ad) - |> List.map ItemForModuleOrNamespaceRef) + @ accessibleSubModules // Get all the types and .NET constructor groups accessible from here @ (tycons @@ -3801,11 +3886,13 @@ let rec ResolvePartialLongIdentInModuleOrNamespace (ncenv: NameResolver) nenv is | id :: rest -> - (match mty.ModulesAndNamespacesByDemangledName.TryFind(id) with - | Some mspec - when not (IsTyconUnseenObsoleteSpec ad g ncenv.amap m (modref.NestedTyconRef mspec) allowObsolete) -> - let allowObsolete = rest <> [] && allowObsolete - ResolvePartialLongIdentInModuleOrNamespace ncenv nenv isApplicableMeth m ad (modref.NestedTyconRef mspec) rest allowObsolete + (match mty.ModulesAndNamespacesByDemangledName.TryGetValue id with + | true, mspec -> + let nested = modref.NestedTyconRef mspec + if IsTyconUnseenObsoleteSpec ad g ncenv.amap m nested allowObsolete then [] else + let allowObsolete = allowObsolete && not (isNil rest) + ResolvePartialLongIdentInModuleOrNamespace ncenv nenv isApplicableMeth m ad nested rest allowObsolete + | _ -> []) @ (LookupTypeNameInEntityNoArity m id modref.ModuleOrNamespaceType @@ -3823,30 +3910,27 @@ let TryToResolveLongIdentAsType (ncenv: NameResolver) (nenv: NameResolutionEnv) match List.tryLast plid with | Some id -> // Look for values called 'id' that accept the dot-notation - let ty, isItemVal = - (match nenv.eUnqualifiedItems |> Map.tryFind id with + let ty = + match nenv.eUnqualifiedItems.TryGetValue id with // v.lookup : member of a value - | Some v -> - match v with - | Item.Value x -> - let ty = x.Type - let ty = if x.BaseOrThisInfo = CtorThisVal && isRefCellTy g ty then destRefCellTy g ty else ty - Some ty, true - | _ -> None, false - | None -> None, false) - - if isItemVal then ty - else - (ty, LookupTypeNameInEnvNoArity OpenQualified id nenv) - ||> List.fold (fun resTy tcref -> - // type.lookup : lookup a static something in a type + | true, v -> + match v with + | Item.Value x -> + let ty = x.Type + let ty = if x.BaseOrThisInfo = CtorThisVal && isRefCellTy g ty then destRefCellTy g ty else ty + Some ty + | _ -> None + | _ -> None + + match ty with + | Some _ -> ty + | _ -> + // type.lookup : lookup a static something in a type + LookupTypeNameInEnvNoArity OpenQualified id nenv + |> List.tryHead + |> Option.map (fun tcref -> let tcref = ResolveNestedTypeThroughAbbreviation ncenv tcref m - let ty = FreshenTycon ncenv m tcref - let resTy = - match resTy with - | Some _ -> resTy - | None -> Some ty - resTy) + FreshenTycon ncenv m tcref) | _ -> None /// allowObsolete - specifies whether we should return obsolete types & modules @@ -3861,10 +3945,6 @@ let rec ResolvePartialLongIdentPrim (ncenv: NameResolver) (nenv: NameResolutionE | [] -> - let ilTyconNames = - nenv.TyconsByAccessNames(fullyQualified).Values - |> List.choose (fun tyconRef -> if tyconRef.IsILTycon then Some tyconRef.DisplayName else None) - |> Set.ofList /// Include all the entries in the eUnqualifiedItems table. let unqualifiedItems = @@ -3886,21 +3966,28 @@ let rec ResolvePartialLongIdentPrim (ncenv: NameResolver) (nenv: NameResolutionE |> NameMap.range |> List.filter (function Item.ActivePatternCase _v -> true | _ -> false) - let moduleAndNamespaceItems = - nenv.ModulesAndNamespaces(fullyQualified) - |> NameMultiMap.range - |> List.filter (fun x -> - let demangledName = x.DemangledModuleOrNamespaceName - IsInterestingModuleName demangledName && notFakeContainerModule ilTyconNames demangledName) - |> List.filter (EntityRefContainsSomethingAccessible ncenv m ad) - |> List.filter (IsTyconUnseen ad g ncenv.amap m >> not) + let moduleAndNamespaceItems = + let moduleOrNamespaceRefs = + nenv.ModulesAndNamespaces fullyQualified + |> NameMultiMap.range + + if isNil moduleOrNamespaceRefs then [] else + let ilTyconNames = getFakeContainerModulesFromTyconRefs (nenv.TyconsByAccessNames(fullyQualified).Values) + + moduleOrNamespaceRefs + |> List.filter (fun modref -> + let demangledName = modref.DemangledModuleOrNamespaceName + IsInterestingModuleName demangledName && notFakeContainerModule ilTyconNames demangledName && + EntityRefContainsSomethingAccessible ncenv m ad modref && + not (IsTyconUnseen ad g ncenv.amap m modref)) |> List.map ItemForModuleOrNamespaceRef let tycons = nenv.TyconsByDemangledNameAndArity(fullyQualified).Values - |> List.filter (fun tcref -> not (tcref.LogicalName.Contains(","))) - |> List.filter (fun tcref -> not tcref.IsExceptionDecl) - |> List.filter (IsTyconUnseen ad g ncenv.amap m >> not) + |> List.filter (fun tcref -> + not (tcref.LogicalName.Contains(",")) && + not tcref.IsExceptionDecl && + not (IsTyconUnseen ad g ncenv.amap m tcref)) |> List.map (ItemOfTyconRef ncenv m) // Get all the constructors accessible from here @@ -3923,16 +4010,16 @@ let rec ResolvePartialLongIdentPrim (ncenv: NameResolver) (nenv: NameResolutionE []) // Look for values called 'id' that accept the dot-notation let values, isItemVal = - (match nenv.eUnqualifiedItems |> Map.tryFind id with + (match nenv.eUnqualifiedItems.TryGetValue id with // v.lookup : member of a value - | Some v -> + | true, v -> match v with | Item.Value x -> let ty = x.Type let ty = if x.BaseOrThisInfo = CtorThisVal && isRefCellTy g ty then destRefCellTy g ty else ty (ResolvePartialLongIdentInType ncenv nenv isApplicableMeth m ad false rest ty), true | _ -> [], false - | None -> [], false) + | _ -> [], false) let staticSometingInType = [ if not isItemVal then @@ -3958,43 +4045,52 @@ let rec ResolvePartialLongIdentInModuleOrNamespaceForRecordFields (ncenv: NameRe // get record type constructors let tycons = mty.TypeDefinitions - |> List.filter (fun tcref -> not (tcref.LogicalName.Contains(","))) - |> List.filter (fun tycon -> tycon.IsRecordTycon) - |> List.filter (fun tycon -> not (IsTyconUnseen ad g ncenv.amap m (modref.NestedTyconRef tycon))) - - let ilTyconNames = - mty.TypesByAccessNames.Values - |> List.choose (fun (tycon:Tycon) -> if tycon.IsILTycon then Some tycon.DisplayName else None) - |> Set.ofList + |> List.filter (fun tcref -> + not (tcref.LogicalName.Contains(",")) && + tcref.IsRecordTycon && + not (IsTyconUnseen ad g ncenv.amap m (modref.NestedTyconRef tcref))) + + + let accessibleSubModules = + let moduleOrNamespaces = + mty.ModulesAndNamespacesByDemangledName + |> NameMap.range + + if isNil moduleOrNamespaces then [] else + + let ilTyconNames = getFakeContainerModulesFromTycons mty.TypesByAccessNames.Values - // Collect up the accessible sub-modules - (mty.ModulesAndNamespacesByDemangledName - |> NameMap.range - |> List.filter (fun x -> - let demangledName = x.DemangledModuleOrNamespaceName - notFakeContainerModule ilTyconNames demangledName && IsInterestingModuleName demangledName) - |> List.map modref.NestedTyconRef - |> List.filter (IsTyconUnseen ad g ncenv.amap m >> not) - |> List.filter (EntityRefContainsSomethingAccessible ncenv m ad) - |> List.map ItemForModuleOrNamespaceRef) + moduleOrNamespaces + |> List.filter (fun x -> + let demangledName = x.DemangledModuleOrNamespaceName + notFakeContainerModule ilTyconNames demangledName && IsInterestingModuleName demangledName) + |> List.map modref.NestedTyconRef + |> List.filter (fun tcref -> + not (IsTyconUnseen ad g ncenv.amap m tcref) && + EntityRefContainsSomethingAccessible ncenv m ad tcref) + |> List.map ItemForModuleOrNamespaceRef + + accessibleSubModules // Collect all accessible record types @ (tycons |> List.map (modref.NestedTyconRef >> ItemOfTyconRef ncenv m) ) @ [ // accessible record fields for tycon in tycons do - if IsEntityAccessible ncenv.amap m ad (modref.NestedTyconRef tycon) then - let ttype = FreshenTycon ncenv m (modref.NestedTyconRef tycon) + let nested = modref.NestedTyconRef tycon + if IsEntityAccessible ncenv.amap m ad nested then + let ttype = FreshenTycon ncenv m nested yield! ncenv.InfoReader.GetRecordOrClassFieldsOfType(None, ad, m, ttype) |> List.map Item.RecdField ] | id :: rest -> - (match mty.ModulesAndNamespacesByDemangledName.TryFind(id) with - | Some mspec - when not (IsTyconUnseenObsoleteSpec ad g ncenv.amap m (modref.NestedTyconRef mspec) allowObsolete) -> - let allowObsolete = rest <> [] && allowObsolete - ResolvePartialLongIdentInModuleOrNamespaceForRecordFields ncenv nenv m ad (modref.NestedTyconRef mspec) rest allowObsolete + (match mty.ModulesAndNamespacesByDemangledName.TryGetValue id with + | true, mspec -> + let nested = modref.NestedTyconRef mspec + if IsTyconUnseenObsoleteSpec ad g ncenv.amap m nested allowObsolete then [] else + let allowObsolete = allowObsolete && not (isNil rest) + ResolvePartialLongIdentInModuleOrNamespaceForRecordFields ncenv nenv m ad nested rest allowObsolete | _ -> []) @ ( match rest with @@ -4026,26 +4122,31 @@ and ResolvePartialLongIdentToClassOrRecdFieldsImpl (ncenv: NameResolver) (nenv: | [] -> // empty plid - return namespaces\modules\record types\accessible fields - let iltyconNames = - nenv.TyconsByAccessNames(fullyQualified).Values - |> List.choose (fun tyconRef -> if tyconRef.IsILTycon then Some tyconRef.DisplayName else None) - |> Set.ofList + let mods = - nenv.ModulesAndNamespaces(fullyQualified) - |> NameMultiMap.range - |> List.filter (fun x -> - let demangledName = x.DemangledModuleOrNamespaceName - IsInterestingModuleName demangledName && notFakeContainerModule iltyconNames demangledName) - |> List.filter (EntityRefContainsSomethingAccessible ncenv m ad) - |> List.filter (IsTyconUnseen ad g ncenv.amap m >> not) + let moduleOrNamespaceRefs = + nenv.ModulesAndNamespaces fullyQualified + |> NameMultiMap.range + + if isNil moduleOrNamespaceRefs then [] else + + let ilTyconNames = getFakeContainerModulesFromTyconRefs (nenv.TyconsByAccessNames(fullyQualified).Values) + + moduleOrNamespaceRefs + |> List.filter (fun modref -> + let demangledName = modref.DemangledModuleOrNamespaceName + IsInterestingModuleName demangledName && notFakeContainerModule ilTyconNames demangledName && + EntityRefContainsSomethingAccessible ncenv m ad modref && + not (IsTyconUnseen ad g ncenv.amap m modref)) |> List.map ItemForModuleOrNamespaceRef let recdTyCons = nenv.TyconsByDemangledNameAndArity(fullyQualified).Values - |> List.filter (fun tcref -> not (tcref.LogicalName.Contains(","))) - |> List.filter (fun tcref -> tcref.IsRecordTycon) - |> List.filter (IsTyconUnseen ad g ncenv.amap m >> not) + |> List.filter (fun tcref -> + not (tcref.LogicalName.Contains(",")) && + tcref.IsRecordTycon && + not (IsTyconUnseen ad g ncenv.amap m tcref)) |> List.map (ItemOfTyconRef ncenv m) let recdFields = @@ -4092,12 +4193,14 @@ let ResolveCompletionsInTypeForItem (ncenv: NameResolver) nenv m ad statics ty ( |> List.filter (fun rfref -> rfref.IsStatic = statics && IsFieldInfoAccessible ad rfref) |> List.map Item.RecdField | Item.UnionCase _ -> - if statics && isAppTy g ty then - let tc, tinst = destAppTy g ty - yield! - tc.UnionCasesAsRefList - |> List.filter (IsUnionCaseUnseen ad g ncenv.amap m >> not) - |> List.map (fun ucref -> Item.UnionCase(UnionCaseInfo(tinst,ucref),false)) + if statics then + match tryAppTy g ty with + | ValueSome(tc, tinst) -> + yield! + tc.UnionCasesAsRefList + |> List.filter (IsUnionCaseUnseen ad g ncenv.amap m >> not) + |> List.map (fun ucref -> Item.UnionCase(UnionCaseInfo(tinst,ucref),false)) + | _ -> () | Item.Event _ -> yield! ncenv.InfoReader.GetEventInfosOfType(None,ad,m,ty) @@ -4117,6 +4220,13 @@ let ResolveCompletionsInTypeForItem (ncenv: NameResolver) nenv m ad statics ty ( if statics then yield! ty |> GetNestedTypesOfType (ad, ncenv, None, TypeNameResolutionStaticArgsInfo.Indefinite, false, m) |> List.map (ItemOfTy g) | _ -> + if not statics then + match tryDestAnonRecdTy g ty with + | ValueSome (anonInfo, tys) -> + for (i,id) in Array.indexed anonInfo.SortedIds do + yield Item.AnonRecdField(anonInfo, tys, i, id.idRange) + | _ -> () + let pinfosIncludingUnseen = AllPropInfosOfTypeInScope ncenv.InfoReader nenv (None,ad) PreferOverrides m ty |> List.filter (fun x -> @@ -4148,13 +4258,12 @@ let ResolveCompletionsInTypeForItem (ncenv: NameResolver) nenv m ad statics ty ( yield einfo.AddMethod.DisplayName yield einfo.RemoveMethod.DisplayName ] - let suppressedMethNames = Zset.ofList String.order (pinfoMethNames @ einfoMethNames) let pinfos = pinfosIncludingUnseen |> List.filter (fun x -> not (PropInfoIsUnseen m x)) - let minfoFilter (minfo: MethInfo) = + let minfoFilter (suppressedMethNames:Zset<_>) (minfo: MethInfo) = // Only show the Finalize, MemberwiseClose etc. methods on System.Object for values whose static type really is // System.Object. Few of these are typically used from F#. // @@ -4205,37 +4314,49 @@ let ResolveCompletionsInTypeForItem (ncenv: NameResolver) nenv m ad statics ty ( | Item.MethodGroup _ -> // REVIEW: add a name filter here in the common cases? let minfos = - let minfos = - AllMethInfosOfTypeInScope ncenv.InfoReader nenv (None,ad) PreferOverrides m ty - |> List.filter minfoFilter - + let minfos = AllMethInfosOfTypeInScope ncenv.InfoReader nenv (None,ad) PreferOverrides m ty + if isNil minfos then [] else + + let suppressedMethNames = Zset.ofList String.order (pinfoMethNames @ einfoMethNames) let minfos = - let addersAndRemovers = - pinfoItems - |> List.collect (function Item.Event(FSEvent(_,_,addValRef,removeValRef)) -> [addValRef.LogicalName;removeValRef.LogicalName] | _ -> []) - |> set + minfos + |> List.filter (minfoFilter suppressedMethNames) - if addersAndRemovers.IsEmpty then minfos - else minfos |> List.filter (fun minfo -> not (addersAndRemovers.Contains minfo.LogicalName)) + if isNil minfos then + [] + else + let minfos = + let addersAndRemovers = + let hashSet = HashSet() + for item in pinfoItems do + match item with + | Item.Event(FSEvent(_,_,addValRef,removeValRef)) -> + hashSet.Add addValRef.LogicalName |> ignore + hashSet.Add removeValRef.LogicalName |> ignore + | _ -> () + hashSet + + if addersAndRemovers.Count = 0 then minfos + else minfos |> List.filter (fun minfo -> not (addersAndRemovers.Contains minfo.LogicalName)) #if !NO_EXTENSIONTYPING - // Filter out the ones with mangled names from applying static parameters - let minfos = - let methsWithStaticParams = - minfos - |> List.filter (fun minfo -> - match minfo.ProvidedStaticParameterInfo with - | Some (_methBeforeArguments, staticParams) -> staticParams.Length <> 0 - | _ -> false) - |> List.map (fun minfo -> minfo.DisplayName) + // Filter out the ones with mangled names from applying static parameters + let minfos = + let methsWithStaticParams = + minfos + |> List.filter (fun minfo -> + match minfo.ProvidedStaticParameterInfo with + | Some (_methBeforeArguments, staticParams) -> staticParams.Length <> 0 + | _ -> false) + |> List.map (fun minfo -> minfo.DisplayName) - if methsWithStaticParams.IsEmpty then minfos - else minfos |> List.filter (fun minfo -> - let nm = minfo.LogicalName - not (nm.Contains "," && methsWithStaticParams |> List.exists (fun m -> nm.StartsWithOrdinal(m)))) + if methsWithStaticParams.IsEmpty then minfos + else minfos |> List.filter (fun minfo -> + let nm = minfo.LogicalName + not (nm.Contains "," && methsWithStaticParams |> List.exists (fun m -> nm.StartsWithOrdinal(m)))) #endif - minfos + minfos // Partition methods into overload sets let rec partitionl (l:MethInfo list) acc = @@ -4259,16 +4380,14 @@ let rec ResolvePartialLongIdentInTypeForItem (ncenv: NameResolver) nenv m ad sta | id :: rest -> let rfinfos = - ncenv.InfoReader.GetRecordOrClassFieldsOfType(None,ad,m,ty) - |> List.filter (fun fref -> IsRecdFieldAccessible ncenv.amap m ad fref.RecdFieldRef) - |> List.filter (fun fref -> fref.RecdField.IsStatic = statics) + ncenv.InfoReader.GetRecordOrClassFieldsOfType(None,ad,m,ty) + |> List.filter (fun fref -> fref.Name = id && IsRecdFieldAccessible ncenv.amap m ad fref.RecdFieldRef && fref.RecdField.IsStatic = statics) let nestedTypes = ty |> GetNestedTypesOfType (ad, ncenv, Some id, TypeNameResolutionStaticArgsInfo.Indefinite, false, m) // e.g. .. for rfinfo in rfinfos do - if rfinfo.Name = id then - yield! ResolvePartialLongIdentInTypeForItem ncenv nenv m ad false rest item rfinfo.FieldType + yield! ResolvePartialLongIdentInTypeForItem ncenv nenv m ad false rest item rfinfo.FieldType // e.g. .. let fullTypeOfPinfo (pinfo: PropInfo) = @@ -4279,12 +4398,17 @@ let rec ResolvePartialLongIdentInTypeForItem (ncenv: NameResolver) nenv m ad sta let pinfos = ty |> AllPropInfosOfTypeInScope ncenv.InfoReader nenv (Some id,ad) IgnoreOverrides m - |> List.filter (fun x -> x.IsStatic = statics) - |> List.filter (IsPropInfoAccessible g amap m ad) + |> List.filter (fun pinfo -> pinfo.IsStatic = statics && IsPropInfoAccessible g amap m ad pinfo) for pinfo in pinfos do yield! (fullTypeOfPinfo pinfo) |> ResolvePartialLongIdentInTypeForItem ncenv nenv m ad false rest item + match TryFindAnonRecdFieldOfType g ty id with + | Some (Item.AnonRecdField(_anonInfo, tys, i, _)) -> + let tyinfo = tys.[i] + yield! ResolvePartialLongIdentInTypeForItem ncenv nenv m ad false rest item tyinfo + | _ -> () + // e.g. .. for einfo in ncenv.InfoReader.GetEventInfosOfType(Some id, ad, m, ty) do let tyinfo = PropTypOfEventInfo ncenv.InfoReader m ad einfo @@ -4314,8 +4438,7 @@ let rec ResolvePartialLongIdentInModuleOrNamespaceForItem (ncenv: NameResolver) mty.AllValsAndMembers |> Seq.toList |> List.choose (TryMkValRefInModRef modref) // if the assembly load set is incomplete and we get a None value here, then ignore the value - |> List.filter (fun v -> not v.IsMember) - |> List.filter (IsValUnseen ad g m >> not) + |> List.filter (fun vref -> not vref.IsMember && not (IsValUnseen ad g m vref)) |> List.map Item.Value | Item.UnionCase _ -> // Collect up the accessible discriminated union cases in the module @@ -4339,38 +4462,45 @@ let rec ResolvePartialLongIdentInModuleOrNamespaceForItem (ncenv: NameResolver) |> List.filter (IsTyconUnseen ad g ncenv.amap m >> not) |> List.map Item.ExnCase | _ -> - let ilTyconNames = - mty.TypesByAccessNames.Values - |> List.choose (fun (tycon:Tycon) -> if tycon.IsILTycon then Some tycon.DisplayName else None) - |> Set.ofList - // Collect up the accessible sub-modules. We must yield them even though `item` is not a module or namespace, // otherwise we would not resolve long idents which have modules and namespaces in the middle (i.e. all long idents) - yield! + + let moduleOrNamespaces = mty.ModulesAndNamespacesByDemangledName - |> NameMap.range - |> List.filter (fun x -> - let demangledName = x.DemangledModuleOrNamespaceName - notFakeContainerModule ilTyconNames demangledName && IsInterestingModuleName demangledName) - |> List.map modref.NestedTyconRef - |> List.filter (IsTyconUnseen ad g ncenv.amap m >> not) - |> List.filter (EntityRefContainsSomethingAccessible ncenv m ad) - |> List.map ItemForModuleOrNamespaceRef + |> NameMap.range + + if not (isNil moduleOrNamespaces) then + let ilTyconNames = getFakeContainerModulesFromTycons mty.TypesByAccessNames.Values + + yield! + moduleOrNamespaces + |> List.filter (fun x -> + let demangledName = x.DemangledModuleOrNamespaceName + notFakeContainerModule ilTyconNames demangledName && IsInterestingModuleName demangledName) + |> List.map modref.NestedTyconRef + |> List.filter (fun tcref -> + not (IsTyconUnseen ad g ncenv.amap m tcref) && + EntityRefContainsSomethingAccessible ncenv m ad tcref) + |> List.map ItemForModuleOrNamespaceRef + let tycons = mty.TypeDefinitions - |> List.filter (fun tcref -> not (tcref.LogicalName.Contains(","))) - |> List.filter (fun tycon -> not (IsTyconUnseen ad g ncenv.amap m (modref.NestedTyconRef tycon))) - - // Get all the types and .NET constructor groups accessible from here - yield! tycons |> List.map (modref.NestedTyconRef >> ItemOfTyconRef ncenv m) - yield! tycons |> List.collect (modref.NestedTyconRef >> InfosForTyconConstructors ncenv m ad) + |> List.filter (fun tcref -> + not (tcref.LogicalName.Contains(",")) && + not (IsTyconUnseen ad g ncenv.amap m (modref.NestedTyconRef tcref))) + + // Get all the types and .NET constructor groups accessible from here + let nestedTycons = tycons |> List.map modref.NestedTyconRef + yield! nestedTycons |> List.map (ItemOfTyconRef ncenv m) + yield! nestedTycons |> List.collect (InfosForTyconConstructors ncenv m ad) | id :: rest -> - match mty.ModulesAndNamespacesByDemangledName.TryFind(id) with - | Some mspec - when not (IsTyconUnseenObsoleteSpec ad g ncenv.amap m (modref.NestedTyconRef mspec) true) -> - yield! ResolvePartialLongIdentInModuleOrNamespaceForItem ncenv nenv m ad (modref.NestedTyconRef mspec) rest item + match mty.ModulesAndNamespacesByDemangledName.TryGetValue id with + | true, mspec -> + let nested = modref.NestedTyconRef mspec + if not (IsTyconUnseenObsoleteSpec ad g ncenv.amap m nested true) then + yield! ResolvePartialLongIdentInModuleOrNamespaceForItem ncenv nenv m ad nested rest item | _ -> () for tycon in LookupTypeNameInEntityNoArity m id modref.ModuleOrNamespaceType do @@ -4384,20 +4514,20 @@ let rec PartialResolveLookupInModuleOrNamespaceAsModuleOrNamespaceThenLazy f pli match plid with | [] -> f modref | id :: rest -> - match mty.ModulesAndNamespacesByDemangledName.TryFind id with - | Some mty -> + match mty.ModulesAndNamespacesByDemangledName.TryGetValue id with + | true, mty -> PartialResolveLookupInModuleOrNamespaceAsModuleOrNamespaceThenLazy f rest (modref.NestedTyconRef mty) - | None -> Seq.empty + | _ -> Seq.empty let PartialResolveLongIndentAsModuleOrNamespaceThenLazy (nenv:NameResolutionEnv) plid f = seq { match plid with | id :: rest -> - match Map.tryFind id nenv.eModulesAndNamespaces with - | Some modrefs -> + match nenv.eModulesAndNamespaces.TryGetValue id with + | true, modrefs -> for modref in modrefs do yield! PartialResolveLookupInModuleOrNamespaceAsModuleOrNamespaceThenLazy f rest modref - | None -> () + | _ -> () | [] -> () } @@ -4422,17 +4552,19 @@ let rec GetCompletionForItem (ncenv: NameResolver) (nenv: NameResolutionEnv) m a match item with | Item.ModuleOrNamespaces _ -> - let ilTyconNames = - nenv.TyconsByAccessNames(OpenQualified).Values - |> List.choose (fun tyconRef -> if tyconRef.IsILTycon then Some tyconRef.DisplayName else None) - |> Set.ofList + let moduleOrNamespaceRefs = + nenv.ModulesAndNamespaces OpenQualified + |> NameMultiMap.range - for ns in NameMultiMap.range (nenv.ModulesAndNamespaces(OpenQualified)) do - let demangledName = ns.DemangledModuleOrNamespaceName - if IsInterestingModuleName demangledName && notFakeContainerModule ilTyconNames demangledName - && EntityRefContainsSomethingAccessible ncenv m ad ns - && not (IsTyconUnseen ad g ncenv.amap m ns) - then yield ItemForModuleOrNamespaceRef ns + if not (isNil moduleOrNamespaceRefs) then + let ilTyconNames = getFakeContainerModulesFromTyconRefs (nenv.TyconsByAccessNames(OpenQualified).Values) + + for ns in moduleOrNamespaceRefs do + let demangledName = ns.DemangledModuleOrNamespaceName + if IsInterestingModuleName demangledName && notFakeContainerModule ilTyconNames demangledName + && EntityRefContainsSomethingAccessible ncenv m ad ns + && not (IsTyconUnseen ad g ncenv.amap m ns) + then yield ItemForModuleOrNamespaceRef ns | Item.Types _ -> for tcref in nenv.TyconsByDemangledNameAndArity(OpenQualified).Values do @@ -4468,8 +4600,8 @@ let rec GetCompletionForItem (ncenv: NameResolver) (nenv: NameResolutionEnv) m a else Seq.empty) // Look for values called 'id' that accept the dot-notation - match Map.tryFind id nenv.eUnqualifiedItems with - | Some (Item.Value x) -> + match nenv.eUnqualifiedItems.TryGetValue id with + | true, Item.Value x -> let ty = x.Type let ty = if x.BaseOrThisInfo = CtorThisVal && isRefCellTy g ty then destRefCellTy g ty else ty yield! ResolvePartialLongIdentInTypeForItem ncenv nenv m ad false rest item ty @@ -4482,20 +4614,25 @@ let rec GetCompletionForItem (ncenv: NameResolver) (nenv: NameResolutionEnv) m a } let IsItemResolvable (ncenv: NameResolver) (nenv: NameResolutionEnv) m ad plid (item: Item) : bool = - protectAssemblyExploration false <| fun () -> - GetCompletionForItem ncenv nenv m ad plid item |> Seq.exists (ItemsAreEffectivelyEqual ncenv.g item) + protectAssemblyExploration false (fun () -> + GetCompletionForItem ncenv nenv m ad plid item + |> Seq.exists (ItemsAreEffectivelyEqual ncenv.g item) + ) let GetVisibleNamespacesAndModulesAtPoint (ncenv: NameResolver) (nenv: NameResolutionEnv) m ad = - protectAssemblyExploration [] <| fun () -> - let ilTyconNames = - nenv.TyconsByAccessNames(FullyQualifiedFlag.OpenQualified).Values - |> List.choose (fun tyconRef -> if tyconRef.IsILTycon then Some tyconRef.DisplayName else None) - |> Set.ofList - - nenv.ModulesAndNamespaces(FullyQualifiedFlag.OpenQualified) - |> NameMultiMap.range - |> List.filter (fun x -> - let demangledName = x.DemangledModuleOrNamespaceName - IsInterestingModuleName demangledName && notFakeContainerModule ilTyconNames demangledName - && EntityRefContainsSomethingAccessible ncenv m ad x - && not (IsTyconUnseen ad ncenv.g ncenv.amap m x)) + protectAssemblyExploration [] (fun () -> + let items = + nenv.ModulesAndNamespaces FullyQualifiedFlag.OpenQualified + |> NameMultiMap.range + + if isNil items then [] else + + let ilTyconNames = getFakeContainerModulesFromTyconRefs (nenv.TyconsByAccessNames(FullyQualifiedFlag.OpenQualified).Values) + + items + |> List.filter (fun x -> + let demangledName = x.DemangledModuleOrNamespaceName + IsInterestingModuleName demangledName && notFakeContainerModule ilTyconNames demangledName + && EntityRefContainsSomethingAccessible ncenv m ad x + && not (IsTyconUnseen ad ncenv.g ncenv.amap m x)) + ) diff --git a/src/fsharp/NameResolution.fsi b/src/fsharp/NameResolution.fsi index 8a1ae97f00..a302e22ef1 100755 --- a/src/fsharp/NameResolution.fsi +++ b/src/fsharp/NameResolution.fsi @@ -64,6 +64,9 @@ type Item = /// Represents the resolution of a name to an F# record field. | RecdField of RecdFieldInfo + /// Represents the resolution of a name to a field of an anonymous record type. + | AnonRecdField of AnonRecdTypeInfo * TTypes * int * range + // The following are never in the items table but are valid results of binding // an identifier in different circumstances. @@ -166,8 +169,8 @@ type FullyQualifiedFlag = [] type BulkAdd = Yes | No -/// Lookup patterns in name resolution environment -val internal TryFindPatternByName : string -> NameResolutionEnv -> Item option +/// Find a field in anonymous record type +val internal TryFindAnonRecdFieldOfType : TcGlobals -> TType -> string -> Item option /// Add extra items to the environment for Visual Studio, e.g. static members val internal AddFakeNamedValRefToNameEnv : string -> NameResolutionEnv -> ValRef -> NameResolutionEnv @@ -237,7 +240,7 @@ type TypeNameResolutionInfo = static member ResolveToTypeRefs : TypeNameResolutionStaticArgsInfo -> TypeNameResolutionInfo /// Represents the kind of the occurrence when reporting a name in name resolution -[] +[] type internal ItemOccurence = | Binding | Use @@ -316,7 +319,7 @@ type internal TcSymbolUses = member GetUsesOfSymbol : Item -> TcSymbolUseData[] /// All the uses of all items within the file - member AllUsesOfSymbols : TcSymbolUseData[] + member AllUsesOfSymbols : TcSymbolUseData[][] /// Get the locations of all the printf format specifiers in the file member GetFormatSpecifierLocationsAndArity : unit -> (range * int)[] @@ -341,12 +344,12 @@ type internal OpenDeclaration = /// Create a new instance of OpenDeclaration. static member Create : longId: Ident list * modules: ModuleOrNamespaceRef list * appliedScope: range * isOwnNamespace: bool -> OpenDeclaration -/// Line-end normalized source text and an array of line end positions, used for format string parsing +/// Source text and an array of line end positions, used for format string parsing type FormatStringCheckContext = - { /// Line-end normalized source text - NormalizedSource: string - /// Array of line end positions - LineEndPositions: int[] } + { /// Source text + Source: string + /// Array of line start positions + LineStartPositions: int[] } /// An abstract type for reporting the results of name resolution and type checking type ITypecheckResultsSink = diff --git a/src/fsharp/NicePrint.fs b/src/fsharp/NicePrint.fs index ca5fd8c674..142ccbae07 100755 --- a/src/fsharp/NicePrint.fs +++ b/src/fsharp/NicePrint.fs @@ -33,6 +33,7 @@ module internal PrintUtilities = let squareAngleL x = LeftL.leftBracketAngle ^^ x ^^ RightL.rightBracketAngle let angleL x = sepL Literals.leftAngle ^^ x ^^ rightL Literals.rightAngle let braceL x = leftL Literals.leftBrace ^^ x ^^ rightL Literals.rightBrace + let braceBarL x = leftL Literals.leftBraceBar ^^ x ^^ rightL Literals.rightBraceBar let comment str = wordL (tagText (sprintf "(* %s *)" str)) @@ -102,7 +103,7 @@ module private PrintIL = open Microsoft.FSharp.Compiler.AbstractIL.IL let fullySplitILTypeRef (tref:ILTypeRef) = - (List.collect IL.splitNamespace (tref.Enclosing @ [IL.ungenericizeTypeName tref.Name])) + (List.collect IL.splitNamespace (tref.Enclosing @ [PrettyNaming.DemangleGenericTypeName tref.Name])) let layoutILTypeRefName denv path = let path = @@ -193,7 +194,7 @@ module private PrintIL = let args = signatur.ArgTypes |> List.map (layoutILType denv ilTyparSubst) let res = match cons with - | Some className -> layoutILTypeRefName denv (SplitNamesForILPath (ungenericizeTypeName className)) ^^ (pruneParms className ilTyparSubst |> paramsL) // special case for constructor return-type (viz., the class itself) + | Some className -> layoutILTypeRefName denv (SplitNamesForILPath (PrettyNaming.DemangleGenericTypeName className)) ^^ (pruneParms className ilTyparSubst |> paramsL) // special case for constructor return-type (viz., the class itself) | None -> signatur.ReturnType |> layoutILType denv ilTyparSubst match args with | [] -> WordL.structUnit ^^ WordL.arrow ^^ res @@ -226,7 +227,7 @@ module private PrintIL = // return type be passed along as the `cons` parameter.) let res = match cons with - | Some className -> layoutILTypeRefName denv (SplitNamesForILPath (ungenericizeTypeName className)) ^^ (pruneParms className ilTyparSubst |> paramsL) // special case for constructor return-type (viz., the class itself) + | Some className -> layoutILTypeRefName denv (SplitNamesForILPath (PrettyNaming.DemangleGenericTypeName className)) ^^ (pruneParms className ilTyparSubst |> paramsL) // special case for constructor return-type (viz., the class itself) | None -> retType |> layoutILType denv ilTyparSubst match parameters with | [] -> WordL.structUnit ^^ WordL.arrow ^^ res @@ -934,6 +935,14 @@ module private PrintTypes = | TType_ucase (UCRef(tc,_),args) -> layoutTypeAppWithInfoAndPrec denv env (layoutTyconRef denv tc) prec tc.IsPrefixDisplay args + // Layout a tuple type + | TType_anon (anonInfo,tys) -> + let core = sepListL (wordL (tagPunctuation ";")) (List.map2 (fun nm ty -> wordL (tagField nm) ^^ wordL (tagPunctuation ":") ^^ layoutTypeWithInfoAndPrec denv env prec ty) (Array.toList anonInfo.SortedNames) tys) + if evalAnonInfoIsStruct anonInfo then + WordL.keywordStruct --- braceBarL core + else + braceBarL core + // Layout a tuple type | TType_tuple (tupInfo,t) -> if evalTupInfoIsStruct tupInfo then @@ -991,7 +1000,7 @@ module private PrintTypes = let isParamArray = HasFSharpAttribute denv.g denv.g.attrib_ParamArrayAttribute argInfo.Attribs match argInfo.Name, isOptionalArg, isParamArray, tryDestOptionTy denv.g ty with // Layout an optional argument - | Some(id), true, _, Some ty -> + | Some(id), true, _, ValueSome ty -> leftL (tagPunctuation "?") ^^ sepL (tagParameter id.idText) ^^ SepL.colon ^^ layoutTypeWithInfoAndPrec denv env 2 ty // Layout an unnamed argument | None, _,_, _ -> @@ -1056,7 +1065,7 @@ module private PrintTypes = let prettyLayoutOfCurriedMemberSig denv typarInst argInfos retTy parentTyparTys = let (prettyTyparInst, parentTyparTys,argInfos,retTy),cxs = PrettyTypes.PrettifyInstAndCurriedSig denv.g (typarInst, parentTyparTys, argInfos, retTy) // Filter out the parent typars, which don't get shown in the member signature - let cxs = cxs |> List.filter (fun (tp,_) -> not (parentTyparTys |> List.exists (fun ty -> match tryDestTyparTy denv.g ty with Some destTypar -> typarEq tp destTypar | None -> false))) + let cxs = cxs |> List.filter (fun (tp,_) -> not (parentTyparTys |> List.exists (fun ty -> match tryDestTyparTy denv.g ty with ValueSome destTypar -> typarEq tp destTypar | _ -> false))) prettyTyparInst, prettyLayoutOfTopTypeInfoAux denv argInfos retTy cxs // Layout: type spec - class, datatype, record, abbrev @@ -1247,7 +1256,7 @@ module InfoMemberPrinting = // Layout an optional argument | _, Some nm, true, ptyOpt -> // detect parameter type, if ptyOpt is None - this is .NET style optional argument - let pty = defaultArg ptyOpt pty + let pty = match ptyOpt with ValueSome x -> x | _ -> pty SepL.questionMark ^^ wordL (tagParameter nm.idText) ^^ RightL.colon ^^ @@ -1513,7 +1522,7 @@ module private TastDefinitionPrinting = /// Another re-implementation of type printing, this time based off provided info objects. let layoutProvidedTycon (denv:DisplayEnv) (infoReader:InfoReader) ad m start lhsL ty = let g = denv.g - let tcref,_ = destAppTy g ty + let tcref = tcrefOfAppTy g ty if isEnumTy g ty then let fieldLs = diff --git a/src/fsharp/Optimizer.fs b/src/fsharp/Optimizer.fs index da19114bcc..5e34582267 100755 --- a/src/fsharp/Optimizer.fs +++ b/src/fsharp/Optimizer.fs @@ -157,17 +157,20 @@ let braceL x = leftL (tagText "{") ^^ x ^^ rightL (tagText "}") let seqL xL xs = Seq.fold (fun z x -> z @@ xL x) emptyL xs let namemapL xL xmap = NameMap.foldBack (fun nm x z -> xL nm x @@ z) xmap emptyL -let rec exprValueInfoL g = function - | ConstValue (x, ty) -> NicePrint.layoutConst g ty x - | UnknownValue -> wordL (tagText "?") - | SizeValue (_, vinfo) -> exprValueInfoL g vinfo - | ValValue (vr, vinfo) -> bracketL ((valRefL vr ^^ wordL (tagText "alias")) --- exprValueInfoL g vinfo) - | TupleValue vinfos -> bracketL (exprValueInfosL g vinfos) - | RecdValue (_, vinfos) -> braceL (exprValueInfosL g vinfos) - | UnionCaseValue (ucr, vinfos) -> unionCaseRefL ucr ^^ bracketL (exprValueInfosL g vinfos) - | CurriedLambdaValue(_lambdaId, _arities, _bsize, expr', _ety) -> wordL (tagText "lam") ++ exprL expr' (* (sprintf "lam(size=%d)" bsize) *) - | ConstExprValue (_size, x) -> exprL x +let rec exprValueInfoL g exprVal = + match exprVal with + | ConstValue (x, ty) -> NicePrint.layoutConst g ty x + | UnknownValue -> wordL (tagText "?") + | SizeValue (_, vinfo) -> exprValueInfoL g vinfo + | ValValue (vr, vinfo) -> bracketL ((valRefL vr ^^ wordL (tagText "alias")) --- exprValueInfoL g vinfo) + | TupleValue vinfos -> bracketL (exprValueInfosL g vinfos) + | RecdValue (_, vinfos) -> braceL (exprValueInfosL g vinfos) + | UnionCaseValue (ucr, vinfos) -> unionCaseRefL ucr ^^ bracketL (exprValueInfosL g vinfos) + | CurriedLambdaValue(_lambdaId, _arities, _bsize, expr', _ety) -> wordL (tagText "lam") ++ exprL expr' (* (sprintf "lam(size=%d)" bsize) *) + | ConstExprValue (_size, x) -> exprL x + and exprValueInfosL g vinfos = commaListL (List.map (exprValueInfoL g) (Array.toList vinfos)) + and moduleInfoL g (x:LazyModuleInfo) = let x = x.Force() braceL ((wordL (tagText "Modules: ") @@ (x.ModuleOrNamespaceInfos |> namemapL (fun nm x -> wordL (tagText nm) ^^ moduleInfoL g x) ) ) @@ -455,8 +458,8 @@ let BindExternalLocalVal cenv (v:Val) vval env = // Passing an empty remap is sufficient for FSharp.Core.dll because it turns out the remapped type signature can // still be resolved. match tryRescopeVal cenv.g.fslibCcu Remap.Empty v with - | Some vref -> BindValueForFslib vref.nlr v vval env - | None -> env + | ValueSome vref -> BindValueForFslib vref.nlr v vval env + | _ -> env else env env @@ -973,11 +976,11 @@ let AbstractLazyModulInfoByHiding isAssemblyBoundary mhi = // Under those checks, the further hidden* checks may be subsumed (meaning, not required anymore). let hiddenTycon, hiddenTyconRepr, hiddenVal, hiddenRecdField, hiddenUnionCase = - Zset.memberOf mhi.mhiTycons, - Zset.memberOf mhi.mhiTyconReprs, - Zset.memberOf mhi.mhiVals, - Zset.memberOf mhi.mhiRecdFields, - Zset.memberOf mhi.mhiUnionCases + Zset.memberOf mhi.HiddenTycons, + Zset.memberOf mhi.HiddenTyconReprs, + Zset.memberOf mhi.HiddenVals, + Zset.memberOf mhi.HiddenRecdFields, + Zset.memberOf mhi.HiddenUnionCases let rec abstractExprInfo ivalue = match ivalue with @@ -1186,9 +1189,9 @@ let IsTyFuncValRefExpr = function | _ -> false /// Type applications of existing functions are always simple constants, with the exception of F# 'type functions' -/// REVIEW: we could also include any under-applied application here. let rec IsSmallConstExpr x = match x with + | Expr.Op (TOp.LValueOp (LAddrOf _, _), [], [], _) -> true // &x is always a constant | Expr.Val (v, _, _m) -> not v.IsMutable | Expr.App(fe, _, _tyargs, args, _) -> isNil args && not (IsTyFuncValRefExpr fe) && IsSmallConstExpr fe | _ -> false @@ -1202,11 +1205,29 @@ let ValueOfExpr expr = // Dead binding elimination //------------------------------------------------------------------------- +// Allow discard of "let v = *byref" if "v" is unused anywhere. The read effect +// can be discarded because it is always assumed that reading byref pointers (without using +// the value of the read) doesn't raise exceptions or cause other "interesting" side effects. +// +// This allows discarding the implicit deref when matching on struct unions, e.g. +// +// [] +// type SingleRec = +// | SingleUnion of int +// member x.Next = let (SingleUnion i) = x in SingleUnion (i+1) +// +// See https://github.com/Microsoft/visualfsharp/issues/5136 +let IsDiscardableEffectExpr expr = + match expr with + | Expr.Op (TOp.LValueOp (LByrefGet _, _), [], [], _) -> true + | _ -> false + +/// Checks is a value binding is non-discardable let ValueIsUsedOrHasEffect cenv fvs (b:Binding, binfo) = let v = b.Var not (cenv.settings.EliminateUnusedBindings()) || Option.isSome v.MemberInfo || - binfo.HasEffect || + (binfo.HasEffect && not (IsDiscardableEffectExpr b.Expr)) || v.IsFixed || Zset.contains v (fvs()) @@ -1259,6 +1280,7 @@ and BindingHasEffect g bind = bind.Expr |> ExprHasEffect g and OpHasEffect g m op = match op with | TOp.Tuple _ -> false + | TOp.AnonRecd _ -> false | TOp.Recd (ctor, tcref) -> match ctor with | RecdExprIsObjInit -> true @@ -1273,10 +1295,11 @@ and OpHasEffect g m op = | TOp.TupleFieldGet(_) -> false | TOp.ExnFieldGet(ecref, n) -> isExnFieldMutable ecref n | TOp.RefAddrGet _ -> false - | TOp.ValFieldGet rfref -> rfref.RecdField.IsMutable || (TryFindTyconRefBoolAttribute g Range.range0 g.attrib_AllowNullLiteralAttribute rfref.TyconRef = Some true) + | TOp.AnonRecdGet _ -> true // conservative + | TOp.ValFieldGet rfref -> rfref.RecdField.IsMutable || (TryFindTyconRefBoolAttribute g Range.range0 g.attrib_AllowNullLiteralAttribute rfref.TyconRef = Some(true)) | TOp.ValFieldGetAddr (rfref, _readonly) -> rfref.RecdField.IsMutable | TOp.UnionCaseFieldGetAddr _ -> false // union case fields are immutable - | TOp.LValueOp (LAddrOf _, lv) -> lv.IsMutable + | TOp.LValueOp (LAddrOf _, _) -> false // addresses of values are always constants | TOp.UnionCaseFieldSet _ | TOp.ExnFieldSet _ | TOp.Coerce @@ -1382,6 +1405,84 @@ let rec (|KnownValApp|_|) expr = | Expr.App(KnownValApp(vref, typeArgs1, otherArgs1), _, typeArgs2, otherArgs2, _) -> Some(vref, typeArgs1@typeArgs2, otherArgs1@otherArgs2) | _ -> None +/// Matches boolean decision tree: +/// check single case with bool const. +let (|TDBoolSwitch|_|) dtree = + match dtree with + | TDSwitch( expr, [TCase (DecisionTreeTest.Const(Const.Bool testBool), caseTree )], Some defaultTree, range) -> + Some (expr, testBool, caseTree, defaultTree, range) + | _ -> + None + +/// Check target that have a constant bool value +let (|ConstantBoolTarget|_|) target = + match target with + | TTarget([], Expr.Const (Const.Bool b,_,_),_) -> Some b + | _ -> None + +/// Is this a tree, where each decision is a two-way switch (to prevent later duplication of trees), and each branch returns or true/false, +/// apart from one branch which defers to another expression +let rec CountBoolLogicTree ((targets: DecisionTreeTarget[], costOuterCaseTree, costOuterDefaultTree, testBool) as data) tree = + match tree with + | TDSwitch (_expr, [case], Some defaultTree, _range) -> + let tc1,ec1 = CountBoolLogicTree data case.CaseTree + let tc2, ec2 = CountBoolLogicTree data defaultTree + tc1 + tc2, ec1 + ec2 + | TDSuccess([], idx) -> + match targets.[idx] with + | ConstantBoolTarget result -> (if result = testBool then costOuterCaseTree else costOuterDefaultTree), 0 + | TTarget([], _exp, _) -> costOuterCaseTree + costOuterDefaultTree, 10 + | _ -> 100, 100 + | _ -> 100, 100 + +/// Rewrite a decision tree for which CountBoolLogicTree returned a low number (see below). Produce a new decision +/// tree where at each ConstantBoolSuccessTree tip we replace with either outerCaseTree or outerDefaultTree +/// depending on whether the target result was true/false +let rec RewriteBoolLogicTree ((targets: DecisionTreeTarget[], outerCaseTree, outerDefaultTree, testBool) as data) tree = + match tree with + | TDSwitch (expr, cases, defaultTree, range) -> + let cases2 = cases |> List.map (RewriteBoolLogicCase data) + let defaultTree2 = defaultTree |> Option.map (RewriteBoolLogicTree data) + TDSwitch (expr, cases2, defaultTree2, range) + | TDSuccess([], idx) -> + match targets.[idx] with + | ConstantBoolTarget result -> if result = testBool then outerCaseTree else outerDefaultTree + | TTarget([], exp, _) -> mkBoolSwitch exp.Range exp (if testBool then outerCaseTree else outerDefaultTree) (if testBool then outerDefaultTree else outerCaseTree) + | _ -> failwith "CountBoolLogicTree should exclude this case" + | _ -> failwith "CountBoolLogicTree should exclude this case" + +and RewriteBoolLogicCase data (TCase(test, tree)) = + TCase(test, RewriteBoolLogicTree data tree) + +/// Repeatedly combine switch-over-match decision trees, see https://github.com/Microsoft/visualfsharp/issues/635. +/// The outer decision tree is doing a swithc over a boolean result, the inner match is producing only +/// constant boolean results in its targets. +let rec CombineBoolLogic expr = + + // try to find nested boolean switch + match expr with + | Expr.Match(outerSP, outerMatchRange, + TDBoolSwitch(Expr.Match(_innerSP, _innerMatchRange, innerTree, innerTargets, _innerDefaultRange, _innerMatchTy), + outerTestBool, outerCaseTree, outerDefaultTree, _outerSwitchRange ), + outerTargets, outerDefaultRange, outerMatchTy) -> + + let costOuterCaseTree = match outerCaseTree with TDSuccess _ -> 0 | _ -> 1 + let costOuterDefaultTree = match outerDefaultTree with TDSuccess _ -> 0 | _ -> 1 + let tc, ec = CountBoolLogicTree (innerTargets, costOuterCaseTree, costOuterDefaultTree, outerTestBool) innerTree + // At most one expression, no overall duplication of TSwitch nodes + if tc <= costOuterCaseTree + costOuterDefaultTree && ec <= 10 then + let newExpr = + Expr.Match(outerSP, outerMatchRange, + RewriteBoolLogicTree (innerTargets, outerCaseTree, outerDefaultTree, outerTestBool) innerTree, + outerTargets, outerDefaultRange, outerMatchTy) + + CombineBoolLogic newExpr + else + expr + | _ -> + expr + + //------------------------------------------------------------------------- // ExpandStructuralBinding // @@ -1663,7 +1764,15 @@ let TryDetectQueryQuoteAndRun cenv (expr:Expr) = //printfn "Not eliminating because no Run found" None - +let IsSystemStringConcatOverload (methRef: ILMethodRef) = + methRef.Name = "Concat" && methRef.DeclaringTypeRef.FullName = "System.String" && + methRef.ReturnType.BasicQualifiedName = "System.String" && + methRef.ArgTypes |> List.forall(fun ilty -> ilty.BasicQualifiedName = "System.String") + +let IsSystemStringConcatArray (methRef: ILMethodRef) = + methRef.Name = "Concat" && methRef.DeclaringTypeRef.FullName = "System.String" && + methRef.ReturnType.BasicQualifiedName = "System.String" && + methRef.ArgTypes.Length = 1 && methRef.ArgTypes.Head.BasicQualifiedName = "System.String[]" //------------------------------------------------------------------------- // The traversal @@ -1723,7 +1832,6 @@ let rec OptimizeExpr cenv (env:IncrementalOptimizationEnv) expr = assert ("unexpected reclink" = "") failwith "Unexpected reclink" - //------------------------------------------------------------------------- // Optimize/analyze an object expression //------------------------------------------------------------------------- @@ -1773,12 +1881,57 @@ and OptimizeInterfaceImpl cenv env baseValOpt (ty, overrides) = Info=UnknownValue} //------------------------------------------------------------------------- -// Optimize/analyze an application of an intrinsic operator to arguments +// Make and optimize String.Concat calls //------------------------------------------------------------------------- +and MakeOptimizedSystemStringConcatCall cenv env m args = + let rec optimizeArg e accArgs = + match e, accArgs with + | Expr.Op(TOp.ILCall(_, _, _, _, _, _, _, methRef, _, _, _), _, [ Expr.Op(TOp.Array, _, args, _) ], _), _ when IsSystemStringConcatArray methRef -> + optimizeArgs args accArgs + + | Expr.Op(TOp.ILCall(_, _, _, _, _, _, _, methRef, _, _, _), _, args, _), _ when IsSystemStringConcatOverload methRef -> + optimizeArgs args accArgs + + // Optimize string constants, e.g. "1" + "2" will turn into "12" + | Expr.Const(Const.String str1, _, _), Expr.Const(Const.String str2, _, _) :: accArgs -> + mkString cenv.g m (str1 + str2) :: accArgs + + | arg, _ -> arg :: accArgs + + and optimizeArgs args accArgs = + (args, accArgs) + ||> List.foldBack (fun arg accArgs -> optimizeArg arg accArgs) + + let args = optimizeArgs args [] + + let e = + match args with + | [ arg ] -> + arg + | [ arg1; arg2 ] -> + mkStaticCall_String_Concat2 cenv.g m arg1 arg2 + | [ arg1; arg2; arg3 ] -> + mkStaticCall_String_Concat3 cenv.g m arg1 arg2 arg3 + | [ arg1; arg2; arg3; arg4 ] -> + mkStaticCall_String_Concat4 cenv.g m arg1 arg2 arg3 arg4 + | args -> + let arg = mkArray (cenv.g.string_ty, args, m) + mkStaticCall_String_Concat_Array cenv.g m arg + + match e with + | Expr.Op(TOp.ILCall(_, _, _, _, _, _, _, methRef, _, _, _) as op, tyargs, args, m) when IsSystemStringConcatOverload methRef || IsSystemStringConcatArray methRef -> + OptimizeExprOpReductions cenv env (op, tyargs, args, m) + | _ -> + OptimizeExpr cenv env e + +//------------------------------------------------------------------------- +// Optimize/analyze an application of an intrinsic operator to arguments +//------------------------------------------------------------------------- + and OptimizeExprOp cenv env (op, tyargs, args, m) = - (* Special cases *) + // Special cases match op, tyargs, args with | TOp.Coerce, [toty;fromty], [e] -> let e', einfo = OptimizeExpr cenv env e @@ -1790,26 +1943,38 @@ and OptimizeExprOp cenv env (op, tyargs, args, m) = HasEffect = true MightMakeCriticalTailcall=false Info=UnknownValue } - (* Handle addresses *) + + // Handle address-of | TOp.LValueOp ((LAddrOf _ as lop), lv), _, _ -> - let e, _ = OptimizeExpr cenv env (exprForValRef m lv) - let op' = - match e with + let newVal, _ = OptimizeExpr cenv env (exprForValRef m lv) + let newOp = + match newVal with // Do not optimize if it's a top level static binding. | Expr.Val (v, _, _) when not v.IsCompiledAsTopLevel -> TOp.LValueOp (lop, v) | _ -> op - Expr.Op (op', tyargs, args, m), + let newExpr = Expr.Op (newOp, tyargs, args, m) + newExpr, { TotalSize = 1 FunctionSize = 1 - HasEffect = OpHasEffect cenv.g m op' + HasEffect = OpHasEffect cenv.g m newOp MightMakeCriticalTailcall = false - Info = UnknownValue } - (* Handle these as special cases since mutables are allowed inside their bodies *) - | TOp.While (spWhile, marker), _, [Expr.Lambda(_, _, _, [_], e1, _, _);Expr.Lambda(_, _, _, [_], e2, _, _)] -> OptimizeWhileLoop cenv { env with inLoop=true } (spWhile, marker, e1, e2, m) - | TOp.For(spStart, dir), _, [Expr.Lambda(_, _, _, [_], e1, _, _);Expr.Lambda(_, _, _, [_], e2, _, _);Expr.Lambda(_, _, _, [v], e3, _, _)] -> OptimizeFastIntegerForLoop cenv { env with inLoop=true } (spStart, v, e1, dir, e2, e3, m) - | TOp.TryFinally(spTry, spFinally), [resty], [Expr.Lambda(_, _, _, [_], e1, _, _); Expr.Lambda(_, _, _, [_], e2, _, _)] -> OptimizeTryFinally cenv env (spTry, spFinally, e1, e2, m, resty) - | TOp.TryCatch(spTry, spWith), [resty], [Expr.Lambda(_, _, _, [_], e1, _, _); Expr.Lambda(_, _, _, [vf], ef, _, _); Expr.Lambda(_, _, _, [vh], eh, _, _)] -> OptimizeTryCatch cenv env (e1, vf, ef, vh, eh, m, resty, spTry, spWith) - | TOp.TraitCall(traitInfo), [], args -> OptimizeTraitCall cenv env (traitInfo, args, m) + Info = ValueOfExpr newExpr } + + // Handle these as special cases since mutables are allowed inside their bodies + | TOp.While (spWhile, marker), _, [Expr.Lambda(_, _, _, [_], e1, _, _);Expr.Lambda(_, _, _, [_], e2, _, _)] -> + OptimizeWhileLoop cenv { env with inLoop=true } (spWhile, marker, e1, e2, m) + + | TOp.For(spStart, dir), _, [Expr.Lambda(_, _, _, [_], e1, _, _);Expr.Lambda(_, _, _, [_], e2, _, _);Expr.Lambda(_, _, _, [v], e3, _, _)] -> + OptimizeFastIntegerForLoop cenv { env with inLoop=true } (spStart, v, e1, dir, e2, e3, m) + + | TOp.TryFinally(spTry, spFinally), [resty], [Expr.Lambda(_, _, _, [_], e1, _, _); Expr.Lambda(_, _, _, [_], e2, _, _)] -> + OptimizeTryFinally cenv env (spTry, spFinally, e1, e2, m, resty) + + | TOp.TryCatch(spTry, spWith), [resty], [Expr.Lambda(_, _, _, [_], e1, _, _); Expr.Lambda(_, _, _, [vf], ef, _, _); Expr.Lambda(_, _, _, [vh], eh, _, _)] -> + OptimizeTryCatch cenv env (e1, vf, ef, vh, eh, m, resty, spTry, spWith) + + | TOp.TraitCall(traitInfo), [], args -> + OptimizeTraitCall cenv env (traitInfo, args, m) // This code hooks arr.Length. The idea is to ensure loops end up in the "same shape"as the forms of loops that the .NET JIT // guarantees to optimize. @@ -1827,8 +1992,17 @@ and OptimizeExprOp cenv env (op, tyargs, args, m) = // if the types match up. | TOp.ILAsm([], [ty]), _, [a] when typeEquiv cenv.g (tyOfExpr cenv.g a) ty -> OptimizeExpr cenv env a + // Optimize calls when concatenating strings, e.g. "1" + "2" + "3" + "4" .. etc. + | TOp.ILCall(_, _, _, _, _, _, _, methRef, _, _, _), _, [ Expr.Op(TOp.Array, _, args, _) ] when IsSystemStringConcatArray methRef -> + MakeOptimizedSystemStringConcatCall cenv env m args + | TOp.ILCall(_, _, _, _, _, _, _, methRef, _, _, _), _, args when IsSystemStringConcatOverload methRef -> + MakeOptimizedSystemStringConcatCall cenv env m args + | _ -> - (* Reductions *) + // Reductions + OptimizeExprOpReductions cenv env (op, tyargs, args, m) + +and OptimizeExprOpReductions cenv env (op, tyargs, args, m) = let args', arginfos = OptimizeExprsThenConsiderSplits cenv env args let knownValue = match op, arginfos with @@ -1843,7 +2017,6 @@ and OptimizeExprOp cenv env (op, tyargs, args, m) = | None -> OptimizeExprOpFallback cenv env (op, tyargs, args', m) arginfos valu | None -> OptimizeExprOpFallback cenv env (op, tyargs, args', m) arginfos UnknownValue - and OptimizeExprOpFallback cenv env (op, tyargs, args', m) arginfos valu = // The generic case - we may collect information, but the construction/projection doesn't disappear let argsTSize = AddTotalSizes arginfos @@ -1858,7 +2031,12 @@ and OptimizeExprOpFallback cenv env (op, tyargs, args', m) arginfos valu = | TOp.Tuple tupInfo -> let isStruct = evalTupInfoIsStruct tupInfo if isStruct then 0, valu - else 1, MakeValueInfoForTuple (Array.ofList argValues) + else 1,MakeValueInfoForTuple (Array.ofList argValues) + | TOp.AnonRecd anonInfo -> + let isStruct = evalAnonInfoIsStruct anonInfo + if isStruct then 0, valu + else 1, valu + | TOp.AnonRecdGet _ | TOp.ValFieldGet _ | TOp.TupleFieldGet _ | TOp.UnionCaseFieldGet _ @@ -2210,8 +2388,11 @@ and TryOptimizeValInfo cenv env m vinfo = //------------------------------------------------------------------------- and AddValEqualityInfo g m (v:ValRef) info = - if v.IsMutable then - /// the env assumes known-values do not change + // ValValue is information that v = v2, where v2 does not change + // So we can't record this information for mutable values. An exception can be made + // for "outArg" values arising from method calls since they are only temporarily mutable + // when their address is passed to the method call. + if v.IsMutable && not (v.IsCompilerGenerated && v.DisplayName.StartsWith(PrettyNaming.outArgCompilerGeneratedName)) then info else {info with Info= MakeValueInfoForValue g m v info.Info} @@ -2253,11 +2434,13 @@ and OptimizeVal cenv env expr (v:ValRef, m) = //------------------------------------------------------------------------- and StripToNominalTyconRef cenv ty = - if isAppTy cenv.g ty then destAppTy cenv.g ty - elif isRefTupleTy cenv.g ty then - let tyargs = destRefTupleTy cenv.g ty - mkCompiledTupleTyconRef cenv.g false (List.length tyargs), tyargs - else failwith "StripToNominalTyconRef: unreachable" + match tryAppTy cenv.g ty with + | ValueSome x -> x + | _ -> + if isRefTupleTy cenv.g ty then + let tyargs = destRefTupleTy cenv.g ty + mkCompiledTupleTyconRef cenv.g false (List.length tyargs), tyargs + else failwith "StripToNominalTyconRef: unreachable" and CanDevirtualizeApplication cenv v vref ty args = valRefEq cenv.g v vref @@ -2559,7 +2742,7 @@ and TryInlineApplication cenv env finfo (tyargs: TType list, args: Expr list, m) // Inlining: beta reducing let expr' = MakeApplicationAndBetaReduce cenv.g (f2', f2ty, [tyargs], args', m) // Inlining: reoptimizing - Some (OptimizeExpr cenv {env with dontInline= Zset.add lambdaId env.dontInline} expr') + Some(OptimizeExpr cenv {env with dontInline= Zset.add lambdaId env.dontInline} expr') | _ -> None @@ -2811,7 +2994,9 @@ and OptimizeMatch cenv env (spMatch, exprm, dtree, targets, m, ty) = // REVIEW: consider collecting, merging and using information flowing through each line of the decision tree to each target let dtree', dinfo = OptimizeDecisionTree cenv env m dtree let targets', tinfos = OptimizeDecisionTreeTargets cenv env m targets - RebuildOptimizedMatch (spMatch, exprm, m, ty, dtree', targets', dinfo, tinfos) + let newExpr, newInfo = RebuildOptimizedMatch (spMatch, exprm, m, ty, dtree', targets', dinfo, tinfos) + let newExpr2 = if not (cenv.settings.localOpt()) then newExpr else CombineBoolLogic newExpr + newExpr2, newInfo and CombineMatchInfos dinfo tinfo = { TotalSize = dinfo.TotalSize + tinfo.TotalSize @@ -2977,7 +3162,7 @@ and OptimizeBinding cenv isRec env (TBind(vref, expr, spBind)) = | None -> false | Some mbrTyconRef -> // Check we can deref system_MarshalByRefObject_tcref. When compiling against the Silverlight mscorlib we can't - if mbrTyconRef.TryDeref.IsSome then + if ValueOptionInternal.isSome mbrTyconRef.TryDeref then // Check if this is a subtype of MarshalByRefObject assert (cenv.g.system_MarshalByRefObject_ty.IsSome) ExistsSameHeadTypeInHierarchy cenv.g cenv.amap vref.Range (generalizedTyconRef tcref) cenv.g.system_MarshalByRefObject_ty.Value @@ -3044,7 +3229,7 @@ and OptimizeModuleExpr cenv env x = not (ValueIsUsedOrHasEffect cenv (fun () -> fvs.FreeLocals) (bind, binfo)) && // Check the thing is hidden by the signature (if any) - hidden.mhiVals.Contains bind.Var && + hidden.HiddenVals.Contains bind.Var && // Check the thing is not compiled as a static field or property, since reflected definitions and other reflective stuff might need it not (IsCompiledAsStaticProperty cenv.g bind.Var)) @@ -3154,7 +3339,7 @@ and OptimizeModuleDefs cenv (env, bindInfosColl) defs = let defs, minfos = List.unzip defs (defs, UnionOptimizationInfos minfos), (env, bindInfosColl) -and OptimizeImplFileInternal cenv env isIncrementalFragment hidden (TImplFile(qname, pragmas, mexpr, hasExplicitEntryPoint, isScript)) = +and OptimizeImplFileInternal cenv env isIncrementalFragment hidden (TImplFile(qname, pragmas, mexpr, hasExplicitEntryPoint, isScript, anonRecdTypes)) = let env, mexpr', minfo = match mexpr with // FSI: FSI compiles everything as if you're typing incrementally into one module @@ -3173,7 +3358,7 @@ and OptimizeImplFileInternal cenv env isIncrementalFragment hidden (TImplFile(qn let hidden = ComputeHidingInfoAtAssemblyBoundary mexpr.Type hidden let minfo = AbstractLazyModulInfoByHiding true hidden minfo - env, TImplFile(qname, pragmas, mexpr', hasExplicitEntryPoint, isScript), minfo, hidden + env, TImplFile(qname, pragmas, mexpr', hasExplicitEntryPoint, isScript, anonRecdTypes), minfo, hidden //------------------------------------------------------------------------- // Entry point diff --git a/src/fsharp/PatternMatchCompilation.fs b/src/fsharp/PatternMatchCompilation.fs index 3ffbc94b04..625b23a70d 100755 --- a/src/fsharp/PatternMatchCompilation.fs +++ b/src/fsharp/PatternMatchCompilation.fs @@ -257,7 +257,7 @@ let RefuteDiscrimSet g m path discrims = | None -> raise CannotRefute | Some c -> match tryDestAppTy g ty with - | Some tcref when tcref.IsEnumTycon -> + | ValueSome tcref when tcref.IsEnumTycon -> // We must distinguish between F#-defined enums and other .NET enums, as they are represented differently in the TAST let enumValues = if tcref.IsILEnumTycon then @@ -418,8 +418,8 @@ let getDiscrimOfPattern (g: TcGlobals) tpinst t = Some(DecisionTreeTest.UnionCase (c,instTypes tpinst tyargs')) | TPat_array (args,ty,_m) -> Some(DecisionTreeTest.ArrayLength (args.Length,ty)) - | TPat_query ((pexp,resTys,apatVrefOpt,idx,apinfo),_,_m) -> - Some(DecisionTreeTest.ActivePatternCase (pexp, instTypes tpinst resTys, apatVrefOpt, idx, apinfo)) + | TPat_query ((activePatExpr,resTys,apatVrefOpt,idx,apinfo),_,_m) -> + Some(DecisionTreeTest.ActivePatternCase (activePatExpr, instTypes tpinst resTys, apatVrefOpt, idx, apinfo)) | _ -> None let constOfDiscrim discrim = @@ -579,8 +579,8 @@ let rec BuildSwitch inpExprOpt g expr edges dflt m = let testexpr = match discrim with | DecisionTreeTest.ArrayLength(n,_) -> - let _v,vexp,bind = mkCompGenLocalAndInvisbleBind g "testExpr" m testexpr - mkLetBind m bind (mkLazyAnd g m (mkNonNullTest g m vexp) (mkILAsmCeq g m (mkLdlen g m vexp) (mkInt g m n))) + let _v,vExpr,bind = mkCompGenLocalAndInvisbleBind g "testExpr" m testexpr + mkLetBind m bind (mkLazyAnd g m (mkNonNullTest g m vExpr) (mkILAsmCeq g m (mkLdlen g m vExpr) (mkInt g m n))) | DecisionTreeTest.Const (Const.String _ as c) -> mkCallEqualsOperator g m g.string_ty testexpr (Expr.Const(c,m,g.string_ty)) | DecisionTreeTest.Const (Const.Decimal _ as c) -> @@ -716,7 +716,7 @@ let CompilePatternBasic warnOnUnused warnOnIncomplete actionOnFailure - (topv,topgtvs) + (origInputVal, origInputValTypars, _origInputExprOpt: Expr option) (clausesL: TypedMatchClause list) inputTy resultTy = @@ -764,7 +764,7 @@ let CompilePatternBasic // We throw instead of rethrow on unmatched try-catch in a computation expression. But why? // Because this isn't a real .NET exception filter/handler but just a function we're passing // to a computation expression builder to simulate one. - mkThrow matchm resultTy (exprForVal matchm topv) + mkThrow matchm resultTy (exprForVal matchm origInputVal) | ThrowIncompleteMatchException -> mkThrow matchm resultTy @@ -809,9 +809,9 @@ let CompilePatternBasic // Build versions of these functions which apply a dummy instantiation to the overall type arguments let GetSubExprOfInput,getDiscrimOfPattern = - let tyargs = List.map (fun _ -> g.unit_ty) topgtvs - let unit_tpinst = mkTyparInst topgtvs tyargs - GetSubExprOfInput g (topgtvs,tyargs,unit_tpinst), + let tyargs = List.map (fun _ -> g.unit_ty) origInputValTypars + let unit_tpinst = mkTyparInst origInputValTypars tyargs + GetSubExprOfInput g (origInputValTypars,tyargs,unit_tpinst), getDiscrimOfPattern g unit_tpinst // The main recursive loop of the pattern match compiler @@ -850,7 +850,7 @@ let CompilePatternBasic // OK, build the whole tree and whack on the binding if any let finalDecisionTree = - let inpExprToSwitch = (match inpExprOpt with Some vexp -> vexp | None -> GetSubExprOfInput subexpr) + let inpExprToSwitch = (match inpExprOpt with Some vExpr -> vExpr | None -> GetSubExprOfInput subexpr) let tree = BuildSwitch inpExprOpt g inpExprToSwitch simulSetOfCases defaultTreeOpt matchm match bindOpt with | None -> tree @@ -907,6 +907,11 @@ let CompilePatternBasic else None,true) + and IsCopyableInputExpr origInputExpr = + match origInputExpr with + | Expr.Op (TOp.LValueOp (LByrefGet, v), [], [], _) when not v.IsMutable -> true + | _ -> false + and ChoosePreBinder simulSetOfEdgeDiscrims subexpr = match simulSetOfEdgeDiscrims with // Very simple 'isinst' tests: put the result of 'isinst' in a local variable @@ -922,27 +927,32 @@ let CompilePatternBasic | EdgeDiscrim(_i',(DecisionTreeTest.IsInst (_srcty,tgty)),m) :: _rest (* check we can use a simple 'isinst' instruction *) - when canUseTypeTestFast g tgty && isNil topgtvs -> + when canUseTypeTestFast g tgty && isNil origInputValTypars -> - let v,vexp = mkCompGenLocal m "typeTestResult" tgty - if topv.IsMemberOrModuleBinding then - AdjustValToTopVal v topv.DeclaringEntity ValReprInfo.emptyValData - let argexp = GetSubExprOfInput subexpr - let appexp = mkIsInst tgty argexp matchm - Some(vexp),Some(mkInvisibleBind v appexp) + let v,vExpr = mkCompGenLocal m "typeTestResult" tgty + if origInputVal.IsMemberOrModuleBinding then + AdjustValToTopVal v origInputVal.DeclaringEntity ValReprInfo.emptyValData + let argExpr = GetSubExprOfInput subexpr + let appExpr = mkIsInst tgty argExpr matchm + Some vExpr, Some(mkInvisibleBind v appExpr) - // Any match on a struct union must take the address of its input + // Any match on a struct union must take the address of its input. + // We can shortcut the addrof when the original input is a deref of a byref value. | EdgeDiscrim(_i',(DecisionTreeTest.UnionCase (ucref, _)),_) :: _rest - when isNil topgtvs && ucref.Tycon.IsStructRecordOrUnionTycon -> - - let argexp = GetSubExprOfInput subexpr - let vOpt, addrexp, _readonly, _writeonly = mkExprAddrOfExprAux g true false NeverMutates argexp None matchm + when isNil origInputValTypars && ucref.Tycon.IsStructRecordOrUnionTycon -> + + let argExpr = GetSubExprOfInput subexpr + let argExpr = + match argExpr, _origInputExprOpt with + | Expr.Val(v1, _, _), Some origInputExpr when valEq origInputVal v1.Deref && IsCopyableInputExpr origInputExpr -> origInputExpr + | _ -> argExpr + let vOpt, addrExp, _readonly, _writeonly = mkExprAddrOfExprAux g true false NeverMutates argExpr None matchm match vOpt with - | None -> Some addrexp, None + | None -> Some addrExp, None | Some (v,e) -> - if topv.IsMemberOrModuleBinding then - AdjustValToTopVal v topv.DeclaringEntity ValReprInfo.emptyValData - Some addrexp, Some (mkInvisibleBind v e) + if origInputVal.IsMemberOrModuleBinding then + AdjustValToTopVal v origInputVal.DeclaringEntity ValReprInfo.emptyValData + Some addrExp, Some (mkInvisibleBind v e) @@ -952,29 +962,29 @@ let CompilePatternBasic | [EdgeDiscrim(_, ListConsDiscrim g tinst, m)] | [EdgeDiscrim(_, ListEmptyDiscrim g tinst, m)] (* check we can use a simple 'isinst' instruction *) - when isNil topgtvs -> + when isNil origInputValTypars -> let ucaseTy = (mkProvenUnionCaseTy g.cons_ucref tinst) - let v,vexp = mkCompGenLocal m "unionTestResult" ucaseTy - if topv.IsMemberOrModuleBinding then - AdjustValToTopVal v topv.DeclaringEntity ValReprInfo.emptyValData - let argexp = GetSubExprOfInput subexpr - let appexp = mkIsInst ucaseTy argexp matchm - Some vexp,Some (mkInvisibleBind v appexp) + let v,vExpr = mkCompGenLocal m "unionTestResult" ucaseTy + if origInputVal.IsMemberOrModuleBinding then + AdjustValToTopVal v origInputVal.DeclaringEntity ValReprInfo.emptyValData + let argExpr = GetSubExprOfInput subexpr + let appExpr = mkIsInst ucaseTy argExpr matchm + Some vExpr,Some (mkInvisibleBind v appExpr) #endif // Active pattern matches: create a variable to hold the results of executing the active pattern. - | (EdgeDiscrim(_,(DecisionTreeTest.ActivePatternCase(pexp,resTys,_,_,apinfo)),m) :: _) -> + | (EdgeDiscrim(_,(DecisionTreeTest.ActivePatternCase(activePatExpr,resTys,_,_,apinfo)),m) :: _) -> - if not (isNil topgtvs) then error(InternalError("Unexpected generalized type variables when compiling an active pattern",m)) - let rty = apinfo.ResultType g m resTys - let v,vexp = mkCompGenLocal m ("activePatternResult" + string (newUnique())) rty - if topv.IsMemberOrModuleBinding then - AdjustValToTopVal v topv.DeclaringEntity ValReprInfo.emptyValData - let argexp = GetSubExprOfInput subexpr - let appexp = mkApps g ((pexp,tyOfExpr g pexp), [], [argexp],m) + if not (isNil origInputValTypars) then error(InternalError("Unexpected generalized type variables when compiling an active pattern",m)) + let resTy = apinfo.ResultType g m resTys + let v,vExpr = mkCompGenLocal m ("activePatternResult" + string (newUnique())) resTy + if origInputVal.IsMemberOrModuleBinding then + AdjustValToTopVal v origInputVal.DeclaringEntity ValReprInfo.emptyValData + let argExpr = GetSubExprOfInput subexpr + let appExpr = mkApps g ((activePatExpr, tyOfExpr g activePatExpr), [], [argExpr],m) - Some(vexp),Some(mkInvisibleBind v appexp) + Some(vExpr),Some(mkInvisibleBind v appExpr) | _ -> None,None @@ -1003,16 +1013,16 @@ let CompilePatternBasic #if OPTIMIZE_LIST_MATCHING isNone inpExprOpt && #endif - (isNil topgtvs && - not topv.IsMemberOrModuleBinding && + (isNil origInputValTypars && + not origInputVal.IsMemberOrModuleBinding && not ucref.Tycon.IsStructRecordOrUnionTycon && ucref.UnionCase.RecdFields.Length >= 1 && ucref.Tycon.UnionCasesArray.Length > 1) -> - let v,vexp = mkCompGenLocal m "unionCase" (mkProvenUnionCaseTy ucref tinst) - let argexp = GetSubExprOfInput subexpr - let appexp = mkUnionCaseProof (argexp, ucref,tinst,m) - Some vexp,Some(mkInvisibleBind v appexp) + let v,vExpr = mkCompGenLocal m "unionCase" (mkProvenUnionCaseTy ucref tinst) + let argExpr = GetSubExprOfInput subexpr + let appExpr = mkUnionCaseProof (argExpr, ucref,tinst,m) + Some vExpr,Some(mkInvisibleBind v appExpr) | _ -> None,None @@ -1134,7 +1144,7 @@ let CompilePatternBasic | None -> let exprIn = match inpExprOpt with - | Some addrexp -> addrexp + | Some addrExp -> addrExp | None -> accessf tpinst exprIn mkUnionCaseFieldGetUnprovenViaExprAddr (exprIn,ucref1,instTypes tpinst tyargs,j,exprm) @@ -1180,7 +1190,7 @@ let CompilePatternBasic // Otherwise call the helper mkCallUnboxFast g exprm (instType tpinst tgtTy1) (accessf tpinst exprIn) - let (v,exprIn) = BindSubExprOfInput g amap topgtvs pbind exprm (SubExpr(accessf',ve)) + let (v,exprIn) = BindSubExprOfInput g amap origInputValTypars pbind exprm (SubExpr(accessf',ve)) [Frontier (i, active', valMap.Add v exprIn )] | None -> [Frontier (i, active', valMap)] @@ -1220,7 +1230,7 @@ let CompilePatternBasic | TPat_wild _ -> BindProjectionPatterns [] s | TPat_as(p',pbind,m) -> - let (v,subExpr') = BindSubExprOfInput g amap topgtvs pbind m subExpr + let (v,subExpr') = BindSubExprOfInput g amap origInputValTypars pbind m subExpr BindProjectionPattern (Active(path,subExpr,p')) (accActive,accValMap.Add v subExpr' ) | TPat_tuple(tupInfo,ps,tyargs,_m) -> let accessf' j tpinst subExpr' = mkTupleFieldGet g (tupInfo,accessf tpinst subExpr',instTypes tpinst tyargs,j,exprm) @@ -1263,7 +1273,7 @@ let CompilePatternBasic let frontiers = ((clausesL |> List.mapi (fun i c -> - let initialSubExpr = SubExpr((fun _tpinst x -> x),(exprForVal topv.Range topv,topv)) + let initialSubExpr = SubExpr((fun _tpinst x -> x),(exprForVal origInputVal.Range origInputVal,origInputVal)) let investigations = BindProjectionPattern (Active(PathEmpty(inputTy),initialSubExpr,c.Pattern)) ([],ValMap<_>.Empty) mkFrontiers investigations i) |> List.concat) @@ -1289,7 +1299,7 @@ let CompilePatternBasic let isPartialOrWhenClause (c:TypedMatchClause) = isPatternPartial c.Pattern || c.GuardExpr.IsSome -let rec CompilePattern g denv amap exprm matchm warnOnUnused actionOnFailure (topv,topgtvs) (clausesL: TypedMatchClause list) inputTy resultTy = +let rec CompilePattern g denv amap exprm matchm warnOnUnused actionOnFailure (origInputVal,origInputValTypars,origInputExprOpt) (clausesL: TypedMatchClause list) inputTy resultTy = match clausesL with | _ when List.exists isPartialOrWhenClause clausesL -> // Partial clauses cause major code explosion if treated naively @@ -1299,13 +1309,13 @@ let rec CompilePattern g denv amap exprm matchm warnOnUnused actionOnFailure (t let warnOnUnused = false in (* we can't turn this on since we're pretending all partial's fail in order to control the complexity of this. *) let warnOnIncomplete = true let clausesPretendAllPartialFail = List.collect (fun (TClause(p,whenOpt,tg,m)) -> [TClause(erasePartialPatterns p,whenOpt,tg,m)]) clausesL - let _ = CompilePatternBasic g denv amap exprm matchm warnOnUnused warnOnIncomplete actionOnFailure (topv,topgtvs) clausesPretendAllPartialFail inputTy resultTy + let _ = CompilePatternBasic g denv amap exprm matchm warnOnUnused warnOnIncomplete actionOnFailure (origInputVal,origInputValTypars,origInputExprOpt) clausesPretendAllPartialFail inputTy resultTy let warnOnIncomplete = false let rec atMostOnePartialAtATime clauses = match List.takeUntil isPartialOrWhenClause clauses with | l,[] -> - CompilePatternBasic g denv amap exprm matchm warnOnUnused warnOnIncomplete actionOnFailure (topv,topgtvs) l inputTy resultTy + CompilePatternBasic g denv amap exprm matchm warnOnUnused warnOnIncomplete actionOnFailure (origInputVal,origInputValTypars,origInputExprOpt) l inputTy resultTy | l,(h :: t) -> // Add the partial clause doGroupWithAtMostOnePartial (l @ [h]) t @@ -1327,12 +1337,10 @@ let rec CompilePattern g denv amap exprm matchm warnOnUnused actionOnFailure (t // Make the clause that represents the remaining cases of the pattern match let clauseForRestOfMatch = TClause(TPat_wild matchm,None,TTarget(List.empty,expr,spTarget),matchm) - CompilePatternBasic - g denv amap exprm matchm warnOnUnused warnOnIncomplete actionOnFailure (topv,topgtvs) - (group @ [clauseForRestOfMatch]) inputTy resultTy + CompilePatternBasic g denv amap exprm matchm warnOnUnused warnOnIncomplete actionOnFailure (origInputVal,origInputValTypars,origInputExprOpt) (group @ [clauseForRestOfMatch]) inputTy resultTy atMostOnePartialAtATime clausesL | _ -> - CompilePatternBasic g denv amap exprm matchm warnOnUnused true actionOnFailure (topv,topgtvs) (clausesL: TypedMatchClause list) inputTy resultTy + CompilePatternBasic g denv amap exprm matchm warnOnUnused true actionOnFailure (origInputVal,origInputValTypars,origInputExprOpt) clausesL inputTy resultTy diff --git a/src/fsharp/PatternMatchCompilation.fsi b/src/fsharp/PatternMatchCompilation.fsi index 348f37ae94..d4fbba2588 100755 --- a/src/fsharp/PatternMatchCompilation.fsi +++ b/src/fsharp/PatternMatchCompilation.fsi @@ -57,8 +57,9 @@ val internal CompilePattern : // warn on unused? bool -> ActionOnFailure -> - // the value being matched against, perhaps polymorphic - Val * Typars -> + // the value being matched against, perhaps polymorphic. Optionally includes the + // input expression, only for the case of immediate matching on a byref pointer + Val * Typars * Expr option -> // input type-checked syntax of pattern matching TypedMatchClause list -> // input type diff --git a/src/fsharp/PostInferenceChecks.fs b/src/fsharp/PostInferenceChecks.fs index 761d5395e8..acc3c0c03a 100755 --- a/src/fsharp/PostInferenceChecks.fs +++ b/src/fsharp/PostInferenceChecks.fs @@ -106,7 +106,10 @@ type env = external : bool /// Current return scope of the expr. - returnScope : int } + returnScope : int + + /// Are we in an app expression (Expr.App)? + isInAppExpr: bool } let BindTypar env (tp:Typar) = { env with @@ -198,6 +201,7 @@ type cenv = { boundVals: Dictionary // really a hash set limitVals: Dictionary mutable potentialUnboundUsesOfVals: StampMap + mutable anonRecdTypes: StampMap g: TcGlobals amap: Import.ImportMap /// For reading metadata @@ -301,7 +305,7 @@ let BindVals cenv env vs = List.iter (BindVal cenv env) vs // approx walk of type //-------------------------------------------------------------------------- -let rec CheckTypeDeep ((visitTy,visitTyconRefOpt,visitAppTyOpt,visitTraitSolutionOpt, visitTyarOpt) as f) g env isInner ty = +let rec CheckTypeDeep (cenv: cenv) ((visitTy,visitTyconRefOpt,visitAppTyOpt,visitTraitSolutionOpt, visitTyparOpt) as f) g env isInner ty = // We iterate the _solved_ constraints as well, to pick up any record of trait constraint solutions // This means we walk _all_ the constraints _everywhere_ in a type, including // those attached to _solved_ type variables. This is used by PostTypeCheckSemanticChecks to detect uses of @@ -326,40 +330,54 @@ let rec CheckTypeDeep ((visitTy,visitTyconRefOpt,visitAppTyOpt,visitTraitSolutio match ty with | TType_forall (tps,body) -> let env = BindTypars g env tps - CheckTypeDeep f g env isInner body - tps |> List.iter (fun tp -> tp.Constraints |> List.iter (CheckTypeConstraintDeep f g env)) + CheckTypeDeep cenv f g env isInner body + tps |> List.iter (fun tp -> tp.Constraints |> List.iter (CheckTypeConstraintDeep cenv f g env)) | TType_measure _ -> () | TType_app (tcref,tinst) -> match visitTyconRefOpt with | Some visitTyconRef -> visitTyconRef isInner tcref | None -> () - CheckTypesDeep f g env tinst + + // If it's a 'byref<'T>', don't check 'T as an inner. This allows byref>. + // 'byref>' is invalid and gets checked in visitAppTy. + if isByrefTyconRef g tcref then + CheckTypesDeepNoInner cenv f g env tinst + else + CheckTypesDeep cenv f g env tinst + match visitAppTyOpt with | Some visitAppTy -> visitAppTy (tcref, tinst) | None -> () - - | TType_ucase (_,tinst) -> CheckTypesDeep f g env tinst - | TType_tuple (_,tys) -> CheckTypesDeep f g env tys - | TType_fun (s,t) -> CheckTypeDeep f g env true s; CheckTypeDeep f g env true t + | TType_anon (anonInfo,tys) -> + if not (cenv.anonRecdTypes.ContainsKey anonInfo.Stamp) then + cenv.anonRecdTypes <- cenv.anonRecdTypes.Add(anonInfo.Stamp, anonInfo) + CheckTypesDeep cenv f g env tys + + | TType_ucase (_,tinst) -> CheckTypesDeep cenv f g env tinst + | TType_tuple (_,tys) -> CheckTypesDeep cenv f g env tys + | TType_fun (s,t) -> CheckTypeDeep cenv f g env true s; CheckTypeDeep cenv f g env true t | TType_var tp -> if not tp.IsSolved then - match visitTyarOpt with + match visitTyparOpt with | None -> () | Some visitTyar -> visitTyar (env,tp) -and CheckTypesDeep f g env tys = - tys |> List.iter (CheckTypeDeep f g env true) +and CheckTypesDeep cenv f g env tys = + tys |> List.iter (CheckTypeDeep cenv f g env true) -and CheckTypeConstraintDeep f g env x = +and CheckTypesDeepNoInner cenv f g env tys = + tys |> List.iter (CheckTypeDeep cenv f g env false) + +and CheckTypeConstraintDeep cenv f g env x = match x with - | TyparConstraint.CoercesTo(ty,_) -> CheckTypeDeep f g env true ty - | TyparConstraint.MayResolveMember(traitInfo,_) -> CheckTraitInfoDeep f g env traitInfo - | TyparConstraint.DefaultsTo(_,ty,_) -> CheckTypeDeep f g env true ty - | TyparConstraint.SimpleChoice(tys,_) -> CheckTypesDeep f g env tys - | TyparConstraint.IsEnum(uty,_) -> CheckTypeDeep f g env true uty - | TyparConstraint.IsDelegate(aty,bty,_) -> CheckTypeDeep f g env true aty; CheckTypeDeep f g env true bty + | TyparConstraint.CoercesTo(ty,_) -> CheckTypeDeep cenv f g env true ty + | TyparConstraint.MayResolveMember(traitInfo,_) -> CheckTraitInfoDeep cenv f g env traitInfo + | TyparConstraint.DefaultsTo(_,ty,_) -> CheckTypeDeep cenv f g env true ty + | TyparConstraint.SimpleChoice(tys,_) -> CheckTypesDeep cenv f g env tys + | TyparConstraint.IsEnum(uty,_) -> CheckTypeDeep cenv f g env true uty + | TyparConstraint.IsDelegate(aty,bty,_) -> CheckTypeDeep cenv f g env true aty; CheckTypeDeep cenv f g env true bty | TyparConstraint.SupportsComparison _ | TyparConstraint.SupportsEquality _ | TyparConstraint.SupportsNull _ @@ -368,21 +386,21 @@ and CheckTypeConstraintDeep f g env x = | TyparConstraint.IsReferenceType _ | TyparConstraint.RequiresDefaultConstructor _ -> () -and CheckTraitInfoDeep ((_,_,_,visitTraitSolutionOpt,_) as f) g env (TTrait(tys,_,_,argtys,rty,soln)) = - CheckTypesDeep f g env tys - CheckTypesDeep f g env argtys - Option.iter (CheckTypeDeep f g env true ) rty +and CheckTraitInfoDeep cenv ((_,_,_,visitTraitSolutionOpt,_) as f) g env (TTrait(tys,_,_,argtys,rty,soln)) = + CheckTypesDeep cenv f g env tys + CheckTypesDeep cenv f g env argtys + Option.iter (CheckTypeDeep cenv f g env true ) rty match visitTraitSolutionOpt, !soln with | Some visitTraitSolution, Some sln -> visitTraitSolution sln | _ -> () /// Check for byref-like types let CheckForByrefLikeType cenv env m ty check = - CheckTypeDeep (ignore, Some (fun _deep tcref -> if isByrefLikeTyconRef cenv.g m tcref then check()), None, None, None) cenv.g env false ty + CheckTypeDeep cenv (ignore, Some (fun _deep tcref -> if isByrefLikeTyconRef cenv.g m tcref then check()), None, None, None) cenv.g env false ty /// Check for byref types let CheckForByrefType cenv env ty check = - CheckTypeDeep (ignore, Some (fun _deep tcref -> if isByrefTyconRef cenv.g tcref then check()), None, None, None) cenv.g env false ty + CheckTypeDeep cenv (ignore, Some (fun _deep tcref -> if isByrefTyconRef cenv.g tcref then check()), None, None, None) cenv.g env false ty /// check captures under lambdas /// @@ -440,28 +458,28 @@ let AccessInternalsVisibleToAsInternal thisCompPath internalsVisibleToPaths acce let CheckTypeForAccess (cenv:cenv) env objName valAcc m ty = if cenv.reportErrors then - let visitTye ty = + let visitType ty = // We deliberately only check the fully stripped type for accessibility, // because references to private type abbreviations are permitted match tryDestAppTy cenv.g ty with - | None -> () - | Some tcref -> + | ValueNone -> () + | ValueSome tcref -> let thisCompPath = compPathOfCcu cenv.viewCcu let tyconAcc = tcref.Accessibility |> AccessInternalsVisibleToAsInternal thisCompPath cenv.internalsVisibleToPaths if isLessAccessible tyconAcc valAcc then errorR(Error(FSComp.SR.chkTypeLessAccessibleThanType(tcref.DisplayName, (objName())), m)) - CheckTypeDeep (visitTye, None, None, None, None) cenv.g env false ty + CheckTypeDeep cenv (visitType, None, None, None, None) cenv.g env false ty let WarnOnWrongTypeForAccess (cenv:cenv) env objName valAcc m ty = if cenv.reportErrors then - let visitTye ty = + let visitType ty = // We deliberately only check the fully stripped type for accessibility, // because references to private type abbreviations are permitted match tryDestAppTy cenv.g ty with - | None -> () - | Some tcref -> + | ValueNone -> () + | ValueSome tcref -> let thisCompPath = compPathOfCcu cenv.viewCcu let tyconAcc = tcref.Accessibility |> AccessInternalsVisibleToAsInternal thisCompPath cenv.internalsVisibleToPaths if isLessAccessible tyconAcc valAcc then @@ -469,13 +487,16 @@ let WarnOnWrongTypeForAccess (cenv:cenv) env objName valAcc m ty = let warningText = errorText + System.Environment.NewLine + FSComp.SR.tcTypeAbbreviationsCheckedAtCompileTime() warning(AttributeChecking.ObsoleteWarning(warningText, m)) - CheckTypeDeep (visitTye, None, None, None, None) cenv.g env false ty + CheckTypeDeep cenv (visitType, None, None, None, None) cenv.g env false ty /// Indicates whether a byref or byref-like type is permitted at a particular location [] type PermitByRefType = /// Don't permit any byref or byref-like types - | None + | None + + /// Don't permit any byref or byref-like types on inner types. + | NoInnerByRefLike /// Permit only a Span or IsByRefLike type | SpanLike @@ -552,7 +573,7 @@ let rec mkArgsForAppliedExpr isBaseCall argsl x = | _ -> [] /// Check types occurring in the TAST. -let CheckType permitByRefLike (cenv:cenv) env m ty = +let CheckTypeAux permitByRefLike (cenv:cenv) env m ty onInnerByrefError = if cenv.reportErrors then let visitTyar (env,tp) = if not (env.boundTypars.ContainsKey tp) then @@ -561,13 +582,17 @@ let CheckType permitByRefLike (cenv:cenv) env m ty = else errorR (Error(FSComp.SR.checkNotSufficientlyGenericBecauseOfScope(tp.DisplayName),m)) - let visitTyconRef _isInner tcref = + let visitTyconRef isInner tcref = + + let isInnerByRefLike = isInner && isByrefLikeTyconRef cenv.g m tcref match permitByRefLike with | PermitByRefType.None when isByrefLikeTyconRef cenv.g m tcref -> errorR(Error(FSComp.SR.chkErrorUseOfByref(), m)) - | PermitByRefType.SpanLike when isByrefTyconRef cenv.g tcref -> - errorR(Error(FSComp.SR.chkErrorUseOfByref(), m)) + | PermitByRefType.NoInnerByRefLike when isInnerByRefLike -> + onInnerByrefError () + | PermitByRefType.SpanLike when isByrefTyconRef cenv.g tcref || isInnerByRefLike -> + onInnerByrefError () | _ -> () if tyconRefEq cenv.g cenv.g.system_Void_tcref tcref then @@ -576,13 +601,13 @@ let CheckType permitByRefLike (cenv:cenv) env m ty = // check if T contains byref types in case of byref let visitAppTy (tcref,tinst) = if isByrefLikeTyconRef cenv.g m tcref then - let visitTye ty0 = + let visitType ty0 = match tryDestAppTy cenv.g ty0 with - | None -> () - | Some tcref2 -> + | ValueNone -> () + | ValueSome tcref2 -> if isByrefTyconRef cenv.g tcref2 then errorR(Error(FSComp.SR.chkNoByrefsOfByrefs(NicePrint.minimalStringOfType cenv.denv ty), m)) - CheckTypesDeep (visitTye, None, None, None, None) cenv.g env tinst + CheckTypesDeep cenv (visitType, None, None, None, None) cenv.g env tinst let visitTraitSolution info = match info with @@ -593,8 +618,10 @@ let CheckType permitByRefLike (cenv:cenv) env m ty = cenv.potentialUnboundUsesOfVals <- cenv.potentialUnboundUsesOfVals.Add(vref.Stamp,m) | _ -> () - CheckTypeDeep (ignore, Some visitTyconRef, Some visitAppTy, Some visitTraitSolution, Some visitTyar) cenv.g env false ty + CheckTypeDeep cenv (ignore, Some visitTyconRef, Some visitAppTy, Some visitTraitSolution, Some visitTyar) cenv.g env false ty +let CheckType permitByRefLike cenv env m ty = + CheckTypeAux permitByRefLike cenv env m ty (fun () -> errorR(Error(FSComp.SR.chkErrorUseOfByref(), m))) /// Check types occurring in TAST (like CheckType) and additionally reject any byrefs. /// The additional byref checks are to catch "byref instantiations" - one place were byref are not permitted. @@ -606,12 +633,18 @@ let CheckTypePermitSpanLike (cenv:cenv) env m ty = CheckType PermitByRefType.Spa /// Check types occurring in TAST but allow all byrefs. Only used on internally-generated types let CheckTypePermitAllByrefs (cenv:cenv) env m ty = CheckType PermitByRefType.All cenv env m ty +/// Check types ocurring in TAST but disallow inner types to be byref or byref-like types. +let CheckTypeNoInnerByrefs cenv env m ty = CheckType PermitByRefType.NoInnerByRefLike cenv env m ty + let CheckTypeInstNoByrefs cenv env m tyargs = tyargs |> List.iter (CheckTypeNoByrefs cenv env m) let CheckTypeInstPermitAllByrefs cenv env m tyargs = tyargs |> List.iter (CheckTypePermitAllByrefs cenv env m) +let CheckTypeInstNoInnerByrefs cenv env m tyargs = + tyargs |> List.iter (CheckTypeNoInnerByrefs cenv env m) + /// Applied functions get wrapped in coerce nodes for subsumption coercions let (|OptionalCoerce|) = function | Expr.Op(TOp.Coerce _, _, [Expr.App(f, _, _, [], _)], _) -> f @@ -663,7 +696,10 @@ and CheckValRef (cenv:cenv) (env:env) v m (context: PermitByRefExpr) = if context.Disallow && isByrefLikeTy cenv.g m v.Type then errorR(Error(FSComp.SR.chkNoByrefAtThisPoint(v.DisplayName), m)) - CheckTypePermitAllByrefs cenv env m v.Type // the byref checks are done at the actual binding of the value + if env.isInAppExpr then + CheckTypePermitAllByrefs cenv env m v.Type // we do checks for byrefs elsewhere + else + CheckTypeNoInnerByrefs cenv env m v.Type /// Check a use of a value and CheckValUse (cenv: cenv) (env: env) (vref: ValRef, vFlags, m) (context: PermitByRefExpr) = @@ -857,6 +893,7 @@ and CheckExpr (cenv:cenv) (env:env) origExpr (context:PermitByRefExpr) : Limit = match expr with | Expr.Sequential (e1,e2,dir,_,_) -> CheckExprNoByrefs cenv env e1 + match dir with | NormalSeq -> CheckExpr cenv env e2 context // carry context into _;RHS (normal sequencing only) @@ -879,7 +916,7 @@ and CheckExpr (cenv:cenv) (env:env) origExpr (context:PermitByRefExpr) : Limit = CheckExpr cenv env body context | Expr.Const (_,m,ty) -> - CheckTypePermitAllByrefs cenv env m ty + CheckTypeNoInnerByrefs cenv env m ty NoLimit | Expr.Val (vref,vFlags,m) -> @@ -930,9 +967,13 @@ and CheckExpr (cenv:cenv) (env:env) origExpr (context:PermitByRefExpr) : Limit = errorR(Error(FSComp.SR.tcCannotCallAbstractBaseMember(v.DisplayName),m)) NoLimit else + let env = { env with isInAppExpr = true } + let returnTy = tyOfExpr g expr + CheckValRef cenv env v m PermitByRefExpr.No CheckValRef cenv env baseVal m PermitByRefExpr.No CheckTypeInstNoByrefs cenv env m tyargs + CheckTypeNoInnerByrefs cenv env m returnTy CheckExprs cenv env rest (mkArgsForAppliedExpr true rest f) // Allow base calls to IL methods @@ -941,7 +982,7 @@ and CheckExpr (cenv:cenv) (env:env) origExpr (context:PermitByRefExpr) : Limit = // Disallow calls to abstract base methods on IL types. match tryDestAppTy g baseVal.Type with - | Some tcref when tcref.IsILTycon -> + | ValueSome tcref when tcref.IsILTycon -> try // This is awkward - we have to explicitly re-resolve back to the IL metadata to determine if the method is abstract. // We believe this may be fragile in some situations, since we are using the Abstract IL code to compare @@ -973,12 +1014,20 @@ and CheckExpr (cenv:cenv) (env:env) origExpr (context:PermitByRefExpr) : Limit = // Allow '%expr' in quotations | Expr.App(Expr.Val(vref,_,_),_,tinst,[arg],m) when isSpliceOperator g vref && env.quote -> - CheckTypeInstPermitAllByrefs cenv env m tinst // it's the splice operator, a byref instantiation is allowed + CheckTypeInstNoInnerByrefs cenv env m tinst // it's the splice operator, a byref instantiation is allowed CheckExprNoByrefs cenv env arg NoLimit // Check an application | Expr.App(f,_fty,tyargs,argsl,m) -> + let returnTy = tyOfExpr g expr + + // This is to handle recursive cases. Don't check 'returnTy' again if we are still inside a app expression. + if not env.isInAppExpr then + CheckTypeNoInnerByrefs cenv env m returnTy + + let env = { env with isInAppExpr = true } + CheckTypeInstNoByrefs cenv env m tyargs CheckExprNoByrefs cenv env f @@ -987,7 +1036,6 @@ and CheckExpr (cenv:cenv) (env:env) origExpr (context:PermitByRefExpr) : Limit = | Expr.Val(vref, _, _) when vref.IsInstanceMember && not argsl.IsEmpty -> true | _ -> false - let returnTy = tyOfExpr g expr let contexts = mkArgsForAppliedExpr false argsl f if hasReceiver then CheckCallWithReceiver cenv env m returnTy argsl contexts context @@ -1010,7 +1058,7 @@ and CheckExpr (cenv:cenv) (env:env) origExpr (context:PermitByRefExpr) : Limit = NoLimit | Expr.Match(_,_,dtree,targets,m,ty) -> - CheckTypePermitAllByrefs cenv env m ty // computed byrefs allowed at each branch + CheckTypeNoInnerByrefs cenv env m ty // computed byrefs allowed at each branch CheckDecisionTree cenv env dtree CheckDecisionTreeTargets cenv env targets context @@ -1065,7 +1113,7 @@ and CheckExprOp cenv env (op,tyargs,args,m) context expr = CheckExprsNoByRefLike cenv env [e1;e2] | TOp.TryFinally _,[_],[Expr.Lambda(_,_,_,[_],e1,_,_); Expr.Lambda(_,_,_,[_],e2,_,_)] -> - CheckTypeInstPermitAllByrefs cenv env m tyargs // result of a try/finally can be a byref + CheckTypeInstNoInnerByrefs cenv env m tyargs // result of a try/finally can be a byref ctorLimitedZoneCheck() let limit = CheckExpr cenv env e1 context // result of a try/finally can be a byref if in a position where the overall expression is can be a byref CheckExprNoByrefs cenv env e2 @@ -1076,7 +1124,7 @@ and CheckExprOp cenv env (op,tyargs,args,m) context expr = CheckExprsNoByRefLike cenv env [e1;e2;e3] | TOp.TryCatch _,[_],[Expr.Lambda(_,_,_,[_],e1,_,_); Expr.Lambda(_,_,_,[_],_e2,_,_); Expr.Lambda(_,_,_,[_],e3,_,_)] -> - CheckTypeInstPermitAllByrefs cenv env m tyargs // result of a try/catch can be a byref + CheckTypeInstNoInnerByrefs cenv env m tyargs // result of a try/catch can be a byref ctorLimitedZoneCheck() let limit1 = CheckExpr cenv env e1 context // result of a try/catch can be a byref if in a position where the overall expression is can be a byref // [(* e2; -- don't check filter body - duplicates logic in 'catch' body *) e3] @@ -1087,7 +1135,7 @@ and CheckExprOp cenv env (op,tyargs,args,m) context expr = CheckTypeInstNoByrefs cenv env m tyargs CheckTypeInstNoByrefs cenv env m enclTypeArgs CheckTypeInstNoByrefs cenv env m methTypeArgs - CheckTypeInstPermitAllByrefs cenv env m tys // permit byref returns + CheckTypeInstNoInnerByrefs cenv env m tys // permit byref returns let hasReceiver = (methRef.CallingConv.IsInstance || methRef.CallingConv.IsInstanceExplicit) && @@ -1176,6 +1224,7 @@ and CheckExprOp cenv env (op,tyargs,args,m) context expr = errorR(Error(FSComp.SR.chkNoWriteToLimitedSpan(vref.DisplayName), m)) NoLimit + | TOp.AnonRecdGet _,_,[arg1] | TOp.TupleFieldGet _,_,[arg1] -> CheckTypeInstNoByrefs cenv env m tyargs CheckExprsPermitByRefLike cenv env [arg1] (* Compiled pattern matches on immutable value structs come through here. *) @@ -1263,7 +1312,7 @@ and CheckExprOp cenv env (op,tyargs,args,m) context expr = CheckExpr cenv env obj context | TOp.ILAsm (instrs,tys),_,_ -> - CheckTypeInstPermitAllByrefs cenv env m tys + CheckTypeInstNoInnerByrefs cenv env m tys CheckTypeInstNoByrefs cenv env m tyargs match instrs,args with // Write a .NET instance field @@ -1323,7 +1372,7 @@ and CheckExprOp cenv env (op,tyargs,args,m) context expr = CheckTypeInstNoByrefs cenv env m tyargs CheckExprsNoByRefLike cenv env args -and CheckLambdas isTop (memInfo: ValMemberInfo option) cenv env inlined topValInfo alwaysCheckNoReraise e m ety context = +and CheckLambdas isTop (memInfo: ValMemberInfo option) cenv env inlined topValInfo alwaysCheckNoReraise e mOrig ety context = let g = cenv.g // The topValInfo here says we are _guaranteeing_ to compile a function value // as a .NET method with precisely the corresponding argument counts. @@ -1353,7 +1402,28 @@ and CheckLambdas isTop (memInfo: ValMemberInfo option) cenv env inlined topValIn // any byRef arguments are considered used, as they may be 'out's restArgs |> List.iter (fun arg -> if isByrefTy g arg.Type then arg.SetHasBeenReferenced()) - syntacticArgs |> List.iter (CheckValSpec cenv env) + let permitByRefType = + if isTop then + PermitByRefType.NoInnerByRefLike + else + PermitByRefType.None + + // Check argument types + syntacticArgs + |> List.iter (fun arg -> + CheckValSpecAux permitByRefType cenv env arg (fun () -> + if arg.IsCompilerGenerated then + errorR(Error(FSComp.SR.chkErrorUseOfByref(), arg.Range)) + else + errorR(Error(FSComp.SR.chkInvalidFunctionParameterType(arg.DisplayName, NicePrint.minimalStringOfType cenv.denv arg.Type), arg.Range)) + ) + ) + + // Check return type + CheckTypeAux permitByRefType cenv env mOrig bodyty (fun () -> + errorR(Error(FSComp.SR.chkInvalidFunctionReturnType(NicePrint.minimalStringOfType cenv.denv bodyty), mOrig)) + ) + syntacticArgs |> List.iter (BindVal cenv env) // Trigger a test hook @@ -1393,8 +1463,10 @@ and CheckLambdas isTop (memInfo: ValMemberInfo option) cenv env inlined topValIn // This path is for expression bindings that are not actually lambdas | _ -> + let m = mOrig // Permit byrefs for let x = ... - CheckTypePermitAllByrefs cenv env m ety + CheckTypeNoInnerByrefs cenv env m ety + let limit = if not inlined && (isByrefLikeTy g m ety || isNativePtrTy g ety) then // allow byref to occur as RHS of byref binding. @@ -1441,7 +1513,7 @@ and CheckDecisionTreeTargets cenv env targets context = and CheckDecisionTreeTarget cenv env context (TTarget(vs,e,_)) = BindVals cenv env vs - vs |> List.iter (CheckValSpec cenv env) + vs |> List.iter (CheckValSpec PermitByRefType.All cenv env) CheckExpr cenv env e context and CheckDecisionTree cenv env x = @@ -1461,11 +1533,11 @@ and CheckDecisionTreeSwitch cenv env (e,cases,dflt,m) = and CheckDecisionTreeTest cenv env m discrim = match discrim with - | DecisionTreeTest.UnionCase (_,tinst) -> CheckTypeInstPermitAllByrefs cenv env m tinst - | DecisionTreeTest.ArrayLength (_,ty) -> CheckTypePermitAllByrefs cenv env m ty + | DecisionTreeTest.UnionCase (_,tinst) -> CheckTypeInstNoInnerByrefs cenv env m tinst + | DecisionTreeTest.ArrayLength (_,ty) -> CheckTypeNoInnerByrefs cenv env m ty | DecisionTreeTest.Const _ -> () | DecisionTreeTest.IsNull -> () - | DecisionTreeTest.IsInst (srcTy,tgtTy) -> CheckTypePermitAllByrefs cenv env m srcTy; CheckTypePermitAllByrefs cenv env m tgtTy + | DecisionTreeTest.IsInst (srcTy,tgtTy) -> CheckTypeNoInnerByrefs cenv env m srcTy; CheckTypeNoInnerByrefs cenv env m tgtTy | DecisionTreeTest.ActivePatternCase (exp,_,_,_,_) -> CheckExprNoByrefs cenv env exp and CheckAttrib cenv env (Attrib(_,_,args,props,_,_,_)) = @@ -1549,10 +1621,13 @@ and CheckValInfo cenv env (ValReprInfo(_,args,ret)) = and CheckArgInfo cenv env (argInfo : ArgReprInfo) = CheckAttribs cenv env argInfo.Attribs -and CheckValSpec cenv env (v:Val) = +and CheckValSpecAux permitByRefLike cenv env (v:Val) onInnerByrefError = v.Attribs |> CheckAttribs cenv env v.ValReprInfo |> Option.iter (CheckValInfo cenv env) - v.Type |> CheckTypePermitAllByrefs cenv env v.Range + CheckTypeAux permitByRefLike cenv env v.Range v.Type onInnerByrefError + +and CheckValSpec permitByRefLike cenv env v = + CheckValSpecAux permitByRefLike cenv env v (fun () -> errorR(Error(FSComp.SR.chkErrorUseOfByref(), v.Range))) and AdjustAccess isHidden (cpath: unit -> CompilationPath) access = if isHidden then @@ -1583,7 +1658,6 @@ and CheckBinding cenv env alwaysCheckNoReraise context (TBind(v,bindRhs,_) as bi let nm = v.DisplayName errorR(Error(FSComp.SR.chkMemberUsedInInvalidWay(nm, nm, stringOfRange m), v.Range)) - // Byrefs allowed for x in 'let x = ...' v.Type |> CheckTypePermitAllByrefs cenv env v.Range v.Attribs |> CheckAttribs cenv env v.ValReprInfo |> Option.iter (CheckValInfo cenv env) @@ -1603,7 +1677,9 @@ and CheckBinding cenv env alwaysCheckNoReraise context (TBind(v,bindRhs,_) as bi CheckForByrefLikeType cenv env v.Range v.Type (fun () -> errorR(Error(FSComp.SR.chkNoByrefAsTopValue(),v.Range))) | _ -> () - if Option.isSome v.PublicPath then + match v.PublicPath with + | None -> () + | _ -> if // Don't support implicit [] on generated members, except the implicit members // for 'let' bound functions in classes. @@ -1776,8 +1852,6 @@ let CheckModuleBinding cenv env (TBind(v,e,_) as bind) = MethInfosEquivByNameAndSig EraseAll true g cenv.amap v.Range minfo1 minfo2 then errorR(Duplicate(kind,v.DisplayName,v.Range))) - - // Properties get 'get_X', only if there are no args // Properties get 'get_X' match v.ValReprInfo with @@ -2055,8 +2129,8 @@ let CheckEntityDefn cenv env (tycon:Entity) = let env = BindTypars g env tps for argtys in argtysl do for (argty, _) in argtys do - CheckTypePermitAllByrefs cenv env m argty - CheckTypePermitAllByrefs cenv env m rty + CheckTypeNoInnerByrefs cenv env vref.Range argty + CheckTypeNoInnerByrefs cenv env vref.Range rty | None -> () @@ -2066,20 +2140,20 @@ let CheckEntityDefn cenv env (tycon:Entity) = superOfTycon g tycon |> CheckTypeNoByrefs cenv env m if tycon.IsUnionTycon then - tycon.UnionCasesAsList |> List.iter (fun uc -> + tycon.UnionCasesArray |> Array.iter (fun uc -> CheckAttribs cenv env uc.Attribs - uc.RecdFields |> List.iter (CheckRecdField true cenv env tycon)) + uc.RecdFieldsArray |> Array.iter (CheckRecdField true cenv env tycon)) // Access checks let access = AdjustAccess (IsHiddenTycon env.sigToImplRemapInfo tycon) (fun () -> tycon.CompilationPath) tycon.Accessibility - let visitTye ty = CheckTypeForAccess cenv env (fun () -> tycon.DisplayNameWithStaticParametersAndUnderscoreTypars) access tycon.Range ty + let visitType ty = CheckTypeForAccess cenv env (fun () -> tycon.DisplayNameWithStaticParametersAndUnderscoreTypars) access tycon.Range ty - abstractSlotValsOfTycons [tycon] |> List.iter (typeOfVal >> visitTye) + abstractSlotValsOfTycons [tycon] |> List.iter (typeOfVal >> visitType) - superOfTycon g tycon |> visitTye + superOfTycon g tycon |> visitType // We do not have to check access of interface implementations. See FSharp 1.0 5042 - //implements_of_tycon g tycon |> List.iter visitTye + //implements_of_tycon g tycon |> List.iter visitType if tycon.IsFSharpDelegateTycon then match tycon.TypeReprInfo with | TFSharpObjectRepr r -> @@ -2087,8 +2161,8 @@ let CheckEntityDefn cenv env (tycon:Entity) = | TTyconDelegate ss -> //ss.ClassTypars //ss.MethodTypars - ss.FormalReturnType |> Option.iter visitTye - ss.FormalParams |> List.iterSquared (fun (TSlotParam(_,ty,_,_,_,_)) -> visitTye ty) + ss.FormalReturnType |> Option.iter visitType + ss.FormalParams |> List.iterSquared (fun (TSlotParam(_,ty,_,_,_,_)) -> visitType ty) | _ -> () | _ -> () @@ -2098,7 +2172,7 @@ let CheckEntityDefn cenv env (tycon:Entity) = |> List.filter (isInterfaceTy g) if tycon.IsFSharpInterfaceTycon then - List.iter visitTye interfaces // Check inherited interface is as accessible + List.iter visitType interfaces // Check inherited interface is as accessible if not (isRecdOrStructTyconRefAssumedImmutable g tcref) && isRecdOrStructTyconRefReadOnly g m tcref then errorR(Error(FSComp.SR.readOnlyAttributeOnStructWithMutableField(),m)) @@ -2185,6 +2259,7 @@ let CheckTopImpl (g,amap,reportErrors,infoReader,internalsVisibleToPaths,viewCcu boundVals= new Dictionary<_,_>(100, HashIdentity.Structural) limitVals= new Dictionary<_,_>(100, HashIdentity.Structural) potentialUnboundUsesOfVals=Map.empty + anonRecdTypes = StampMap.Empty usesQuotations=false infoReader=infoReader internalsVisibleToPaths=internalsVisibleToPaths @@ -2215,10 +2290,11 @@ let CheckTopImpl (g,amap,reportErrors,infoReader,internalsVisibleToPaths,viewCcu boundTypars= TyparMap.Empty reflect=false external=false - returnScope = 0 } + returnScope = 0 + isInAppExpr = false } CheckModuleExpr cenv env mexpr CheckAttribs cenv env extraAttribs if cenv.usesQuotations && QuotationTranslator.QuotationGenerationScope.ComputeQuotationFormat(g) = QuotationTranslator.QuotationSerializationFormat.FSharp_20_Plus then viewCcu.UsesFSharp20PlusQuotations <- true - cenv.entryPointGiven + cenv.entryPointGiven, cenv.anonRecdTypes diff --git a/src/fsharp/PostInferenceChecks.fsi b/src/fsharp/PostInferenceChecks.fsi index 970c143155..62ad52d449 100644 --- a/src/fsharp/PostInferenceChecks.fsi +++ b/src/fsharp/PostInferenceChecks.fsi @@ -11,4 +11,6 @@ open Microsoft.FSharp.Compiler.Tastops open Microsoft.FSharp.Compiler.TcGlobals val testFlagMemberBody : bool ref -val CheckTopImpl : TcGlobals * ImportMap * bool * InfoReader * CompilationPath list * CcuThunk * DisplayEnv * ModuleOrNamespaceExprWithSig * Attribs * (bool * bool) * isInternalTestSpanStackReferring: bool -> bool + +/// Perform the checks on the TAST for a file after type inference is complete. +val CheckTopImpl : TcGlobals * ImportMap * bool * InfoReader * CompilationPath list * CcuThunk * DisplayEnv * ModuleOrNamespaceExprWithSig * Attribs * (bool * bool) * isInternalTestSpanStackReferring: bool -> bool * StampMap diff --git a/src/fsharp/PrettyNaming.fs b/src/fsharp/PrettyNaming.fs index fe0bb57745..923be2ccea 100755 --- a/src/fsharp/PrettyNaming.fs +++ b/src/fsharp/PrettyNaming.fs @@ -484,30 +484,36 @@ module public Microsoft.FSharp.Compiler.PrettyNaming let [] private mangledGenericTypeNameSym = '`' - let IsMangledGenericName (n:string) = - n.IndexOf mangledGenericTypeNameSym <> -1 && + let TryDemangleGenericNameAndPos (n:string) = (* check what comes after the symbol is a number *) - let m = n.LastIndexOf mangledGenericTypeNameSym - let mutable res = m < n.Length - 1 - for i = m + 1 to n.Length - 1 do - res <- res && n.[i] >= '0' && n.[i] <= '9' - res + let pos = n.LastIndexOf mangledGenericTypeNameSym + if pos = -1 then ValueNone else + let mutable res = pos < n.Length - 1 + let mutable i = pos + 1 + while res && i < n.Length do + let char = n.[i] + if not (char >= '0' && char <= '9') then + res <- false + i <- i + 1 + if res then + ValueSome pos + else + ValueNone type NameArityPair = NameArityPair of string * int - let DecodeGenericTypeName n = - if IsMangledGenericName n then - let pos = n.LastIndexOf mangledGenericTypeNameSym - let res = n.Substring(0,pos) - let num = n.Substring(pos+1,n.Length - pos - 1) - NameArityPair(res, int32 num) - else NameArityPair(n,0) + let DecodeGenericTypeName pos (mangledName:string) = + let res = mangledName.Substring(0,pos) + let num = mangledName.Substring(pos+1,mangledName.Length - pos - 1) + NameArityPair(res, int32 num) + + let DemangleGenericTypeNameWithPos pos (mangledName:string) = + mangledName.Substring(0,pos) - let DemangleGenericTypeName n = - if IsMangledGenericName n then - let pos = n.LastIndexOf mangledGenericTypeNameSym - n.Substring(0,pos) - else n + let DemangleGenericTypeName (mangledName:string) = + match TryDemangleGenericNameAndPos mangledName with + | ValueSome pos -> DemangleGenericTypeNameWithPos pos mangledName + | _ -> mangledName let private chopStringTo (s:string) (c:char) = match s.IndexOf c with @@ -544,21 +550,31 @@ module public Microsoft.FSharp.Compiler.PrettyNaming /// Return a string array delimited by the given separator. /// Note that a quoted string is not going to be mangled into pieces. + let inline private isNotQuotedQuotation (text: string) n = n > 0 && text.[n-1] <> '\\' let private splitAroundQuotation (text:string) (separator:char) = let length = text.Length - let isNotQuotedQuotation n = n > 0 && text.[n-1] <> '\\' - let rec split (i, cur, group, insideQuotation) = - if i>=length then List.rev (cur::group) else + let result = ResizeArray() + let mutable insideQuotation = false + let mutable start = 0 + for i = 0 to length - 1 do match text.[i], insideQuotation with // split when seeing a separator - | c, false when c = separator -> split (i+1, "", cur::group, false) + | c, false when c = separator -> + result.Add(text.Substring(start, i - start)) + insideQuotation <- false + start <- i + 1 + | _, _ when i = length - 1 -> + result.Add(text.Substring(start, i - start + 1)) // keep reading if a separator is inside quotation - | c, true when c = separator -> split (i+1, cur+(Char.ToString c), group, true) - // open or close quotation - | '\"', _ when isNotQuotedQuotation i -> split (i+1, cur+"\"", group, not insideQuotation) + | c, true when c = separator -> + insideQuotation <- true + // open or close quotation + | '\"', _ when isNotQuotedQuotation text i -> + insideQuotation <- not insideQuotation // keep reading - | c, _ -> split (i+1, cur+(Char.ToString c), group, insideQuotation) - split (0, "", [], false) |> Array.ofList + | _ -> () + + result.ToArray() /// Return a string array delimited by the given separator up to the maximum number. /// Note that a quoted string is not going to be mangled into pieces. @@ -684,3 +700,5 @@ module public Microsoft.FSharp.Compiler.PrettyNaming | Some v when v = actualArgValue -> None | _ -> Some (defaultArgName, actualArgValue)) mangleProvidedTypeName (nm, nonDefaultArgs) + + let outArgCompilerGeneratedName = "outArg" \ No newline at end of file diff --git a/src/fsharp/QuotationPickler.fs b/src/fsharp/QuotationPickler.fs index ea9ba92077..79c2ac2796 100755 --- a/src/fsharp/QuotationPickler.fs +++ b/src/fsharp/QuotationPickler.fs @@ -304,12 +304,12 @@ module SimplePickle = open SimplePickle -let p_assref x st = p_string x st +let p_assemblyref x st = p_string x st let p_NamedType x st = match x with - | Idx n -> p_tup2 p_string p_assref (string n, "") st - | Named (nm,ass) -> p_tup2 p_string p_assref (nm, ass) st + | Idx n -> p_tup2 p_string p_assemblyref (string n, "") st + | Named (nm,a) -> p_tup2 p_string p_assemblyref (nm, a) st let p_tycon x st = match x with diff --git a/src/fsharp/QuotationTranslator.fs b/src/fsharp/QuotationTranslator.fs index 9c7bc53e33..b0f1e7ce4c 100755 --- a/src/fsharp/QuotationTranslator.fs +++ b/src/fsharp/QuotationTranslator.fs @@ -66,7 +66,7 @@ type QuotationGenerationScope = static member ComputeQuotationFormat g = let deserializeExValRef = ValRefForIntrinsic g.deserialize_quoted_FSharp_40_plus_info - if deserializeExValRef.TryDeref.IsSome then + if ValueOptionInternal.isSome deserializeExValRef.TryDeref then QuotationSerializationFormat.FSharp_40_Plus else QuotationSerializationFormat.FSharp_20_Plus @@ -424,6 +424,20 @@ and private ConvExprCore cenv (env : QuotationTranslationEnv) (expr: Expr) : QP. let argsR = ConvExprs cenv env args QP.mkRecdMk(rgtypR,tyargsR,argsR) + | TOp.AnonRecd anonInfo, _, _ -> + let tref = anonInfo.ILTypeRef + let rgtypR = ConvILTypeRef cenv tref + let tyargsR = ConvTypes cenv env m tyargs + let argsR = ConvExprs cenv env args + QP.mkRecdMk(rgtypR,tyargsR,argsR) + + | TOp.AnonRecdGet (anonInfo, n), _, _ -> + let tref = anonInfo.ILTypeRef + let rgtypR = ConvILTypeRef cenv tref + let tyargsR = ConvTypes cenv env m tyargs + let argsR = ConvExprs cenv env args + QP.mkRecdGet((rgtypR,anonInfo.SortedNames.[n]),tyargsR,argsR) + | TOp.UnionCaseFieldGet (ucref,n),tyargs,[e] -> ConvUnionFieldGet cenv env m ucref n tyargs e @@ -807,6 +821,10 @@ and ConvType cenv env m ty = | TType_fun(a,b) -> QP.mkFunTy(ConvType cenv env m a,ConvType cenv env m b) | TType_tuple(tupInfo,l) -> ConvType cenv env m (mkCompiledTupleTy cenv.g (evalTupInfoIsStruct tupInfo) l) + | TType_anon(anonInfo,tinst) -> + let tref = anonInfo.ILTypeRef + let tinstR = ConvTypes cenv env m tinst + QP.mkILNamedTy(ConvILTypeRefUnadjusted cenv m tref, tinstR) | TType_var(tp) -> QP.mkVarTy(ConvTyparRef cenv env m tp) | TType_forall(_spec,_ty) -> wfail(Error(FSComp.SR.crefNoInnerGenericsInQuotations(),m)) | _ -> wfail(Error (FSComp.SR.crefQuotationsCantContainThisType(),m)) @@ -960,12 +978,12 @@ and ConvILTypeRef cenv (tr:ILTypeRef) = QP.Idx idx | QuotationSerializationFormat.FSharp_20_Plus -> - let assref = + let assemblyRef = match tr.Scope with | ILScopeRef.Local -> "." | _ -> tr.Scope.QualifiedName - QP.Named(tr.BasicQualifiedName, assref) + QP.Named(tr.BasicQualifiedName, assemblyRef) and ConvVoidType cenv m = QP.mkILNamedTy(ConvTyconRef cenv cenv.g.system_Void_tcref m, []) diff --git a/src/fsharp/SignatureConformance.fs b/src/fsharp/SignatureConformance.fs index 8b0981451e..ac0c23e970 100644 --- a/src/fsharp/SignatureConformance.fs +++ b/src/fsharp/SignatureConformance.fs @@ -37,8 +37,8 @@ type Checker(g, amap, denv, remapInfo: SignatureRepackageInfo, checkingSig) = // Used when checking attributes. let sigToImplRemap = let remap = Remap.Empty - let remap = (remapInfo.mrpiEntities,remap) ||> List.foldBack (fun (implTcref ,signTcref) acc -> addTyconRefRemap signTcref implTcref acc) - let remap = (remapInfo.mrpiVals ,remap) ||> List.foldBack (fun (implValRef,signValRef) acc -> addValRemap signValRef.Deref implValRef.Deref acc) + let remap = (remapInfo.RepackagedEntities,remap) ||> List.foldBack (fun (implTcref ,signTcref) acc -> addTyconRefRemap signTcref implTcref acc) + let remap = (remapInfo.RepackagedVals ,remap) ||> List.foldBack (fun (implValRef,signValRef) acc -> addValRemap signValRef.Deref implValRef.Deref acc) remap // For all attributable elements (types, modules, exceptions, record fields, unions, parameters, generic type parameters) @@ -177,46 +177,62 @@ type Checker(g, amap, denv, remapInfo: SignatureRepackageInfo, checkingSig) = |> ListSet.setify (typeEquiv g) |> List.filter (isInterfaceTy g) let aintfs = flatten aintfs - let aintfsUser = flatten aintfsUser let fintfs = flatten fintfs let unimpl = ListSet.subtract (fun fity aity -> typeAEquiv g aenv aity fity) fintfs aintfs - (unimpl |> List.forall (fun ity -> errorR (Error (FSComp.SR.DefinitionsInSigAndImplNotCompatibleMissingInterface(implTycon.TypeOrMeasureKind.ToString(),implTycon.DisplayName, NicePrint.minimalStringOfType denv ity),m)); false)) && + (unimpl + |> List.forall (fun ity -> + let errorMessage = FSComp.SR.DefinitionsInSigAndImplNotCompatibleMissingInterface(implTycon.TypeOrMeasureKind.ToString(),implTycon.DisplayName, NicePrint.minimalStringOfType denv ity) + errorR (Error(errorMessage,m)); false)) && + + let aintfsUser = flatten aintfsUser + let hidden = ListSet.subtract (typeAEquiv g aenv) aintfsUser fintfs - let warningOrError = if implTycon.IsFSharpInterfaceTycon then error else warning - hidden |> List.iter (fun ity -> warningOrError (InterfaceNotRevealed(denv,ity,implTycon.Range))) + let continueChecks,warningOrError = if implTycon.IsFSharpInterfaceTycon then false,errorR else true,warning + (hidden |> List.forall (fun ity -> warningOrError (InterfaceNotRevealed(denv,ity,implTycon.Range)); continueChecks)) && let aNull = IsUnionTypeWithNullAsTrueValue g implTycon let fNull = IsUnionTypeWithNullAsTrueValue g sigTycon if aNull && not fNull then - errorR(Error(FSComp.SR.DefinitionsInSigAndImplNotCompatibleImplementationSaysNull(implTycon.TypeOrMeasureKind.ToString(),implTycon.DisplayName),m)) + errorR(Error(FSComp.SR.DefinitionsInSigAndImplNotCompatibleImplementationSaysNull(implTycon.TypeOrMeasureKind.ToString(),implTycon.DisplayName),m)) + false elif fNull && not aNull then - errorR(Error(FSComp.SR.DefinitionsInSigAndImplNotCompatibleSignatureSaysNull(implTycon.TypeOrMeasureKind.ToString(),implTycon.DisplayName),m)) + errorR(Error(FSComp.SR.DefinitionsInSigAndImplNotCompatibleSignatureSaysNull(implTycon.TypeOrMeasureKind.ToString(),implTycon.DisplayName),m)) + false + else let aNull2 = TypeNullIsExtraValue g m (generalizedTyconRef (mkLocalTyconRef implTycon)) let fNull2 = TypeNullIsExtraValue g m (generalizedTyconRef (mkLocalTyconRef implTycon)) if aNull2 && not fNull2 then errorR(Error(FSComp.SR.DefinitionsInSigAndImplNotCompatibleImplementationSaysNull2(implTycon.TypeOrMeasureKind.ToString(),implTycon.DisplayName),m)) + false elif fNull2 && not aNull2 then errorR(Error(FSComp.SR.DefinitionsInSigAndImplNotCompatibleSignatureSaysNull2(implTycon.TypeOrMeasureKind.ToString(),implTycon.DisplayName),m)) + false + else let aSealed = isSealedTy g (generalizedTyconRef (mkLocalTyconRef implTycon)) let fSealed = isSealedTy g (generalizedTyconRef (mkLocalTyconRef sigTycon)) - if aSealed && not fSealed then + if aSealed && not fSealed then errorR(Error(FSComp.SR.DefinitionsInSigAndImplNotCompatibleImplementationSealed(implTycon.TypeOrMeasureKind.ToString(),implTycon.DisplayName),m)) - if not aSealed && fSealed then + false + elif not aSealed && fSealed then errorR(Error(FSComp.SR.DefinitionsInSigAndImplNotCompatibleImplementationIsNotSealed(implTycon.TypeOrMeasureKind.ToString(),implTycon.DisplayName),m)) + false + else let aPartial = isAbstractTycon implTycon let fPartial = isAbstractTycon sigTycon if aPartial && not fPartial then errorR(Error(FSComp.SR.DefinitionsInSigAndImplNotCompatibleImplementationIsAbstract(implTycon.TypeOrMeasureKind.ToString(),implTycon.DisplayName),m)) - - if not aPartial && fPartial then + false + elif not aPartial && fPartial then errorR(Error(FSComp.SR.DefinitionsInSigAndImplNotCompatibleSignatureIsAbstract(implTycon.TypeOrMeasureKind.ToString(),implTycon.DisplayName),m)) - - if not (typeAEquiv g aenv (superOfTycon g implTycon) (superOfTycon g sigTycon)) then + false + elif not (typeAEquiv g aenv (superOfTycon g implTycon) (superOfTycon g sigTycon)) then errorR (Error(FSComp.SR.DefinitionsInSigAndImplNotCompatibleTypesHaveDifferentBaseTypes(implTycon.TypeOrMeasureKind.ToString(),implTycon.DisplayName),m)) + false + else checkTypars m aenv implTypars sigTypars && checkTypeRepr m aenv implTycon sigTycon.TypeReprInfo && diff --git a/src/fsharp/SimulatedMSBuildReferenceResolver.fs b/src/fsharp/SimulatedMSBuildReferenceResolver.fs index 1668cdc09d..6fd5fc5312 100644 --- a/src/fsharp/SimulatedMSBuildReferenceResolver.fs +++ b/src/fsharp/SimulatedMSBuildReferenceResolver.fs @@ -186,8 +186,8 @@ let internal GetBestAvailableResolver() = let tryMSBuild v = // Detect if MSBuild is on the machine, if so use the resolver from there let mb = try Assembly.Load(sprintf "Microsoft.Build.Framework, Version=%s.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" v) |> Option.ofObj with _ -> None - let ass = mb |> Option.bind (fun _ -> try Assembly.Load(sprintf "FSharp.Compiler.Service.MSBuild.v%s" v) |> Option.ofObj with _ -> None) - let ty = ass |> Option.bind (fun ass -> ass.GetType("Microsoft.FSharp.Compiler.MSBuildReferenceResolver") |> Option.ofObj) + let assembly = mb |> Option.bind (fun _ -> try Assembly.Load(sprintf "FSharp.Compiler.Service.MSBuild.v%s" v) |> Option.ofObj with _ -> None) + let ty = assembly |> Option.bind (fun a -> a.GetType("Microsoft.FSharp.Compiler.MSBuildReferenceResolver") |> Option.ofObj) let obj = ty |> Option.bind (fun ty -> ty.InvokeMember("get_Resolver",BindingFlags.Static ||| BindingFlags.Public ||| BindingFlags.InvokeMethod ||| BindingFlags.NonPublic, null, null, [| |]) |> Option.ofObj) let resolver = obj |> Option.bind (fun obj -> match obj with :? Resolver as r -> Some r | _ -> None) resolver diff --git a/src/fsharp/TastOps.fs b/src/fsharp/TastOps.fs index db888dd8f9..23242b1aff 100644 --- a/src/fsharp/TastOps.fs +++ b/src/fsharp/TastOps.fs @@ -181,6 +181,12 @@ let rec remapTypeAux (tyenv : Remap) (ty:TType) = | Some tcr' -> TType_ucase (UCRef(tcr', n), remapTypesAux tyenv tinst) | None -> TType_ucase (UCRef(tcr, n), remapTypesAux tyenv tinst) + | TType_anon (anonInfo, l) as ty -> + let tupInfo' = remapTupInfoAux tyenv anonInfo.TupInfo + let l' = remapTypesAux tyenv l + if anonInfo.TupInfo === tupInfo' && l === l' then ty else + TType_anon (AnonRecdTypeInfo.Create(anonInfo.Assembly, tupInfo', anonInfo.SortedIds), l') + | TType_tuple (tupInfo, l) as ty -> let tupInfo' = remapTupInfoAux tyenv tupInfo let l' = remapTypesAux tyenv l @@ -229,7 +235,7 @@ and remapTupInfoAux _tyenv unt = and remapTypesAux tyenv types = List.mapq (remapTypeAux tyenv) types and remapTyparConstraintsAux tyenv cs = - cs |> List.choose (fun x -> + cs |> List.choose (fun x -> match x with | TyparConstraint.CoercesTo(ty, m) -> Some(TyparConstraint.CoercesTo (remapTypeAux tyenv ty, m)) @@ -263,6 +269,8 @@ and remapTraitAux tyenv (TTrait(tys, nm, mf, argtys, rty, slnCell)) = FSMethSln(remapTypeAux tyenv ty, remapValRef tyenv vref, remapTypesAux tyenv minst) | FSRecdFieldSln(tinst, rfref, isSet) -> FSRecdFieldSln(remapTypesAux tyenv tinst, remapRecdFieldRef tyenv.tyconRefRemap rfref, isSet) + | FSAnonRecdFieldSln(anonInfo, tinst, n) -> + FSAnonRecdFieldSln(anonInfo, remapTypesAux tyenv tinst, n) | BuiltInSln -> BuiltInSln | ClosedExprSln e -> @@ -667,7 +675,7 @@ let mkOuterCompiledTupleTy g isStruct tupElemTys = let marker = TType_app (mkCompiledTupleTyconRef g isStruct 1, [tyB]) TType_app (tcref, tysA@[marker]) | _ -> - TType_app (tcref, tysA@[TType_tuple (TupInfo.Const isStruct, tysB)]) + TType_app (tcref, tysA@[TType_tuple (mkTupInfo isStruct, tysB)]) //--------------------------------------------------------------------------- // Remove inference equations and abbreviations from types @@ -733,6 +741,9 @@ let evalTupInfoIsStruct aexpr = match aexpr with | TupInfo.Const b -> b +let evalAnonInfoIsStruct (anonInfo: AnonRecdTypeInfo) = + evalTupInfoIsStruct anonInfo.TupInfo + /// This erases outermost occurrences of inference equations, type abbreviations, non-generated provided types /// and measureable types (float<_>). /// It also optionally erases all "compilation representations", i.e. function and @@ -783,6 +794,8 @@ let isForallTy g ty = ty |> stripTyEqns g |> (function TType_forall _ -> tru let isAnyTupleTy g ty = ty |> stripTyEqns g |> (function TType_tuple _ -> true | _ -> false) let isRefTupleTy g ty = ty |> stripTyEqns g |> (function TType_tuple (tupInfo, _) -> not (evalTupInfoIsStruct tupInfo) | _ -> false) let isStructTupleTy g ty = ty |> stripTyEqns g |> (function TType_tuple (tupInfo, _) -> evalTupInfoIsStruct tupInfo | _ -> false) +let isAnonRecdTy g ty = ty |> stripTyEqns g |> (function TType_anon _ -> true | _ -> false) +let isStructAnonRecdTy g ty = ty |> stripTyEqns g |> (function TType_anon (anonInfo, _) -> evalAnonInfoIsStruct anonInfo | _ -> false) let isUnionTy g ty = ty |> stripTyEqns g |> (function TType_app(tcr, _) -> tcr.IsUnionTycon | _ -> false) let isReprHiddenTy g ty = ty |> stripTyEqns g |> (function TType_app(tcr, _) -> tcr.IsHiddenReprTycon | _ -> false) let isFSharpObjModelTy g ty = ty |> stripTyEqns g |> (function TType_app(tcr, _) -> tcr.IsFSharpObjectModelTycon | _ -> false) @@ -799,38 +812,48 @@ let isProvenUnionCaseTy ty = match ty with TType_ucase _ -> true | _ -> false let mkAppTy tcref tyargs = TType_app(tcref, tyargs) let mkProvenUnionCaseTy ucref tyargs = TType_ucase(ucref, tyargs) let isAppTy g ty = ty |> stripTyEqns g |> (function TType_app _ -> true | _ -> false) +let tryAppTy g ty = ty |> stripTyEqns g |> (function TType_app(tcref, tinst) -> ValueSome (tcref, tinst) | _ -> ValueNone) let destAppTy g ty = ty |> stripTyEqns g |> (function TType_app(tcref, tinst) -> tcref, tinst | _ -> failwith "destAppTy") let tcrefOfAppTy g ty = ty |> stripTyEqns g |> (function TType_app(tcref, _) -> tcref | _ -> failwith "tcrefOfAppTy") let argsOfAppTy g ty = ty |> stripTyEqns g |> (function TType_app(_, tinst) -> tinst | _ -> []) -let tryDestTyparTy g ty = ty |> stripTyEqns g |> (function TType_var v -> Some v | _ -> None) -let tryDestFunTy g ty = ty |> stripTyEqns g |> (function TType_fun (tyv, tau) -> Some(tyv, tau) | _ -> None) -let tryDestAppTy g ty = ty |> stripTyEqns g |> (function TType_app(tcref, _) -> Some tcref | _ -> None) -let tryAnyParTy g ty = ty |> stripTyEqns g |> (function TType_var v -> Some v | TType_measure unt when isUnitParMeasure g unt -> Some(destUnitParMeasure g unt) | _ -> None) +let tryDestTyparTy g ty = ty |> stripTyEqns g |> (function TType_var v -> ValueSome v | _ -> ValueNone) +let tryDestFunTy g ty = ty |> stripTyEqns g |> (function TType_fun (tyv, tau) -> ValueSome(tyv, tau) | _ -> ValueNone) +let tryDestAppTy g ty = ty |> stripTyEqns g |> (function TType_app(tcref, _) -> ValueSome tcref | _ -> ValueNone) +let tryDestAnonRecdTy g ty = ty |> stripTyEqns g |> (function TType_anon (anonInfo, tys) -> ValueSome (anonInfo, tys) | _ -> ValueNone) + +let tryAnyParTy g ty = ty |> stripTyEqns g |> (function TType_var v -> ValueSome v | TType_measure unt when isUnitParMeasure g unt -> ValueSome(destUnitParMeasure g unt) | _ -> ValueNone) +let tryAnyParTyOption g ty = ty |> stripTyEqns g |> (function TType_var v -> Some v | TType_measure unt when isUnitParMeasure g unt -> Some(destUnitParMeasure g unt) | _ -> None) let (|AppTy|_|) g ty = ty |> stripTyEqns g |> (function TType_app(tcref, tinst) -> Some (tcref, tinst) | _ -> None) let (|RefTupleTy|_|) g ty = ty |> stripTyEqns g |> (function TType_tuple(tupInfo, tys) when not (evalTupInfoIsStruct tupInfo) -> Some tys | _ -> None) let (|FunTy|_|) g ty = ty |> stripTyEqns g |> (function TType_fun(dty, rty) -> Some (dty, rty) | _ -> None) let tryNiceEntityRefOfTy ty = let ty = stripTyparEqnsAux false ty - match ty with + match ty with + | TType_app (tcref, _) -> ValueSome tcref + | TType_measure (Measure.Con tcref) -> ValueSome tcref + | _ -> ValueNone + +let tryNiceEntityRefOfTyOption ty = + let ty = stripTyparEqnsAux false ty + match ty with | TType_app (tcref, _) -> Some tcref | TType_measure (Measure.Con tcref) -> Some tcref | _ -> None - -let (|NullableTy|_|) g ty = - match ty with - | AppTy g (tcr, [tyarg]) when tyconRefEq g tcr g.system_Nullable_tcref -> Some tyarg +let (|NullableTy|_|) g ty = + match tryAppTy g ty with + | ValueSome (tcr, [tyarg]) when tyconRefEq g tcr g.system_Nullable_tcref -> Some tyarg | _ -> None let (|StripNullableTy|) g ty = - match ty with - | AppTy g (tcr, [tyarg]) when tyconRefEq g tcr g.system_Nullable_tcref -> tyarg + match tryAppTy g ty with + | ValueSome (tcr, [tyarg]) when tyconRefEq g tcr g.system_Nullable_tcref -> tyarg | _ -> ty let mkInstForAppTy g ty = - match ty with - | AppTy g (tcref, tinst) -> mkTyconRefInst tcref tinst + match tryAppTy g ty with + | ValueSome (tcref, tinst) -> mkTyconRefInst tcref tinst | _ -> [] let domainOfFunTy g ty = fst (destFunTy g ty) @@ -957,6 +980,9 @@ and typeAEquivAux erasureFlag g aenv ty1 ty2 = typesAEquivAux erasureFlag g aenv b1 b2 | TType_tuple (s1, l1), TType_tuple (s2, l2) -> structnessAEquiv s1 s2 && typesAEquivAux erasureFlag g aenv l1 l2 + | TType_anon (anonInfo1, l1), TType_anon (anonInfo2, l2) -> + anonInfoEquiv anonInfo1 anonInfo2 && + typesAEquivAux erasureFlag g aenv l1 l2 | TType_fun (dtys1, rty1), TType_fun (dtys2, rty2) -> typeAEquivAux erasureFlag g aenv dtys1 dtys2 && typeAEquivAux erasureFlag g aenv rty1 rty2 | TType_measure m1, TType_measure m2 -> @@ -965,6 +991,12 @@ and typeAEquivAux erasureFlag g aenv ty1 ty2 = | _ -> true | _ -> false + +and anonInfoEquiv (anonInfo1: AnonRecdTypeInfo) (anonInfo2: AnonRecdTypeInfo) = + ccuEq anonInfo1.Assembly anonInfo2.Assembly && + structnessAEquiv anonInfo1.TupInfo anonInfo2.TupInfo && + anonInfo1.SortedNames = anonInfo2.SortedNames + and structnessAEquiv un1 un2 = match un1, un2 with | TupInfo.Const b1, TupInfo.Const b2 -> (b1 = b2) @@ -1011,7 +1043,7 @@ let rec getErasedTypes g ty = getErasedTypes g rty | TType_var tp -> if tp.IsErased then [ty] else [] - | TType_app (_, b) | TType_ucase(_, b) | TType_tuple (_, b) -> + | TType_app (_, b) | TType_ucase(_, b) | TType_anon (_, b) | TType_tuple (_, b) -> List.foldBack (fun ty tys -> getErasedTypes g ty @ tys) b [] | TType_fun (dty, rty) -> getErasedTypes g dty @ getErasedTypes g rty @@ -1227,8 +1259,8 @@ let NormalizeDeclaredTyparsForEquiRecursiveInference g tps = tps |> List.map (fun tp -> let ty = mkTyparTy tp match tryAnyParTy g ty with - | Some anyParTy -> anyParTy - | None -> tp) + | ValueSome anyParTy -> anyParTy + | ValueNone -> tp) type TypeScheme = TypeScheme of Typars * TType @@ -1270,6 +1302,7 @@ let mkAsmExpr(code, tinst, args, rettys, m) = Expr.Op (TOp.ILAsm let mkUnionCaseExpr(uc, tinst, args, m) = Expr.Op (TOp.UnionCase uc, tinst, args, m) let mkExnExpr(uc, args, m) = Expr.Op (TOp.ExnConstr uc, [], args, m) let mkTupleFieldGetViaExprAddr(tupInfo, e, tinst, i, m) = Expr.Op (TOp.TupleFieldGet(tupInfo, i), tinst, [e], m) +let mkAnonRecdFieldGetViaExprAddr(anonInfo, e, tinst, i, m) = Expr.Op (TOp.AnonRecdGet(anonInfo, i), tinst, [e], m) let mkRecdFieldGetViaExprAddr(e, fref, tinst, m) = Expr.Op (TOp.ValFieldGet(fref), tinst, [e], m) let mkRecdFieldGetAddrViaExprAddr(readonly, e, fref, tinst, m) = Expr.Op (TOp.ValFieldGetAddr(fref, readonly), tinst, [e], m) @@ -1391,14 +1424,13 @@ type TyconRefMultiMap<'T>(contents: TyconRefMap<'T list>) = //-------------------------------------------------------------------------- /// Try to create a EntityRef suitable for accessing the given Entity from another assembly -let tryRescopeEntity viewedCcu (entity:Entity) : EntityRef option = +let tryRescopeEntity viewedCcu (entity:Entity) : ValueOption = match entity.PublicPath with - | Some pubpath -> Some (ERefNonLocal (rescopePubPath viewedCcu pubpath)) - | None -> None - + | Some pubpath -> ValueSome (ERefNonLocal (rescopePubPath viewedCcu pubpath)) + | None -> ValueNone /// Try to create a ValRef suitable for accessing the given Val from another assembly -let tryRescopeVal viewedCcu (entityRemap:Remap) (vspec:Val) : ValRef option = +let tryRescopeVal viewedCcu (entityRemap:Remap) (vspec:Val) : ValueOption = match vspec.PublicPath with | Some (ValPubPath(p, fullLinkageKey)) -> // The type information in the val linkage doesn't need to keep any information to trait solutions. @@ -1413,9 +1445,8 @@ let tryRescopeVal viewedCcu (entityRemap:Remap) (vspec:Val) : ValRef option = mkNonLocalValRef (rescopePubPathToParent viewedCcu p) fullLinkageKey else mkNonLocalValRef (rescopePubPath viewedCcu p) fullLinkageKey - Some vref - | None -> None - + ValueSome vref + | _ -> ValueNone //--------------------------------------------------------------------------- // Type information about records, constructors etc. @@ -1569,13 +1600,13 @@ let rankOfArrayTyconRef (g:TcGlobals) tcr = //------------------------------------------------------------------------- let destArrayTy (g:TcGlobals) ty = - match ty with - | AppTy g (tcref, [ty]) when isArrayTyconRef g tcref -> ty + match tryAppTy g ty with + | ValueSome (tcref, [ty]) when isArrayTyconRef g tcref -> ty | _ -> failwith "destArrayTy" let destListTy (g:TcGlobals) ty = - match ty with - | AppTy g (tcref, [ty]) when tyconRefEq g tcref g.list_tcr_canon -> ty + match tryAppTy g ty with + | ValueSome (tcref, [ty]) when tyconRefEq g tcref g.list_tcr_canon -> ty | _ -> failwith "destListTy" let tyconRefEqOpt g tcOpt tc = @@ -1667,24 +1698,24 @@ let rankOfArrayTy g ty = rankOfArrayTyconRef g (tcrefOfAppTy g ty) let isFSharpObjModelRefTy g ty = isFSharpObjModelTy g ty && - let tcr, _ = destAppTy g ty + let tcr = tcrefOfAppTy g ty match tcr.FSharpObjectModelTypeInfo.fsobjmodel_kind with | TTyconClass | TTyconInterface | TTyconDelegate _ -> true | TTyconStruct | TTyconEnum -> false let isFSharpClassTy g ty = match tryDestAppTy g ty with - | Some tcref -> tcref.Deref.IsFSharpClassTycon + | ValueSome tcref -> tcref.Deref.IsFSharpClassTycon | _ -> false let isFSharpStructTy g ty = match tryDestAppTy g ty with - | Some tcref -> tcref.Deref.IsFSharpStructOrEnumTycon + | ValueSome tcref -> tcref.Deref.IsFSharpStructOrEnumTycon | _ -> false let isFSharpInterfaceTy g ty = match tryDestAppTy g ty with - | Some tcref -> tcref.Deref.IsFSharpInterfaceTycon + | ValueSome tcref -> tcref.Deref.IsFSharpInterfaceTycon | _ -> false let isDelegateTy g ty = @@ -1695,7 +1726,7 @@ let isDelegateTy g ty = | ILTypeMetadata (TILObjectReprData(_, _, td)) -> td.IsDelegate | FSharpOrArrayOrByrefOrTupleOrExnTypeMetadata -> match tryDestAppTy g ty with - | Some tcref -> tcref.Deref.IsFSharpDelegateTycon + | ValueSome tcref -> tcref.Deref.IsFSharpDelegateTycon | _ -> false let isInterfaceTy g ty = @@ -1716,20 +1747,21 @@ let isClassTy g ty = let isStructOrEnumTyconTy g ty = match tryDestAppTy g ty with - | Some tcref -> tcref.Deref.IsStructOrEnumTycon + | ValueSome tcref -> tcref.Deref.IsStructOrEnumTycon | _ -> false let isStructRecordOrUnionTyconTy g ty = match tryDestAppTy g ty with - | Some tcref -> tcref.Deref.IsStructRecordOrUnionTycon + | ValueSome tcref -> tcref.Deref.IsStructRecordOrUnionTycon | _ -> false let isStructTy g ty = match tryDestAppTy g ty with - | Some tcref -> + | ValueSome tcref -> let tycon = tcref.Deref tycon.IsStructRecordOrUnionTycon || tycon.IsStructOrEnumTycon - | _ -> false + | _ -> + isStructAnonRecdTy g ty || isStructTupleTy g ty let isRefTy g ty = not (isStructOrEnumTyconTy g ty) && @@ -1756,7 +1788,7 @@ let isRefTy g ty = let rec isUnmanagedTy g ty = let ty = stripTyEqnsAndMeasureEqns g ty match tryDestAppTy g ty with - | Some tcref -> + | ValueSome tcref -> let isEq tcref2 = tyconRefEq g tcref tcref2 if isEq g.nativeptr_tcr || isEq g.nativeint_tcr || isEq g.sbyte_tcr || isEq g.byte_tcr || @@ -1778,7 +1810,7 @@ let rec isUnmanagedTy g ty = | [] -> tycon.AllInstanceFieldsAsList |> List.forall (fun r -> isUnmanagedTy g r.rfield_type) | _ -> false // generic structs are never else false - | None -> + | ValueNone -> false let isInterfaceTycon x = @@ -1788,8 +1820,8 @@ let isInterfaceTyconRef (tcref: TyconRef) = isInterfaceTycon tcref.Deref let isEnumTy g ty = match tryDestAppTy g ty with - | None -> false - | Some tcref -> tcref.IsEnumTycon + | ValueNone -> false + | ValueSome tcref -> tcref.IsEnumTycon let actualReturnTyOfSlotSig parentTyInst methTyInst (TSlotSig(_, _, parentFormalTypars, methFormalTypars, _, formalRetTy)) = let methTyInst = mkTyparInst methFormalTypars methTyInst @@ -2011,6 +2043,8 @@ and accFreeInTraitSln opts sln acc = accFreeInType opts ty (accFreeValRefInTraitSln opts vref (accFreeInTypes opts minst acc)) + | FSAnonRecdFieldSln(_anonInfo, tinst, _n) -> + accFreeInTypes opts tinst acc | FSRecdFieldSln(tinst, _rfref, _isSet) -> accFreeInTypes opts tinst acc | BuiltInSln -> acc @@ -2037,6 +2071,7 @@ and accFreeTyparRef opts (tp:Typar) acc = and accFreeInType opts ty acc = match stripTyparEqns ty with | TType_tuple (tupInfo, l) -> accFreeInTypes opts l (accFreeInTupInfo opts tupInfo acc) + | TType_anon (anonInfo, l) -> accFreeInTypes opts l (accFreeInTupInfo opts anonInfo.TupInfo acc) | TType_app (tc, tinst) -> let acc = accFreeTycon opts tc acc match tinst with @@ -2126,6 +2161,9 @@ and accFreeTyparRefLeftToRight g cxFlag thruFlag acc (tp:Typar) = and accFreeInTypeLeftToRight g cxFlag thruFlag acc ty = if verbose then dprintf "--> accFreeInTypeLeftToRight \n" match (if thruFlag then stripTyEqns g ty else stripTyparEqns ty) with + | TType_anon (anonInfo, l) -> + let acc = accFreeInTupInfoLeftToRight g cxFlag thruFlag acc anonInfo.TupInfo + accFreeInTypesLeftToRight g cxFlag thruFlag acc l | TType_tuple (tupInfo, l) -> let acc = accFreeInTupInfoLeftToRight g cxFlag thruFlag acc tupInfo accFreeInTypesLeftToRight g cxFlag thruFlag acc l @@ -2453,7 +2491,7 @@ module PrettyTypes = // Badly formed code may instantiate rigid declared typars to types. // Hence we double check here that the thing is really a type variable - let safeDestAnyParTy orig g ty = match tryAnyParTy g ty with None -> orig | Some x -> x + let safeDestAnyParTy orig g ty = match tryAnyParTy g ty with ValueNone -> orig | ValueSome x -> x let tee f x = f x x let foldUnurriedArgInfos f z (x: UncurriedArgInfos) = List.fold (fold1Of2 f) z x @@ -2518,8 +2556,9 @@ module SimplifyTypes = let z = f z ty match ty with | TType_forall (_, body) -> foldTypeButNotConstraints f z body - | TType_app (_, tinst) -> List.fold (foldTypeButNotConstraints f) z tinst - | TType_ucase (_, tinst) -> List.fold (foldTypeButNotConstraints f) z tinst + | TType_app (_, tys) + | TType_ucase (_, tys) + | TType_anon (_, tys) | TType_tuple (_, tys) -> List.fold (foldTypeButNotConstraints f) z tys | TType_fun (s, t) -> foldTypeButNotConstraints f (foldTypeButNotConstraints f z s) t | TType_var _ -> z @@ -2650,30 +2689,30 @@ let layoutOfPath p = let fullNameOfParentOfPubPath pp = match pp with - | PubPath([| _ |]) -> None - | pp -> Some(textOfPath pp.EnclosingPath) + | PubPath([| _ |]) -> ValueNone + | pp -> ValueSome(textOfPath pp.EnclosingPath) let fullNameOfParentOfPubPathAsLayout pp = match pp with - | PubPath([| _ |]) -> None - | pp -> Some(layoutOfPath (Array.toList pp.EnclosingPath)) + | PubPath([| _ |]) -> ValueNone + | pp -> ValueSome(layoutOfPath (Array.toList pp.EnclosingPath)) let fullNameOfPubPath (PubPath(p)) = textOfPath p let fullNameOfPubPathAsLayout (PubPath(p)) = layoutOfPath (Array.toList p) let fullNameOfParentOfNonLocalEntityRef (nlr: NonLocalEntityRef) = - if nlr.Path.Length < 2 then None - else Some (textOfPath nlr.EnclosingMangledPath) // <--- BAD BAD BAD: this is a mangled path. This is wrong for nested modules + if nlr.Path.Length < 2 then ValueNone + else ValueSome (textOfPath nlr.EnclosingMangledPath) // <--- BAD BAD BAD: this is a mangled path. This is wrong for nested modules let fullNameOfParentOfNonLocalEntityRefAsLayout (nlr: NonLocalEntityRef) = - if nlr.Path.Length < 2 then None - else Some (layoutOfPath (List.ofArray nlr.EnclosingMangledPath)) // <--- BAD BAD BAD: this is a mangled path. This is wrong for nested modules + if nlr.Path.Length < 2 then ValueNone + else ValueSome (layoutOfPath (List.ofArray nlr.EnclosingMangledPath)) // <--- BAD BAD BAD: this is a mangled path. This is wrong for nested modules let fullNameOfParentOfEntityRef eref = match eref with | ERefLocal x -> match x.PublicPath with - | None -> None + | None -> ValueNone | Some ppath -> fullNameOfParentOfPubPath ppath | ERefNonLocal nlr -> fullNameOfParentOfNonLocalEntityRef nlr @@ -2681,14 +2720,14 @@ let fullNameOfParentOfEntityRefAsLayout eref = match eref with | ERefLocal x -> match x.PublicPath with - | None -> None + | None -> ValueNone | Some ppath -> fullNameOfParentOfPubPathAsLayout ppath | ERefNonLocal nlr -> fullNameOfParentOfNonLocalEntityRefAsLayout nlr let fullNameOfEntityRef nmF xref = - match fullNameOfParentOfEntityRef xref with - | None -> nmF xref - | Some pathText -> pathText +.+ nmF xref + match fullNameOfParentOfEntityRef xref with + | ValueNone -> nmF xref + | ValueSome pathText -> pathText +.+ nmF xref let tagEntityRefName (xref: EntityRef) name = if xref.IsNamespace then tagNamespace name @@ -2710,26 +2749,26 @@ let fullNameOfEntityRefAsLayout nmF (xref: EntityRef) = |> mkNav xref.DefinitionRange |> wordL match fullNameOfParentOfEntityRefAsLayout xref with - | None -> navigableText - | Some pathText -> pathText ^^ SepL.dot ^^ navigableText + | ValueNone -> navigableText + | ValueSome pathText -> pathText ^^ SepL.dot ^^ navigableText let fullNameOfParentOfValRef vref = match vref with | VRefLocal x -> match x.PublicPath with - | None -> None - | Some (ValPubPath(pp, _)) -> Some(fullNameOfPubPath pp) + | None -> ValueNone + | Some (ValPubPath(pp, _)) -> ValueSome(fullNameOfPubPath pp) | VRefNonLocal nlr -> - Some (fullNameOfEntityRef (fun (x:EntityRef) -> x.DemangledModuleOrNamespaceName) nlr.EnclosingEntity) + ValueSome (fullNameOfEntityRef (fun (x:EntityRef) -> x.DemangledModuleOrNamespaceName) nlr.EnclosingEntity) let fullNameOfParentOfValRefAsLayout vref = match vref with | VRefLocal x -> match x.PublicPath with - | None -> None - | Some (ValPubPath(pp, _)) -> Some(fullNameOfPubPathAsLayout pp) + | None -> ValueNone + | Some (ValPubPath(pp, _)) -> ValueSome(fullNameOfPubPathAsLayout pp) | VRefNonLocal nlr -> - Some (fullNameOfEntityRefAsLayout (fun (x:EntityRef) -> x.DemangledModuleOrNamespaceName) nlr.EnclosingEntity) + ValueSome (fullNameOfEntityRefAsLayout (fun (x:EntityRef) -> x.DemangledModuleOrNamespaceName) nlr.EnclosingEntity) let fullDisplayTextOfParentOfModRef r = fullNameOfParentOfEntityRef r @@ -2742,12 +2781,12 @@ let fullDisplayTextOfExnRefAsLayout r = fullNameOfEntityRefAsLayout (fun (tc:Ty let fullDisplayTextOfUnionCaseRef (ucref:UnionCaseRef) = fullDisplayTextOfTyconRef ucref.TyconRef +.+ ucref.CaseName let fullDisplayTextOfRecdFieldRef (rfref:RecdFieldRef) = fullDisplayTextOfTyconRef rfref.TyconRef +.+ rfref.FieldName -let fullDisplayTextOfValRef (vref:ValRef) = +let fullDisplayTextOfValRef (vref:ValRef) = match fullNameOfParentOfValRef vref with - | None -> vref.DisplayName - | Some pathText -> pathText +.+ vref.DisplayName + | ValueNone -> vref.DisplayName + | ValueSome pathText -> pathText +.+ vref.DisplayName -let fullDisplayTextOfValRefAsLayout (vref:ValRef) = +let fullDisplayTextOfValRefAsLayout (vref:ValRef) = let n = match vref.MemberInfo with | None -> @@ -2762,8 +2801,8 @@ let fullDisplayTextOfValRefAsLayout (vref:ValRef) = | MemberKind.Constructor -> tagMethod vref.DisplayName | MemberKind.Member -> tagMember vref.DisplayName match fullNameOfParentOfValRefAsLayout vref with - | None -> wordL n - | Some pathText -> + | ValueNone -> wordL n + | ValueSome pathText -> pathText ^^ SepL.dot ^^ wordL n //pathText +.+ vref.DisplayName @@ -2988,8 +3027,8 @@ let destNativePtrTy g ty = let isRefCellTy g ty = match tryDestAppTy g ty with - | None -> false - | Some tcref -> tyconRefEq g g.refcell_tcr_canon tcref + | ValueNone -> false + | ValueSome tcref -> tyconRefEq g g.refcell_tcr_canon tcref let destRefCellTy g ty = match ty |> stripTyEqns g with @@ -3013,23 +3052,23 @@ let mkListTy (g:TcGlobals) ty = TType_app (g.list_tcr_nice, [ty]) let isOptionTy (g:TcGlobals) ty = match tryDestAppTy g ty with - | None -> false - | Some tcref -> tyconRefEq g g.option_tcr_canon tcref + | ValueNone -> false + | ValueSome tcref -> tyconRefEq g g.option_tcr_canon tcref let tryDestOptionTy g ty = match argsOfAppTy g ty with - | [ty1] when isOptionTy g ty -> Some ty1 - | _ -> None + | [ty1] when isOptionTy g ty -> ValueSome ty1 + | _ -> ValueNone let destOptionTy g ty = match tryDestOptionTy g ty with - | Some ty -> ty - | None -> failwith "destOptionTy: not an option type" + | ValueSome ty -> ty + | ValueNone -> failwith "destOptionTy: not an option type" let isLinqExpressionTy g ty = match tryDestAppTy g ty with - | None -> false - | Some tcref -> tyconRefEq g g.system_LinqExpression_tcref tcref + | ValueNone -> false + | ValueSome tcref -> tyconRefEq g g.system_LinqExpression_tcref tcref let tryDestLinqExpressionTy g ty = match argsOfAppTy g ty with @@ -3142,6 +3181,7 @@ module DebugPrint = begin let squareAngleL x = LeftL.leftBracketAngle ^^ x ^^ RightL.rightBracketAngle let angleL x = sepL Literals.leftAngle ^^ x ^^ rightL Literals.rightAngle let braceL x = leftL Literals.leftBrace ^^ x ^^ rightL Literals.rightBrace + let braceBarL x = leftL Literals.leftBraceBar ^^ x ^^ rightL Literals.rightBraceBar let boolL = function true -> WordL.keywordTrue | false -> WordL.keywordFalse let intL (n:int) = wordL (tagNumericLiteral (string n )) @@ -3203,6 +3243,7 @@ module DebugPrint = begin let prefix = tcref.IsPrefixDisplay let tcL = layoutTyconRef tcref auxTyparsL env tcL prefix tinst + | TType_anon (anonInfo, tys) -> braceBarL (sepListL (wordL (tagText ";")) (List.map2 (fun nm ty -> wordL (tagField nm) --- auxTypeAtomL env ty) (Array.toList anonInfo.SortedNames) tys)) | TType_tuple (_tupInfo, tys) -> sepListL (wordL (tagText "*")) (List.map (auxTypeAtomL env) tys) |> wrap | TType_fun (f, x) -> ((auxTypeAtomL env f ^^ wordL (tagText "->")) --- auxTypeL env x) |> wrap | TType_var typar -> auxTyparWrapL env isAtomic typar @@ -3401,7 +3442,7 @@ module DebugPrint = begin let rec MemberL (v:Val) (membInfo:ValMemberInfo) = (aboveListL [ wordL(tagText "compiled_name! = ") ^^ wordL (tagText v.CompiledName) ; wordL(tagText "membInfo-slotsig! = ") ^^ listL slotSigL membInfo.ImplementedSlotSigs ]) - and vspecAtBindL v = + and valAtBindL v = let vL = valL v in let mutL = (if v.IsMutable then wordL(tagText "mutable") ++ vL else vL) mutL --- (aboveListL (List.concat [[wordL(tagText ":") ^^ typeL v.Type]; @@ -3471,7 +3512,7 @@ module DebugPrint = begin then emptyL else let iimplsLs = iimpls |> List.map (fun (ty, _, _) -> wordL(tagText "interface") --- typeL ty) - let adhocLs = adhoc |> List.map (fun vref -> vspecAtBindL vref.Deref) + let adhocLs = adhoc |> List.map (fun vref -> valAtBindL vref.Deref) (wordL(tagText "with") @@-- aboveListL (iimplsLs @ adhocLs)) @@ wordL(tagText "end") let layoutUnionCaseArgTypes argtys = sepListL (wordL(tagText "*")) (List.map typeL argtys) @@ -3518,7 +3559,7 @@ module DebugPrint = begin let vsprs = tycon.MembersOfFSharpTyconSorted |> List.filter (fun v -> v.IsDispatchSlot) - |> List.map (fun vref -> vspecAtBindL vref.Deref) + |> List.map (fun vref -> valAtBindL vref.Deref) let vals = tycon.TrueFieldsAsList |> List.map (fun f -> (if f.IsStatic then wordL(tagText "static") else emptyL) ^^ wordL(tagText "val") ^^ layoutRecdField f) let alldecls = inherits @ vsprs @ vals let emptyMeasure = match tycon.TypeOrMeasureKind with TyparKind.Measure -> isNil alldecls | _ -> false @@ -3549,7 +3590,7 @@ module DebugPrint = begin //-------------------------------------------------------------------------- and bindingL (TBind(v, repr, _)) = - vspecAtBindL v --- (wordL(tagText "=") ^^ exprL repr) + valAtBindL v --- (wordL(tagText "=") ^^ exprL repr) and exprL expr = exprWrapL false expr and atomL expr = exprWrapL true expr // true means bracket if needed to be atomic expr @@ -3587,11 +3628,11 @@ module DebugPrint = begin | ThenDoSeq -> "; (*ThenDo*)" ((exprL x0 ^^ rightL (tagText flag)) @@ exprL x1) |> wrap | Expr.Lambda(_, _, baseValOpt, argvs, body, _, _) -> - let formalsL = spaceListL (List.map vspecAtBindL argvs) in + let formalsL = spaceListL (List.map valAtBindL argvs) in let bindingL = match baseValOpt with | None -> wordL(tagText "lam") ^^ formalsL ^^ rightL(tagText ".") - | Some basev -> wordL(tagText "lam") ^^ (leftL(tagText "base=") ^^ vspecAtBindL basev) --- formalsL ^^ rightL(tagText ".") in + | Some basev -> wordL(tagText "lam") ^^ (leftL(tagText "base=") ^^ valAtBindL basev) --- formalsL ^^ rightL(tagText ".") in (bindingL ++ exprL body) |> wrap | Expr.TyLambda(_, argtyvs, body, _, _) -> ((wordL(tagText "LAM") ^^ spaceListL (List.map typarL argtyvs) ^^ rightL(tagText ".")) ++ exprL body) |> wrap @@ -3686,7 +3727,7 @@ module DebugPrint = begin | Expr.Obj (_lambdaId, ty, basev, ccall, overrides, iimpls, _) -> wordL(tagText "OBJ:") ^^ aboveListL [typeL ty; exprL ccall; - optionL vspecAtBindL basev; + optionL valAtBindL basev; aboveListL (List.map overrideL overrides); aboveListL (List.map iimplL iimpls)] @@ -3708,8 +3749,8 @@ module DebugPrint = begin let z = z --- sepL(tagText "`") --- (spaceListL (List.map atomL args)) z - and implFileL (TImplFile(_, _, e, _, _)) = - aboveListL [(wordL(tagText "top implementation ")) @@-- mexprL e] + and implFileL (TImplFile(_, _, mexpr, _, _, _)) = + aboveListL [(wordL(tagText "top implementation ")) @@-- mexprL mexpr] and mexprL x = match x with @@ -3771,7 +3812,7 @@ module DebugPrint = begin and tmethodL (TObjExprMethod(TSlotSig(nm, _, _, _, _, _), _, tps, vs, e, _)) = (wordL(tagText "TObjExprMethod") --- (wordL (tagText nm)) ^^ wordL(tagText "=")) -- (wordL(tagText "METH-LAM") --- angleBracketListL (List.map typarL tps) ^^ rightL(tagText ".")) --- - (wordL(tagText "meth-lam") --- tupleL (List.map (List.map vspecAtBindL >> tupleL) vs) ^^ rightL(tagText ".")) --- + (wordL(tagText "meth-lam") --- tupleL (List.map (List.map valAtBindL >> tupleL) vs) ^^ rightL(tagText ".")) --- (atomL e) and overrideL tmeth = wordL(tagText "with") ^^ tmethodL tmeth and iimplL (ty, tmeths) = wordL(tagText "impl") ^^ aboveListL (typeL ty :: List.map tmethodL tmeths) @@ -3800,7 +3841,7 @@ let wrapModuleOrNamespaceExprInNamespace (id :Ident) cpath mexpr = TMDefRec (false, [], [ModuleOrNamespaceBinding.Module(mspec, mexpr)], id.idRange) // cleanup: make this a property -let SigTypeOfImplFile (TImplFile(_, _, mexpr, _, _)) = mexpr.Type +let SigTypeOfImplFile (TImplFile(_, _, mexpr, _, _, _)) = mexpr.Type //-------------------------------------------------------------------------- @@ -3809,33 +3850,33 @@ let SigTypeOfImplFile (TImplFile(_, _, mexpr, _, _)) = mexpr.Type //-------------------------------------------------------------------------- type SignatureRepackageInfo = - { mrpiVals : (ValRef * ValRef) list; - mrpiEntities: (TyconRef * TyconRef) list } + { RepackagedVals : (ValRef * ValRef) list; + RepackagedEntities: (TyconRef * TyconRef) list } - member remapInfo.ImplToSigMapping = { TypeEquivEnv.Empty with EquivTycons = TyconRefMap.OfList remapInfo.mrpiEntities } - static member Empty = { mrpiVals = []; mrpiEntities= [] } + member remapInfo.ImplToSigMapping = { TypeEquivEnv.Empty with EquivTycons = TyconRefMap.OfList remapInfo.RepackagedEntities } + static member Empty = { RepackagedVals = []; RepackagedEntities= [] } type SignatureHidingInfo = - { mhiTycons : Zset; - mhiTyconReprs : Zset; - mhiVals : Zset; - mhiRecdFields : Zset; - mhiUnionCases : Zset } + { HiddenTycons : Zset; + HiddenTyconReprs : Zset; + HiddenVals : Zset; + HiddenRecdFields : Zset; + HiddenUnionCases : Zset } static member Empty = - { mhiTycons = Zset.empty tyconOrder; - mhiTyconReprs = Zset.empty tyconOrder; - mhiVals = Zset.empty valOrder; - mhiRecdFields = Zset.empty recdFieldRefOrder; - mhiUnionCases = Zset.empty unionCaseRefOrder } + { HiddenTycons = Zset.empty tyconOrder; + HiddenTyconReprs = Zset.empty tyconOrder; + HiddenVals = Zset.empty valOrder; + HiddenRecdFields = Zset.empty recdFieldRefOrder; + HiddenUnionCases = Zset.empty unionCaseRefOrder } let addValRemap v v' tmenv = { tmenv with valRemap= tmenv.valRemap.Add v (mkLocalValRef v') } let mkRepackageRemapping mrpi = - { valRemap = ValMap.OfList (mrpi.mrpiVals |> List.map (fun (vref, x) -> vref.Deref, x)); + { valRemap = ValMap.OfList (mrpi.RepackagedVals |> List.map (fun (vref, x) -> vref.Deref, x)); tpinst = emptyTyparInst; - tyconRefRemap = TyconRefMap.OfList mrpi.mrpiEntities + tyconRefRemap = TyconRefMap.OfList mrpi.RepackagedEntities removeTraitSolutions = false } //-------------------------------------------------------------------------- @@ -3847,18 +3888,18 @@ let accEntityRemap (msigty:ModuleOrNamespaceType) (entity:Entity) (mrpi, mhi) = match sigtyconOpt with | None -> // The type constructor is not present in the signature. Hence it is hidden. - let mhi = { mhi with mhiTycons = Zset.add entity mhi.mhiTycons } + let mhi = { mhi with HiddenTycons = Zset.add entity mhi.HiddenTycons } (mrpi, mhi) | Some sigtycon -> // The type constructor is in the signature. Hence record the repackage entry let sigtcref = mkLocalTyconRef sigtycon let tcref = mkLocalTyconRef entity - let mrpi = { mrpi with mrpiEntities = ((tcref, sigtcref) :: mrpi.mrpiEntities) } + let mrpi = { mrpi with RepackagedEntities = ((tcref, sigtcref) :: mrpi.RepackagedEntities) } // OK, now look for hidden things let mhi = if (match entity.TypeReprInfo with TNoRepr -> false | _ -> true) && (match sigtycon.TypeReprInfo with TNoRepr -> true | _ -> false) then // The type representation is absent in the signature, hence it is hidden - { mhi with mhiTyconReprs = Zset.add entity mhi.mhiTyconReprs } + { mhi with HiddenTyconReprs = Zset.add entity mhi.HiddenTyconReprs } else // The type representation is present in the signature. // Find the fields that have been hidden or which were non-public anyway. @@ -3871,7 +3912,7 @@ let accEntityRemap (msigty:ModuleOrNamespaceType) (entity:Entity) (mrpi, mhi) = | _ -> // The field is not in the signature. Hence it is regarded as hidden. let rfref = tcref.MakeNestedRecdFieldRef rfield - { mhi with mhiRecdFields = Zset.add rfref mhi.mhiRecdFields }) + { mhi with HiddenRecdFields = Zset.add rfref mhi.HiddenRecdFields }) entity.AllFieldsArray |> List.foldBack (fun (ucase:UnionCase) mhi -> match sigtycon.GetUnionCaseByName ucase.DisplayName with @@ -3881,7 +3922,7 @@ let accEntityRemap (msigty:ModuleOrNamespaceType) (entity:Entity) (mrpi, mhi) = | _ -> // The constructor is not in the signature. Hence it is regarded as hidden. let ucref = tcref.MakeNestedUnionCaseRef ucase - { mhi with mhiUnionCases = Zset.add ucref mhi.mhiUnionCases }) + { mhi with HiddenUnionCases = Zset.add ucref mhi.HiddenUnionCases }) (entity.UnionCasesAsList) (mrpi, mhi) @@ -3890,13 +3931,13 @@ let accSubEntityRemap (msigty:ModuleOrNamespaceType) (entity:Entity) (mrpi, mhi) match sigtyconOpt with | None -> // The type constructor is not present in the signature. Hence it is hidden. - let mhi = { mhi with mhiTycons = Zset.add entity mhi.mhiTycons } + let mhi = { mhi with HiddenTycons = Zset.add entity mhi.HiddenTycons } (mrpi, mhi) | Some sigtycon -> // The type constructor is in the signature. Hence record the repackage entry let sigtcref = mkLocalTyconRef sigtycon let tcref = mkLocalTyconRef entity - let mrpi = { mrpi with mrpiEntities = ((tcref, sigtcref) :: mrpi.mrpiEntities) } + let mrpi = { mrpi with RepackagedEntities = ((tcref, sigtcref) :: mrpi.RepackagedEntities) } (mrpi, mhi) let valLinkageAEquiv g aenv (v1:Val) (v2:Val) = @@ -3914,11 +3955,11 @@ let accValRemap g aenv (msigty:ModuleOrNamespaceType) (implVal:Val) (mrpi, mhi) match sigValOpt with | None -> if verbose then dprintf "accValRemap, hide = %s#%d\n" implVal.LogicalName implVal.Stamp - let mhi = { mhi with mhiVals = Zset.add implVal mhi.mhiVals } + let mhi = { mhi with HiddenVals = Zset.add implVal mhi.HiddenVals } (mrpi, mhi) | Some (sigVal:Val) -> // The value is in the signature. Add the repackage entry. - let mrpi = { mrpi with mrpiVals = (vref, mkLocalValRef sigVal) :: mrpi.mrpiVals } + let mrpi = { mrpi with RepackagedVals = (vref, mkLocalValRef sigVal) :: mrpi.RepackagedVals } (mrpi, mhi) let getCorrespondingSigTy nm (msigty:ModuleOrNamespaceType) = @@ -4012,9 +4053,9 @@ let ComputeRemappingFromImplementationToSignature g mdef msigty = let accTyconHidingInfoAtAssemblyBoundary (tycon:Tycon) mhi = if not (canAccessFromEverywhere tycon.Accessibility) then // The type constructor is not public, hence hidden at the assembly boundary. - { mhi with mhiTycons = Zset.add tycon mhi.mhiTycons } + { mhi with HiddenTycons = Zset.add tycon mhi.HiddenTycons } elif not (canAccessFromEverywhere tycon.TypeReprAccessibility) then - { mhi with mhiTyconReprs = Zset.add tycon mhi.mhiTyconReprs } + { mhi with HiddenTyconReprs = Zset.add tycon mhi.HiddenTyconReprs } else mhi |> Array.foldBack @@ -4022,7 +4063,7 @@ let accTyconHidingInfoAtAssemblyBoundary (tycon:Tycon) mhi = if not (canAccessFromEverywhere rfield.Accessibility) then let tcref = mkLocalTyconRef tycon let rfref = tcref.MakeNestedRecdFieldRef rfield - { mhi with mhiRecdFields = Zset.add rfref mhi.mhiRecdFields } + { mhi with HiddenRecdFields = Zset.add rfref mhi.HiddenRecdFields } else mhi) tycon.AllFieldsArray |> List.foldBack @@ -4030,7 +4071,7 @@ let accTyconHidingInfoAtAssemblyBoundary (tycon:Tycon) mhi = if not (canAccessFromEverywhere ucase.Accessibility) then let tcref = mkLocalTyconRef tycon let ucref = tcref.MakeNestedUnionCaseRef ucase - { mhi with mhiUnionCases = Zset.add ucref mhi.mhiUnionCases } + { mhi with HiddenUnionCases = Zset.add ucref mhi.HiddenUnionCases } else mhi) (tycon.UnionCasesAsList) @@ -4045,7 +4086,7 @@ let accValHidingInfoAtAssemblyBoundary (vspec:Val) mhi = // anything that's not a module or member binding gets assembly visibility not vspec.IsMemberOrModuleBinding then // The value is not public, hence hidden at the assembly boundary. - { mhi with mhiVals = Zset.add vspec mhi.mhiVals } + { mhi with HiddenVals = Zset.add vspec mhi.HiddenVals } else mhi @@ -4080,10 +4121,10 @@ let IsHidden setF accessF remapF debugF = if verbose then dprintf "IsHidden, #mrmi = %d, %s = %b\n" mrmi.Length (showL (debugF x)) res; res -let IsHiddenTycon mrmi x = IsHidden (fun mhi -> mhi.mhiTycons) (fun tc -> tc.Accessibility) (fun rpi x -> (remapTyconRef rpi.tyconRefRemap (mkLocalTyconRef x)).Deref) DebugPrint.tyconL mrmi x -let IsHiddenTyconRepr mrmi x = IsHidden (fun mhi -> mhi.mhiTyconReprs) (fun v -> v.TypeReprAccessibility) (fun rpi x -> (remapTyconRef rpi.tyconRefRemap (mkLocalTyconRef x)).Deref) DebugPrint.tyconL mrmi x -let IsHiddenVal mrmi x = IsHidden (fun mhi -> mhi.mhiVals) (fun v -> v.Accessibility) (fun rpi x -> (remapValRef rpi (mkLocalValRef x)).Deref) DebugPrint.valL mrmi x -let IsHiddenRecdField mrmi x = IsHidden (fun mhi -> mhi.mhiRecdFields) (fun rfref -> rfref.RecdField.Accessibility) (fun rpi x -> remapRecdFieldRef rpi.tyconRefRemap x) DebugPrint.recdFieldRefL mrmi x +let IsHiddenTycon mrmi x = IsHidden (fun mhi -> mhi.HiddenTycons) (fun tc -> tc.Accessibility) (fun rpi x -> (remapTyconRef rpi.tyconRefRemap (mkLocalTyconRef x)).Deref) DebugPrint.tyconL mrmi x +let IsHiddenTyconRepr mrmi x = IsHidden (fun mhi -> mhi.HiddenTyconReprs) (fun v -> v.TypeReprAccessibility) (fun rpi x -> (remapTyconRef rpi.tyconRefRemap (mkLocalTyconRef x)).Deref) DebugPrint.tyconL mrmi x +let IsHiddenVal mrmi x = IsHidden (fun mhi -> mhi.HiddenVals) (fun v -> v.Accessibility) (fun rpi x -> (remapValRef rpi (mkLocalValRef x)).Deref) DebugPrint.valL mrmi x +let IsHiddenRecdField mrmi x = IsHidden (fun mhi -> mhi.HiddenRecdFields) (fun rfref -> rfref.RecdField.Accessibility) (fun rpi x -> remapRecdFieldRef rpi.tyconRefRemap x) DebugPrint.recdFieldRefL mrmi x //-------------------------------------------------------------------------- @@ -4404,7 +4445,9 @@ and accFreeInOp opts op acc = | TOp.Goto _ | TOp.Label _ | TOp.Return | TOp.TupleFieldGet _ -> acc - | TOp.Tuple tupInfo -> accFreeTyvars opts accFreeInTupInfo tupInfo acc + | TOp.Tuple tupInfo -> accFreeTyvars opts accFreeInTupInfo tupInfo acc + | TOp.AnonRecd anonInfo + | TOp.AnonRecdGet (anonInfo, _) -> accFreeTyvars opts accFreeInTupInfo anonInfo.TupInfo acc | TOp.UnionCaseTagGet tr -> accUsedRecdOrUnionTyconRepr opts tr.Deref acc @@ -4659,8 +4702,8 @@ let decideStaticOptimizationConstraint g c = | TTyconIsStruct a -> let a = normalizeEnumTy g (stripTyEqnsAndMeasureEqns g a) match tryDestAppTy g a with - | Some tcref1 -> if tcref1.IsStructOrEnumTycon then StaticOptimizationAnswer.Yes else StaticOptimizationAnswer.No - | None -> StaticOptimizationAnswer.Unknown + | ValueSome tcref1 -> if tcref1.IsStructOrEnumTycon then StaticOptimizationAnswer.Yes else StaticOptimizationAnswer.No + | ValueNone -> StaticOptimizationAnswer.Unknown let rec DecideStaticOptimizations g cs = match cs with @@ -5369,8 +5412,8 @@ let ComputeFieldName tycon f = // Helpers for building code contained in the initial environment //------------------------------------------------------------------------- -let isQuotedExprTy g ty = match ty with AppTy g (tcref, _) -> tyconRefEq g tcref g.expr_tcr | _ -> false -let destQuotedExprTy g ty = match ty with AppTy g (_, [ty]) -> ty | _ -> failwith "destQuotedExprTy" +let isQuotedExprTy g ty = match tryAppTy g ty with ValueSome (tcref, _) -> tyconRefEq g tcref g.expr_tcr | _ -> false +let destQuotedExprTy g ty = match tryAppTy g ty with ValueSome (_, [ty]) -> ty | _ -> failwith "destQuotedExprTy" let mkQuotedExprTy (g:TcGlobals) ty = TType_app(g.expr_tcr, [ty]) let mkRawQuotedExprTy (g:TcGlobals) = TType_app(g.raw_expr_tcr, []) @@ -5381,6 +5424,9 @@ let mkAnyTupledTy (g:TcGlobals) tupInfo tys = | [h] -> h | _ -> TType_tuple(tupInfo, tys) +let mkAnyAnonRecdTy (_g:TcGlobals) anonInfo tys = + TType_anon(anonInfo, tys) + let mkRefTupledTy g tys = mkAnyTupledTy g tupInfoRef tys let mkRefTupledVarsTy g vs = mkRefTupledTy g (typesOfVals vs) @@ -5419,8 +5465,10 @@ let rec tyOfExpr g e = | TOp.ExnConstr _ -> g.exn_ty | TOp.Bytes _ -> mkByteArrayTy g | TOp.UInt16s _ -> mkArrayType g g.uint16_ty + | TOp.AnonRecdGet(_, i) -> List.item i tinst | TOp.TupleFieldGet(_, i) -> List.item i tinst | TOp.Tuple tupInfo -> mkAnyTupledTy g tupInfo tinst + | TOp.AnonRecd anonInfo -> mkAnyAnonRecdTy g anonInfo tinst | (TOp.For _ | TOp.While _) -> g.unit_ty | TOp.Array -> (match tinst with [ty] -> mkArrayType g ty | _ -> failwith "bad TOp.Array node") | (TOp.TryCatch _ | TOp.TryFinally _) -> (match tinst with [ty] -> ty | _ -> failwith "bad TOp_try node") @@ -5680,8 +5728,8 @@ let isRecdOrStructTyconRefReadOnly (g: TcGlobals) m (tcref: TyconRef) = let isRecdOrStructTyReadOnly (g: TcGlobals) m ty = match tryDestAppTy g ty with - | None -> false - | Some tcref -> isRecdOrStructTyconRefReadOnly g m tcref + | ValueNone -> false + | ValueSome tcref -> isRecdOrStructTyconRefReadOnly g m tcref let CanTakeAddressOf g m ty mut = @@ -5863,16 +5911,23 @@ let rec mkExprAddrOfExprAux g mustTakeAddress useReadonlyForGenericArrayAddress let ty = tyOfExpr g expr if isStructTy g ty then match mut with - | NeverMutates -> () - | AddressOfOp -> - // we get an inref - errorR(Error(FSComp.SR.tastCantTakeAddressOfExpression(), m)) + | NeverMutates + | AddressOfOp -> () | DefinitelyMutates -> // Give a nice error message for mutating something we can't take the address of errorR(Error(FSComp.SR.tastInvalidMutationOfConstant(), m)) | PossiblyMutates -> // Warn on defensive copy of something we can't take the address of warning(DefensiveCopyWarning(FSComp.SR.tastValueHasBeenCopied(), m)) + + match mut with + | NeverMutates + | DefinitelyMutates + | PossiblyMutates -> () + | AddressOfOp -> + // we get an inref + errorR(Error(FSComp.SR.tastCantTakeAddressOfExpression(), m)) + // Take a defensive copy let tmp, _ = match mut with @@ -5894,6 +5949,10 @@ let mkTupleFieldGet g (tupInfo, e, tinst, i, m) = let wrap, e', _readonly, _writeonly = mkExprAddrOfExpr g (evalTupInfoIsStruct tupInfo) false NeverMutates e None m wrap (mkTupleFieldGetViaExprAddr(tupInfo, e', tinst, i, m)) +let mkAnonRecdFieldGet g (anonInfo:AnonRecdTypeInfo, e, tinst, i, m) = + let wrap, e', _readonly, _writeonly = mkExprAddrOfExpr g (evalAnonInfoIsStruct anonInfo) false NeverMutates e None m + wrap (mkAnonRecdFieldGetViaExprAddr(anonInfo, e', tinst, i, m)) + let mkRecdFieldGet g (e, fref:RecdFieldRef, tinst, m) = assert (not (isByrefTy g (tyOfExpr g e))) let wrap, e', _readonly, _writeonly = mkExprAddrOfExpr g fref.Tycon.IsStructOrEnumTycon false NeverMutates e None m @@ -6167,7 +6226,7 @@ let mkMinusOne g m = mkInt g m (-1) let destInt32 = function Expr.Const(Const.Int32 n, _, _) -> Some n | _ -> None -let isIDelegateEventType g ty = isAppTy g ty && tyconRefEq g g.fslib_IDelegateEvent_tcr (tcrefOfAppTy g ty) +let isIDelegateEventType g ty = match tryDestAppTy g ty with ValueSome tcref -> tyconRefEq g g.fslib_IDelegateEvent_tcr tcref | _ -> false let destIDelegateEventType g ty = if isIDelegateEventType g ty then match argsOfAppTy g ty with @@ -6205,6 +6264,9 @@ let mkRefTupled g m es tys = mkAnyTupled g m tupInfoRef es tys let mkRefTupledNoTypes g m args = mkRefTupled g m args (List.map (tyOfExpr g) args) let mkRefTupledVars g m vs = mkRefTupled g m (List.map (exprForVal m) vs) (typesOfVals vs) +let mkAnonRecd (_g:TcGlobals) m anonInfo es tys = Expr.Op (TOp.AnonRecd (anonInfo),tys,es,m) + + //-------------------------------------------------------------------------- // Permute expressions //-------------------------------------------------------------------------- @@ -6260,11 +6322,6 @@ let permuteExprList (sigma:int[]) (exprs: Expr list) (ty: TType list) (names:str let reorderedExprs = permute sigma (Array.ofList newExprs) binds, Array.toList reorderedExprs -//------------------------------------------------------------------------- -// Build record expressions... -//------------------------------------------------------------------------- - - /// Evaluate the expressions in the original order, but build a record with the results in field order /// Note some fields may be static. If this were not the case we could just use /// let sigma = Array.map #Index () @@ -6316,6 +6373,18 @@ let mkIsInst ty e m = mkAsmExpr ([ isinst ], [ty], [e], [ ty ], m) let mspec_Type_GetTypeFromHandle (g: TcGlobals) = IL.mkILNonGenericStaticMethSpecInTy(g.ilg.typ_Type, "GetTypeFromHandle", [g.iltyp_RuntimeTypeHandle], g.ilg.typ_Type) let mspec_String_Length (g: TcGlobals) = mkILNonGenericInstanceMethSpecInTy (g.ilg.typ_String, "get_Length", [], g.ilg.typ_Int32) +let mspec_String_Concat2 (g: TcGlobals) = + mkILNonGenericStaticMethSpecInTy (g.ilg.typ_String, "Concat", [ g.ilg.typ_String; g.ilg.typ_String ], g.ilg.typ_String) + +let mspec_String_Concat3 (g: TcGlobals) = + mkILNonGenericStaticMethSpecInTy (g.ilg.typ_String, "Concat", [ g.ilg.typ_String; g.ilg.typ_String; g.ilg.typ_String ], g.ilg.typ_String) + +let mspec_String_Concat4 (g: TcGlobals) = + mkILNonGenericStaticMethSpecInTy (g.ilg.typ_String, "Concat", [ g.ilg.typ_String; g.ilg.typ_String; g.ilg.typ_String; g.ilg.typ_String ], g.ilg.typ_String) + +let mspec_String_Concat_Array (g: TcGlobals) = + mkILNonGenericStaticMethSpecInTy (g.ilg.typ_String, "Concat", [ mkILArr1DTy g.ilg.typ_String ], g.ilg.typ_String) + let fspec_Missing_Value (g: TcGlobals) = IL.mkILFieldSpecInTy(g.iltyp_Missing, "Value", g.iltyp_Missing) let mkInitializeArrayMethSpec (g: TcGlobals) = @@ -6537,6 +6606,21 @@ let mkGetStringLength g m e = /// ILCall(useCallvirt, isProtected, valu, newobj, valUseFlags, isProp, noTailCall, mref, actualTypeInst, actualMethInst, retTy) Expr.Op(TOp.ILCall(false, false, false, false, ValUseFlag.NormalValUse, true, false, mspec.MethodRef, [], [], [g.int32_ty]), [], [e], m) +let mkStaticCall_String_Concat2 g m arg1 arg2 = + let mspec = mspec_String_Concat2 g + Expr.Op(TOp.ILCall(false, false, false, false, ValUseFlag.NormalValUse, false, false, mspec.MethodRef, [], [], [g.string_ty]), [], [arg1; arg2], m) + +let mkStaticCall_String_Concat3 g m arg1 arg2 arg3 = + let mspec = mspec_String_Concat3 g + Expr.Op(TOp.ILCall(false, false, false, false, ValUseFlag.NormalValUse, false, false, mspec.MethodRef, [], [], [g.string_ty]), [], [arg1; arg2; arg3], m) + +let mkStaticCall_String_Concat4 g m arg1 arg2 arg3 arg4 = + let mspec = mspec_String_Concat4 g + Expr.Op(TOp.ILCall(false, false, false, false, ValUseFlag.NormalValUse, false, false, mspec.MethodRef, [], [], [g.string_ty]), [], [arg1; arg2; arg3; arg4], m) + +let mkStaticCall_String_Concat_Array g m arg = + let mspec = mspec_String_Concat_Array g + Expr.Op(TOp.ILCall(false, false, false, false, ValUseFlag.NormalValUse, false, false, mspec.MethodRef, [], [], [g.string_ty]), [], [arg], m) // Quotations can't contain any IL. // As a result, we aim to get rid of all IL generation in the typechecker and pattern match @@ -7295,6 +7379,7 @@ let rec typeEnc g (gtpsType, gtpsMethod) ty = match stripped with | TType_forall _ -> "Microsoft.FSharp.Core.FSharpTypeFunc" + | _ when isArrayTy g ty -> let tcref, tinst = destAppTy g ty let arraySuffix = @@ -7310,6 +7395,7 @@ let rec typeEnc g (gtpsType, gtpsMethod) ty = | 4 -> "[0:, 0:, 0:, 0:]" | _ -> failwith "impossible: rankOfArrayTyconRef: unsupported array rank" typeEnc g (gtpsType, gtpsMethod) (List.head tinst) + arraySuffix + | TType_ucase (UCRef(tcref, _), tinst) | TType_app (tcref, tinst) -> if tyconRefEq g g.byref_tcr tcref then @@ -7327,15 +7413,22 @@ let rec typeEnc g (gtpsType, gtpsMethod) ty = textOfPath (List.map DemangleGenericTypeName path) | _ -> assert(false); failwith "impossible" tyName + tyargsEnc g (gtpsType, gtpsMethod) tinst + + | TType_anon (anonInfo, tinst) -> + sprintf "%s%s" anonInfo.ILTypeRef.FullName (tyargsEnc g (gtpsType, gtpsMethod) tinst) + | TType_tuple (tupInfo, tys) -> if evalTupInfoIsStruct tupInfo then sprintf "System.ValueTuple%s"(tyargsEnc g (gtpsType, gtpsMethod) tys) else sprintf "System.Tuple%s"(tyargsEnc g (gtpsType, gtpsMethod) tys) + | TType_fun (f, x) -> "Microsoft.FSharp.Core.FSharpFunc" + tyargsEnc g (gtpsType, gtpsMethod) [f;x] + | TType_var typar -> typarEnc g (gtpsType, gtpsMethod) typar + | TType_measure _ -> "?" and tyargsEnc g (gtpsType, gtpsMethod) args = @@ -7460,16 +7553,16 @@ let TypeNullNever g ty = let TypeNullIsExtraValue g m ty = if isILReferenceTy g ty || isDelegateTy g ty then // Putting AllowNullLiteralAttribute(false) on an IL or provided type means 'null' can't be used with that type - not (isAppTy g ty && TryFindTyconRefBoolAttribute g m g.attrib_AllowNullLiteralAttribute (tcrefOfAppTy g ty) = Some(false)) + not (match tryDestAppTy g ty with ValueSome tcref -> TryFindTyconRefBoolAttribute g m g.attrib_AllowNullLiteralAttribute tcref = Some false | _ -> false) elif TypeNullNever g ty then false else // Putting AllowNullLiteralAttribute(true) on an F# type means 'null' can be used with that type - isAppTy g ty && TryFindTyconRefBoolAttribute g m g.attrib_AllowNullLiteralAttribute (tcrefOfAppTy g ty) = Some(true) + match tryDestAppTy g ty with ValueSome tcref -> TryFindTyconRefBoolAttribute g m g.attrib_AllowNullLiteralAttribute tcref = Some true | _ -> false let TypeNullIsTrueValue g ty = (match tryDestAppTy g ty with - | Some tcref -> IsUnionTypeWithNullAsTrueValue g tcref.Deref + | ValueSome tcref -> IsUnionTypeWithNullAsTrueValue g tcref.Deref | _ -> false) || (isUnitTy g ty) let TypeNullNotLiked g m ty = @@ -7496,6 +7589,10 @@ let rec TypeHasDefaultValue g m ty = flds |> List.forall (actualTyOfRecdField (mkTyconRefInst tcref tinst) >> TypeHasDefaultValue g m) elif isStructTupleTy g ty then destStructTupleTy g ty |> List.forall (TypeHasDefaultValue g m) + elif isStructAnonRecdTy g ty then + match tryDestAnonRecdTy g ty with + | ValueNone -> true + | ValueSome (_, ptys) -> ptys |> List.forall (TypeHasDefaultValue g m) else // All struct types defined in other .NET languages have a DefaultValue regardless of their // instantiation @@ -7508,9 +7605,13 @@ let (|SpecialComparableHeadType|_|) g ty = if isAnyTupleTy g ty then let _tupInfo, elemTys = destAnyTupleTy g ty Some elemTys + elif isAnonRecdTy g ty then + match tryDestAnonRecdTy g ty with + | ValueNone -> Some [] + | ValueSome (_anonInfo, elemTys) -> Some elemTys else - match ty with - | AppTy g (tcref, tinst) -> + match tryAppTy g ty with + | ValueSome (tcref, tinst) -> if isArrayTyconRef g tcref || tyconRefEq g tcref g.system_UIntPtr_tcref || tyconRefEq g tcref g.system_IntPtr_tcref then @@ -7619,17 +7720,16 @@ let isSealedTy g ty = | ProvidedTypeMetadata st -> st.IsSealed #endif | ILTypeMetadata (TILObjectReprData(_, _, td)) -> td.IsSealed - | FSharpOrArrayOrByrefOrTupleOrExnTypeMetadata -> - + | FSharpOrArrayOrByrefOrTupleOrExnTypeMetadata -> if (isFSharpInterfaceTy g ty || isFSharpClassTy g ty) then - let tcref, _ = destAppTy g ty - (TryFindFSharpBoolAttribute g g.attrib_SealedAttribute tcref.Attribs = Some(true)) + let tcref = tcrefOfAppTy g ty + TryFindFSharpBoolAttribute g g.attrib_SealedAttribute tcref.Attribs = Some true else // All other F# types, array, byref, tuple types are sealed true let isComInteropTy g ty = - let tcr, _ = destAppTy g ty + let tcr = tcrefOfAppTy g ty match g.attrib_ComImportAttribute with | None -> false | Some attr -> TryFindFSharpBoolAttribute g attr tcr.Attribs = Some(true) @@ -7935,9 +8035,9 @@ let MakeExportRemapping viewedCcu (mspec:ModuleOrNamespace) = let accEntityRemap (entity:Entity) acc = match tryRescopeEntity viewedCcu entity with - | Some eref -> + | ValueSome eref -> addTyconRefRemap (mkLocalTyconRef entity) eref acc - | None -> + | _ -> if entity.IsNamespace then acc else @@ -7946,9 +8046,9 @@ let MakeExportRemapping viewedCcu (mspec:ModuleOrNamespace) = let accValRemap (vspec:Val) acc = // The acc contains the entity remappings match tryRescopeVal viewedCcu acc vspec with - | Some vref -> + | ValueSome vref -> {acc with valRemap=acc.valRemap.Add vspec vref } - | None -> + | _ -> error(InternalError("Unexpected value without a pubpath when remapping assembly data", vspec.Range)) let mty = mspec.ModuleOrNamespaceType @@ -8275,12 +8375,12 @@ let rec mkCompiledTuple g isStruct (argtys, args, m) = ty8, arg8 | _ -> let ty8enc = TType_app((if isStruct then g.struct_tuple1_tcr else g.ref_tuple1_tcr), [ty8]) - let v8enc = Expr.Op (TOp.Tuple (TupInfo.Const isStruct), [ty8], [arg8], m) + let v8enc = Expr.Op (TOp.Tuple (mkTupInfo isStruct), [ty8], [arg8], m) ty8enc, v8enc | _ -> let a, b, c, d = mkCompiledTuple g isStruct (argtysB, argsB, m) let ty8plus = TType_app(a, b) - let v8plus = Expr.Op (TOp.Tuple(TupInfo.Const isStruct), b, c, d) + let v8plus = Expr.Op (TOp.Tuple(mkTupInfo isStruct), b, c, d) ty8plus, v8plus let argtysAB = argtysA @ [ty8] (mkCompiledTupleTyconRef g isStruct (List.length argtysAB), argtysAB, argsA @ [v8], m) diff --git a/src/fsharp/TastOps.fsi b/src/fsharp/TastOps.fsi index d2a532c37a..badacfda0e 100755 --- a/src/fsharp/TastOps.fsi +++ b/src/fsharp/TastOps.fsi @@ -3,7 +3,6 @@ /// Defines derived expression manipulation and construction functions. module internal Microsoft.FSharp.Compiler.Tastops -open System.Text open System.Collections.Generic open Internal.Utilities open Microsoft.FSharp.Compiler.AbstractIL @@ -13,15 +12,9 @@ open Microsoft.FSharp.Compiler open Microsoft.FSharp.Compiler.Range open Microsoft.FSharp.Compiler.Rational open Microsoft.FSharp.Compiler.Ast -open Microsoft.FSharp.Compiler.ErrorLogger open Microsoft.FSharp.Compiler.Tast open Microsoft.FSharp.Compiler.TcGlobals open Microsoft.FSharp.Compiler.Layout -open Microsoft.FSharp.Compiler.Lib - -#if !NO_EXTENSIONTYPING -open Microsoft.FSharp.Compiler.ExtensionTyping -#endif //------------------------------------------------------------------------- // Type equivalence @@ -41,10 +34,6 @@ val measureEquiv : TcGlobals -> Measure -> Measure -> bool /// Reduce a type to its more anonical form subject to an erasure flag, inference equations and abbreviations val stripTyEqnsWrtErasure: Erasure -> TcGlobals -> TType -> TType -//------------------------------------------------------------------------- -// Build common types -//------------------------------------------------------------------------- - /// Build a function type val mkFunTy : TType -> TType -> TType @@ -76,137 +65,232 @@ val stripExpr : Expr -> Expr /// Get the values for a set of bindings val valsOfBinds : Bindings -> Vals -val (|ExprValWithPossibleTypeInst|_|) : Expr -> (ValRef * ValUseFlag * TType list * range) option -//------------------------------------------------------------------------- -// Build decision trees imperatively -//------------------------------------------------------------------------- +/// Look for a use of an F# value, possibly including application of a generic thing to a set of type arguments +val (|ExprValWithPossibleTypeInst|_|) : Expr -> (ValRef * ValUseFlag * TType list * range) option +/// Build decision trees imperatively type MatchBuilder = + + /// Create a new builder new : SequencePointInfoForBinding * range -> MatchBuilder + + /// Add a new destination target member AddTarget : DecisionTreeTarget -> int + + /// Add a new destination target that is an expression result member AddResultTarget : Expr * SequencePointInfoForTarget -> DecisionTree + + /// Finish the targets member CloseTargets : unit -> DecisionTreeTarget list - member Close : DecisionTree * range * TType -> Expr -//------------------------------------------------------------------------- -// Make some special decision graphs -//------------------------------------------------------------------------- + /// Build the overall expression + member Close : DecisionTree * range * TType -> Expr +/// Add an if-then-else boolean conditional node into a decision tree val mkBoolSwitch : range -> Expr -> DecisionTree -> DecisionTree -> DecisionTree + +/// Build a conditional expression val primMkCond : SequencePointInfoForBinding -> SequencePointInfoForTarget -> SequencePointInfoForTarget -> range -> TType -> Expr -> Expr -> Expr -> Expr + +/// Build a conditional expression val mkCond : SequencePointInfoForBinding -> SequencePointInfoForTarget -> range -> TType -> Expr -> Expr -> Expr -> Expr + +/// Build a conditional expression that checks for non-nullness val mkNonNullCond : TcGlobals -> range -> TType -> Expr -> Expr -> Expr -> Expr -val mkIfThen : TcGlobals -> range -> Expr -> Expr -> Expr -//------------------------------------------------------------------------- -// Generate new locals -//------------------------------------------------------------------------- +/// Build an if-then statement +val mkIfThen : TcGlobals -> range -> Expr -> Expr -> Expr +/// Build an expression corresponding to the use of a value /// Note: try to use exprForValRef or the expression returned from mkLocal instead of this. val exprForVal : range -> Val -> Expr + +/// Build an expression corresponding to the use of a reference to a value val exprForValRef : range -> ValRef -> Expr -/// Return the local and an expression to reference it +/// Make a new local value and build an expression to reference it val mkLocal : range -> string -> TType -> Val * Expr + +/// Make a new compiler-generated local value and build an expression to reference it val mkCompGenLocal : range -> string -> TType -> Val * Expr + +/// Make a new mutable compiler-generated local value and build an expression to reference it val mkMutableCompGenLocal : range -> string -> TType -> Val * Expr -val mkCompGenLocalAndInvisbleBind : TcGlobals -> string -> range -> Expr -> Val * Expr * Binding -//------------------------------------------------------------------------- -// Make lambdas -//------------------------------------------------------------------------- +/// Make a new mutable compiler-generated local value, 'let' bind it to an expression +/// 'invisibly' (no sequence point etc.), and build an expression to reference it +val mkCompGenLocalAndInvisbleBind : TcGlobals -> string -> range -> Expr -> Val * Expr * Binding +/// Build a lambda expression taking multiple values val mkMultiLambda : range -> Val list -> Expr * TType -> Expr + +/// Rebuild a lambda during an expression tree traversal val rebuildLambda : range -> Val option -> Val option -> Val list -> Expr * TType -> Expr + +/// Build a lambda expression taking a single value val mkLambda : range -> Val -> Expr * TType -> Expr + +/// Build a generic lambda expression (type abstraction) val mkTypeLambda : range -> Typars -> Expr * TType -> Expr + +/// Build an object expression val mkObjExpr : TType * Val option * Expr * ObjExprMethod list * (TType * ObjExprMethod list) list * Range.range -> Expr + +/// Build an type-chose expression, indicating that a local free choice of a type variable val mkTypeChoose : range -> Typars -> Expr -> Expr + +/// Build an iterated (curried) lambda expression val mkLambdas : range -> Typars -> Val list -> Expr * TType -> Expr + +/// Build an iterated (tupled+curried) lambda expression val mkMultiLambdasCore : range -> Val list list -> Expr * TType -> Expr * TType + +/// Build an iterated generic (type abstraction + tupled+curried) lambda expression val mkMultiLambdas : range -> Typars -> Val list list -> Expr * TType -> Expr + +/// Build a lambda expression that corresponds to the implementation of a member val mkMemberLambdas : range -> Typars -> Val option -> Val option -> Val list list -> Expr * TType -> Expr +/// Build a 'while' loop expression val mkWhile : TcGlobals -> SequencePointInfoForWhileLoop * SpecialWhileLoopMarker * Expr * Expr * range -> Expr + +/// Build a 'for' loop expression val mkFor : TcGlobals -> SequencePointInfoForForLoop * Val * Expr * ForLoopStyle * Expr * Expr * range -> Expr + +/// Build a 'try/with' expression val mkTryWith : TcGlobals -> Expr * (* filter val *) Val * (* filter expr *) Expr * (* handler val *) Val * (* handler expr *) Expr * range * TType * SequencePointInfoForTry * SequencePointInfoForWith -> Expr -val mkTryFinally: TcGlobals -> Expr * Expr * range * TType * SequencePointInfoForTry * SequencePointInfoForFinally -> Expr -//------------------------------------------------------------------------- -// Make let/letrec -//------------------------------------------------------------------------- - +/// Build a 'try/finally' expression +val mkTryFinally: TcGlobals -> Expr * Expr * range * TType * SequencePointInfoForTry * SequencePointInfoForFinally -> Expr -// Generate a user-level let-bindings +/// Build a user-level value binding val mkBind : SequencePointInfoForBinding -> Val -> Expr -> Binding + +/// Build a user-level let-binding val mkLetBind : range -> Binding -> Expr -> Expr + +/// Build a user-level value sequence of let bindings val mkLetsBind : range -> Binding list -> Expr -> Expr + +/// Build a user-level value sequence of let bindings val mkLetsFromBindings : range -> Bindings -> Expr -> Expr + +/// Build a user-level let expression val mkLet : SequencePointInfoForBinding -> range -> Val -> Expr -> Expr -> Expr + +/// Make a binding that binds a function value to a lambda taking multiple arguments val mkMultiLambdaBind : Val -> SequencePointInfoForBinding -> range -> Typars -> Val list list -> Expr * TType -> Binding // Compiler generated bindings may involve a user variable. // Compiler generated bindings may give rise to a sequence point if they are part of // an SPAlways expression. Compiler generated bindings can arise from for example, inlining. val mkCompGenBind : Val -> Expr -> Binding + +/// Make a set of bindings that bind compiler generated values to corresponding expressions. +/// Compiler-generated bindings do not give rise to a sequence point in debugging. val mkCompGenBinds : Val list -> Exprs -> Bindings + +/// Make a let-expression that locally binds a compiler-generated value to an expression. +/// Compiler-generated bindings do not give rise to a sequence point in debugging. val mkCompGenLet : range -> Val -> Expr -> Expr -> Expr + +/// Make a let-expression that locally binds a compiler-generated value to an expression, where the expression +/// is returned by the given continuation. Compiler-generated bindings do not give rise to a sequence point in debugging. val mkCompGenLetIn: range -> string -> TType -> Expr -> (Val * Expr -> Expr) -> Expr -// Invisible bindings are never given a sequence point and should never have side effects +/// Make a let-expression that locally binds a value to an expression in an "invisible" way. +/// Invisible bindings are not given a sequence point and should not have side effects. val mkInvisibleLet : range -> Val -> Expr -> Expr -> Expr + +/// Make a binding that binds a value to an expression in an "invisible" way. +/// Invisible bindings are not given a sequence point and should not have side effects. val mkInvisibleBind : Val -> Expr -> Binding + +/// Make a set of bindings that bind values to expressions in an "invisible" way. +/// Invisible bindings are not given a sequence point and should not have side effects. val mkInvisibleBinds : Vals -> Exprs -> Bindings + +/// Make a let-rec expression that locally binds values to expressions where self-reference back to the values is possible. val mkLetRecBinds : range -> Bindings -> Expr -> Expr -//------------------------------------------------------------------------- -// Generalization/inference helpers -//------------------------------------------------------------------------- - /// TypeScheme (generalizedTypars, tauTy) /// /// generalizedTypars -- the truly generalized type parameters /// tauTy -- the body of the generalized type. A 'tau' type is one with its type parameters stripped off. type TypeScheme = TypeScheme of Typars * TType +/// Make the right-hand side of a generalized binding, incorporating the generalized generic parameters from the type +/// scheme into the right-hand side as type generalizations. val mkGenericBindRhs : TcGlobals -> range -> Typars -> TypeScheme -> Expr -> Expr -val isBeingGeneralized : Typar -> TypeScheme -> bool -//------------------------------------------------------------------------- -// Make lazy and/or -//------------------------------------------------------------------------- +/// Test if the type parameter is one of those being generalized by a type scheme. +val isBeingGeneralized : Typar -> TypeScheme -> bool +/// Make the expression corresponding to 'expr1 && expr2' val mkLazyAnd : TcGlobals -> range -> Expr -> Expr -> Expr + +/// Make the expression corresponding to 'expr1 || expr2' val mkLazyOr : TcGlobals -> range -> Expr -> Expr -> Expr + +/// Make a byref type val mkByrefTy : TcGlobals -> TType -> TType + +/// Make a byref type with a in/out kind inference parameter val mkByrefTyWithInference : TcGlobals -> TType -> TType -> TType + +/// Make a in-byref type with a in kind parameter val mkInByrefTy : TcGlobals -> TType -> TType -val mkOutByrefTy : TcGlobals -> TType -> TType -//------------------------------------------------------------------------- -// Make construction operations -//------------------------------------------------------------------------- +/// Make an out-byref type with an out kind parameter +val mkOutByrefTy : TcGlobals -> TType -> TType +/// Make an expression that constructs a union case, e.g. 'Some(expr)' val mkUnionCaseExpr : UnionCaseRef * TypeInst * Exprs * range -> Expr + +/// Make an expression that constructs an exception value val mkExnExpr : TyconRef * Exprs * range -> Expr + +/// Make an expression that is IL assembly code val mkAsmExpr : ILInstr list * TypeInst * Exprs * TTypes * range -> Expr + +/// Make an expression that coerces one expression to another type val mkCoerceExpr : Expr * TType * range * TType -> Expr -val mkReraise : range -> TType -> Expr -val mkReraiseLibCall : TcGlobals -> TType -> range -> Expr +/// Make an expression that re-raises an exception +val mkReraise : range -> TType -> Expr -//------------------------------------------------------------------------- -// Make projection operations -//------------------------------------------------------------------------- +/// Make an expression that re-raises an exception via a library call +val mkReraiseLibCall : TcGlobals -> TType -> range -> Expr +/// Make an expression that gets an item from a tuple val mkTupleFieldGet : TcGlobals -> TupInfo * Expr * TypeInst * int * range -> Expr + +/// Make an expression that gets an item from an anonymous record +val mkAnonRecdFieldGet : TcGlobals -> AnonRecdTypeInfo * Expr * TypeInst * int * range -> Expr + +/// Make an expression that gets an item from an anonymous record (via the address of the value if it is a struct) +val mkAnonRecdFieldGetViaExprAddr : AnonRecdTypeInfo * Expr * TypeInst * int * range -> Expr + +/// Make an expression that gets an instance field from a record or class (via the address of the value if it is a struct) val mkRecdFieldGetViaExprAddr : Expr * RecdFieldRef * TypeInst * range -> Expr + +/// Make an expression that gets the address of an instance field from a record or class (via the address of the value if it is a struct) val mkRecdFieldGetAddrViaExprAddr : readonly: bool * Expr * RecdFieldRef * TypeInst * range -> Expr + +/// Make an expression that gets a static field from a record or class val mkStaticRecdFieldGet : RecdFieldRef * TypeInst * range -> Expr + +/// Make an expression that sets a static field in a record or class val mkStaticRecdFieldSet : RecdFieldRef * TypeInst * Expr * range -> Expr + +/// Make an expression that gets the address of a static field in a record or class val mkStaticRecdFieldGetAddr : readonly: bool * RecdFieldRef * TypeInst * range -> Expr + +/// Make an expression that sets an instance the field of a record or class (via the address of the value if it is a struct) val mkRecdFieldSetViaExprAddr : Expr * RecdFieldRef * TypeInst * Expr * range -> Expr + +/// Make an expression that gets the tag of a union value (via the address of the value if it is a struct) val mkUnionCaseTagGetViaExprAddr : Expr * TyconRef * TypeInst * range -> Expr /// Make a 'TOp.UnionCaseProof' expression, which proves a union value is over a particular case (used only for ref-unions, not struct-unions) @@ -235,9 +319,13 @@ val mkUnionCaseFieldSet : Expr * UnionCaseRef * TypeInst * int * E /// Like mkUnionCaseFieldGetUnprovenViaExprAddr, but for struct-unions, the input should be a copy of the expression. val mkUnionCaseFieldGetUnproven : TcGlobals -> Expr * UnionCaseRef * TypeInst * int * range -> Expr +/// Make an expression that gets an instance field from an F# exception value val mkExnCaseFieldGet : Expr * TyconRef * int * range -> Expr + +/// Make an expression that sets an instance field in an F# exception value val mkExnCaseFieldSet : Expr * TyconRef * int * Expr * range -> Expr +/// Make an expression that gets the address of an element in an array val mkArrayElemAddress : TcGlobals -> readonly: bool * ILReadonly * bool * ILArrayShape * TType * Expr list * range -> Expr //------------------------------------------------------------------------- @@ -270,47 +358,59 @@ val mkGetTupleItemN : TcGlobals -> range -> int -> ILType -> bool -> Expr -> TTy /// but TupInfo may later be used carry variables that infer structness. val evalTupInfoIsStruct : TupInfo -> bool +/// Evaluate the AnonRecdTypeInfo to work out if it is a struct or a ref. +val evalAnonInfoIsStruct : AnonRecdTypeInfo -> bool + /// If it is a tuple type, ensure it's outermost type is a .NET tuple type, otherwise leave unchanged val convertToTypeWithMetadataIfPossible : TcGlobals -> TType -> TType - -//------------------------------------------------------------------------- -// Take the address of an expression, or force it into a mutable local. Any allocated -// mutable local may need to be kept alive over a larger expression, hence we return -// a wrapping function that wraps "let mutable loc = Expr in ..." around a larger -// expression. -//------------------------------------------------------------------------- - +/// An exception representing a warning for a defensive copy of an immutable struct exception DefensiveCopyWarning of string * range + type Mutates = AddressOfOp | DefinitelyMutates | PossiblyMutates | NeverMutates + +/// Helper to take the address of an expression val mkExprAddrOfExprAux : TcGlobals -> bool -> bool -> Mutates -> Expr -> ValRef option -> range -> (Val * Expr) option * Expr * bool * bool -val mkExprAddrOfExpr : TcGlobals -> bool -> bool -> Mutates -> Expr -> ValRef option -> range -> (Expr -> Expr) * Expr * bool * bool -//------------------------------------------------------------------------- -// Tables keyed on values and/or type parameters -//------------------------------------------------------------------------- +/// Take the address of an expression, or force it into a mutable local. Any allocated +/// mutable local may need to be kept alive over a larger expression, hence we return +/// a wrapping function that wraps "let mutable loc = Expr in ..." around a larger +/// expression. +val mkExprAddrOfExpr : TcGlobals -> bool -> bool -> Mutates -> Expr -> ValRef option -> range -> (Expr -> Expr) * Expr * bool * bool /// Maps Val to T, based on stamps [] type ValMap<'T> = + member Contents : StampMap<'T> + member Item : Val -> 'T with get + member TryFind : Val -> 'T option + member ContainsVal : Val -> bool + member Add : Val -> 'T -> ValMap<'T> + member Remove : Val -> ValMap<'T> + member IsEmpty : bool + static member Empty : ValMap<'T> + static member OfList : (Val * 'T) list -> ValMap<'T> /// Mutable data structure mapping Val's to T based on stamp keys [] type ValHash<'T> = + member Values : seq<'T> + member TryFind : Val -> 'T option + member Add : Val * 'T -> unit - static member Create : unit -> ValHash<'T> + static member Create : unit -> ValHash<'T> /// Maps Val's to list of T based on stamp keys [] @@ -328,97 +428,126 @@ type ValMultiMap<'T> = static member Empty : ValMultiMap<'T> +/// Maps type parameters to entries based on stamp keys [] -/// Maps Typar to T based on stamp keys type TyparMap<'T> = + /// Get the entry for the given type parameter member Item : Typar -> 'T with get + /// Determine is the map contains an entry for the given type parameter member ContainsKey : Typar -> bool + /// Try to find the entry for the given type parameter member TryFind : Typar -> 'T option + /// Make a new map, containing a new entry for the given type parameter member Add : Typar * 'T -> TyparMap<'T> + /// The empty map static member Empty : TyparMap<'T> -[] /// Maps TyconRef to T based on stamp keys +[] type TyconRefMap<'T> = + /// Get the entry for the given type definition member Item : TyconRef -> 'T with get + /// Try to find the entry for the given type definition member TryFind : TyconRef -> 'T option + /// Determine is the map contains an entry for the given type definition member ContainsKey : TyconRef -> bool + /// Make a new map, containing a new entry for the given type definition member Add : TyconRef -> 'T -> TyconRefMap<'T> + /// Remove the entry for the given type definition, if any member Remove : TyconRef -> TyconRefMap<'T> + /// Determine if the map is empty member IsEmpty : bool + /// The empty map static member Empty : TyconRefMap<'T> + /// Make a new map, containing entries for the given type definitions static member OfList : (TyconRef * 'T) list -> TyconRefMap<'T> /// Maps TyconRef to list of T based on stamp keys [] type TyconRefMultiMap<'T> = + /// Fetch the entries for the given type definition member Find : TyconRef -> 'T list + /// Make a new map, containing a new entry for the given type definition member Add : TyconRef * 'T -> TyconRefMultiMap<'T> + /// The empty map static member Empty : TyconRefMultiMap<'T> + /// Make a new map, containing a entries for the given type definitions static member OfList : (TyconRef * 'T) list -> TyconRefMultiMap<'T> -//------------------------------------------------------------------------- -// Orderings on Tycon, Val, RecdFieldRef, Typar -//------------------------------------------------------------------------- +/// An ordering for value definitions, based on stamp +val valOrder: IComparer -val valOrder : IComparer -val tyconOrder : IComparer -val recdFieldRefOrder : IComparer -val typarOrder : IComparer +/// An ordering for type definitions, based on stamp +val tyconOrder: IComparer -//------------------------------------------------------------------------- -// Equality on Tycon and Val -//------------------------------------------------------------------------- +/// An ordering for record fields, based on stamp +val recdFieldRefOrder: IComparer +/// An ordering for type parameters, based on stamp +val typarOrder: IComparer + +/// Equality for type definition references val tyconRefEq : TcGlobals -> TyconRef -> TyconRef -> bool + +/// Equality for value references val valRefEq : TcGlobals -> ValRef -> ValRef -> bool //------------------------------------------------------------------------- // Operations on types: substitution //------------------------------------------------------------------------- +/// Represents an instantiation where types replace type parameters type TyparInst = (Typar * TType) list +/// Represents an instantiation where type definition references replace other type definition references type TyconRefRemap = TyconRefMap + +/// Represents an instantiation where value references replace other value references type ValRemap = ValMap +/// Represents a combination of substitutions/instantiations where things replace other things during remapping [] type Remap = - { tpinst : TyparInst; - valRemap: ValRemap; - tyconRefRemap : TyconRefRemap; + { tpinst : TyparInst + valRemap: ValRemap + tyconRefRemap : TyconRefRemap removeTraitSolutions: bool } static member Empty : Remap val addTyconRefRemap : TyconRef -> TyconRef -> Remap -> Remap -val addValRemap : Val -> Val -> Remap -> Remap +val addValRemap : Val -> Val -> Remap -> Remap val mkTyparInst : Typars -> TTypes -> TyparInst + val mkTyconRefInst : TyconRef -> TypeInst -> TyparInst + val emptyTyparInst : TyparInst val instType : TyparInst -> TType -> TType + val instTypes : TyparInst -> TypeInst -> TypeInst + val instTyparConstraints : TyparInst -> TyparConstraint list -> TyparConstraint list + val instTrait : TyparInst -> TraitConstraintInfo -> TraitConstraintInfo //------------------------------------------------------------------------- @@ -426,8 +555,11 @@ val instTrait : TyparInst -> TraitConstraintInfo -> TraitConstraint //------------------------------------------------------------------------- val generalizeTypars : Typars -> TypeInst + val generalizeTyconRef : TyconRef -> TTypes * TType + val generalizedTyconRef : TyconRef -> TType + val mkTyparToTyparRenaming : Typars -> Typars -> TyparInst * TTypes //------------------------------------------------------------------------- @@ -435,12 +567,16 @@ val mkTyparToTyparRenaming : Typars -> Typars -> TyparInst * TTypes //------------------------------------------------------------------------- val reduceTyconRefAbbrev : TyconRef -> TypeInst -> TType + val reduceTyconRefMeasureableOrProvided : TcGlobals -> TyconRef -> TypeInst -> TType + val reduceTyconRefAbbrevMeasureable : TyconRef -> Measure /// set bool to 'true' to allow shortcutting of type parameter equation chains during stripping val stripTyEqnsA : TcGlobals -> bool -> TType -> TType + val stripTyEqns : TcGlobals -> TType -> TType + val stripTyEqnsAndMeasureEqns : TcGlobals -> TType -> TType val tryNormalizeMeasureInType : TcGlobals -> TType -> TType @@ -451,7 +587,9 @@ val tryNormalizeMeasureInType : TcGlobals -> TType -> TType /// See through F# exception abbreviations val stripExnEqns : TyconRef -> Tycon + val recdFieldsOfExnDefRef : TyconRef -> RecdField list + val recdFieldTysOfExnDefRef : TyconRef -> TType list //------------------------------------------------------------------------- @@ -460,57 +598,102 @@ val recdFieldTysOfExnDefRef : TyconRef -> TType list //------------------------------------------------------------------------- val destForallTy : TcGlobals -> TType -> Typars * TType + val destFunTy : TcGlobals -> TType -> TType * TType + val destAnyTupleTy : TcGlobals -> TType -> TupInfo * TTypes + val destRefTupleTy : TcGlobals -> TType -> TTypes + val destStructTupleTy : TcGlobals -> TType -> TTypes + val destTyparTy : TcGlobals -> TType -> Typar + val destAnyParTy : TcGlobals -> TType -> Typar + val destMeasureTy : TcGlobals -> TType -> Measure + val tryDestForallTy : TcGlobals -> TType -> Typars * TType val isFunTy : TcGlobals -> TType -> bool + val isForallTy : TcGlobals -> TType -> bool + val isAnyTupleTy : TcGlobals -> TType -> bool + val isRefTupleTy : TcGlobals -> TType -> bool + val isStructTupleTy : TcGlobals -> TType -> bool + +val isStructAnonRecdTy : TcGlobals -> TType -> bool + +val isAnonRecdTy : TcGlobals -> TType -> bool + val isUnionTy : TcGlobals -> TType -> bool + val isReprHiddenTy : TcGlobals -> TType -> bool + val isFSharpObjModelTy : TcGlobals -> TType -> bool + val isRecdTy : TcGlobals -> TType -> bool + val isFSharpStructOrEnumTy : TcGlobals -> TType -> bool + val isFSharpEnumTy : TcGlobals -> TType -> bool + val isTyparTy : TcGlobals -> TType -> bool + val isAnyParTy : TcGlobals -> TType -> bool -val tryAnyParTy : TcGlobals -> TType -> Typar option + +val tryAnyParTy : TcGlobals -> TType -> ValueOption + +val tryAnyParTyOption : TcGlobals -> TType -> Typar option + val isMeasureTy : TcGlobals -> TType -> bool val mkAppTy : TyconRef -> TypeInst -> TType val mkProvenUnionCaseTy : UnionCaseRef -> TypeInst -> TType + val isProvenUnionCaseTy : TType -> bool val isAppTy : TcGlobals -> TType -> bool + +val tryAppTy : TcGlobals -> TType -> ValueOption + val destAppTy : TcGlobals -> TType -> TyconRef * TypeInst + val tcrefOfAppTy : TcGlobals -> TType -> TyconRef -val tryDestAppTy : TcGlobals -> TType -> TyconRef option -val tryDestTyparTy : TcGlobals -> TType -> Typar option -val tryDestFunTy : TcGlobals -> TType -> (TType * TType) option + +val tryDestAppTy : TcGlobals -> TType -> ValueOption + +val tryDestTyparTy : TcGlobals -> TType -> ValueOption + +val tryDestFunTy : TcGlobals -> TType -> ValueOption<(TType * TType)> + +val tryDestAnonRecdTy : TcGlobals -> TType -> ValueOption + val argsOfAppTy : TcGlobals -> TType -> TypeInst + val mkInstForAppTy : TcGlobals -> TType -> TyparInst /// Try to get a TyconRef for a type without erasing type abbreviations -val tryNiceEntityRefOfTy : TType -> TyconRef option +val tryNiceEntityRefOfTy : TType -> ValueOption +val tryNiceEntityRefOfTyOption : TType -> TyconRef option val domainOfFunTy : TcGlobals -> TType -> TType + val rangeOfFunTy : TcGlobals -> TType -> TType + val stripFunTy : TcGlobals -> TType -> TType list * TType + val stripFunTyN : TcGlobals -> int -> TType -> TType list * TType val applyForallTy : TcGlobals -> TType -> TypeInst -> TType val tryDestAnyTupleTy : TcGlobals -> TType -> TupInfo * TType list + val tryDestRefTupleTy : TcGlobals -> TType -> TType list //------------------------------------------------------------------------- @@ -525,7 +708,9 @@ val actualTysOfUnionCaseFields : TyparInst -> UnionCaseRef -> TType list val actualTysOfInstanceRecdFields : TyparInst -> TyconRef -> TType list val actualTyOfRecdField : TyparInst -> RecdField -> TType + val actualTyOfRecdFieldRef : RecdFieldRef -> TypeInst -> TType + val actualTyOfRecdFieldForTycon : Tycon -> TypeInst -> RecdField -> TType //------------------------------------------------------------------------- @@ -535,14 +720,21 @@ val actualTyOfRecdFieldForTycon : Tycon -> TypeInst -> RecdField -> TType //------------------------------------------------------------------------- type UncurriedArgInfos = (TType * ArgReprInfo) list + type CurriedArgInfos = UncurriedArgInfos list val destTopForallTy : TcGlobals -> ValReprInfo -> TType -> Typars * TType + val GetTopTauTypeInFSharpForm : TcGlobals -> ArgReprInfo list list -> TType -> range -> CurriedArgInfos * TType + val GetTopValTypeInFSharpForm : TcGlobals -> ValReprInfo -> TType -> range -> Typars * CurriedArgInfos * TType * ArgReprInfo + val IsCompiledAsStaticProperty : TcGlobals -> Val -> bool + val IsCompiledAsStaticPropertyWithField : TcGlobals -> Val -> bool + val GetTopValTypeInCompiledForm : TcGlobals -> ValReprInfo -> TType -> range -> Typars * CurriedArgInfos * TType option * ArgReprInfo + val GetFSharpViewOfReturnType : TcGlobals -> TType option -> TType val NormalizeDeclaredTyparsForEquiRecursiveInference : TcGlobals -> Typars -> Typars @@ -558,40 +750,58 @@ val applyTys : TcGlobals -> TType -> TType list * 'T list -> TType //------------------------------------------------------------------------- val emptyFreeTypars : FreeTypars + val unionFreeTypars : FreeTypars -> FreeTypars -> FreeTypars val emptyFreeTycons : FreeTycons + val unionFreeTycons : FreeTycons -> FreeTycons -> FreeTycons val emptyFreeTyvars : FreeTyvars + val isEmptyFreeTyvars : FreeTyvars -> bool + val unionFreeTyvars : FreeTyvars -> FreeTyvars -> FreeTyvars val emptyFreeLocals : FreeLocals + val unionFreeLocals : FreeLocals -> FreeLocals -> FreeLocals type FreeVarOptions val CollectLocalsNoCaching : FreeVarOptions + val CollectTyparsNoCaching : FreeVarOptions + val CollectTyparsAndLocalsNoCaching : FreeVarOptions + val CollectTyparsAndLocals : FreeVarOptions + val CollectLocals : FreeVarOptions + val CollectTypars : FreeVarOptions + val CollectAllNoCaching : FreeVarOptions + val CollectAll : FreeVarOptions val accFreeInTypes : FreeVarOptions -> TType list -> FreeTyvars -> FreeTyvars + val accFreeInType : FreeVarOptions -> TType -> FreeTyvars -> FreeTyvars + val accFreeInTypars : FreeVarOptions -> Typars -> FreeTyvars -> FreeTyvars val freeInType : FreeVarOptions -> TType -> FreeTyvars + val freeInTypes : FreeVarOptions -> TType list -> FreeTyvars + val freeInVal : FreeVarOptions -> Val -> FreeTyvars // This one puts free variables in canonical left-to-right order. val freeInTypeLeftToRight : TcGlobals -> bool -> TType -> Typars + val freeInTypesLeftToRight : TcGlobals -> bool -> TType list -> Typars + val freeInTypesLeftToRightSkippingConstraints : TcGlobals -> TType list -> Typars val freeInModuleTy: ModuleOrNamespaceType -> FreeTyvars @@ -604,26 +814,41 @@ val isDimensionless : TcGlobals -> TType -> bool [] type TypeEquivEnv = - { EquivTypars: TyparMap; + { EquivTypars: TyparMap EquivTycons: TyconRefRemap } static member Empty : TypeEquivEnv + member BindEquivTypars : Typars -> Typars -> TypeEquivEnv + static member FromTyparInst : TyparInst -> TypeEquivEnv + static member FromEquivTypars : Typars -> Typars -> TypeEquivEnv val traitsAEquivAux : Erasure -> TcGlobals -> TypeEquivEnv -> TraitConstraintInfo -> TraitConstraintInfo -> bool + val traitsAEquiv : TcGlobals -> TypeEquivEnv -> TraitConstraintInfo -> TraitConstraintInfo -> bool + val typarConstraintsAEquivAux : Erasure -> TcGlobals -> TypeEquivEnv -> TyparConstraint -> TyparConstraint -> bool + val typarConstraintsAEquiv : TcGlobals -> TypeEquivEnv -> TyparConstraint -> TyparConstraint -> bool + val typarsAEquiv : TcGlobals -> TypeEquivEnv -> Typars -> Typars -> bool + val typeAEquivAux : Erasure -> TcGlobals -> TypeEquivEnv -> TType -> TType -> bool + val typeAEquiv : TcGlobals -> TypeEquivEnv -> TType -> TType -> bool + val returnTypesAEquivAux : Erasure -> TcGlobals -> TypeEquivEnv -> TType option -> TType option -> bool + val returnTypesAEquiv : TcGlobals -> TypeEquivEnv -> TType option -> TType option -> bool + val tcrefAEquiv : TcGlobals -> TypeEquivEnv -> TyconRef -> TyconRef -> bool + val valLinkageAEquiv : TcGlobals -> TypeEquivEnv -> Val -> Val -> bool +val anonInfoEquiv : AnonRecdTypeInfo -> AnonRecdTypeInfo -> bool + //------------------------------------------------------------------------- // Erasure of types wrt units-of-measure and type providers //------------------------------------------------------------------------- @@ -639,11 +864,17 @@ val getErasedTypes : TcGlobals -> TType -> TType list //------------------------------------------------------------------------- val MeasurePower : Measure -> int -> Measure + val ListMeasureVarOccsWithNonZeroExponents : Measure -> (Typar * Rational) list + val ListMeasureConOccsWithNonZeroExponents : TcGlobals -> bool -> Measure -> (TyconRef * Rational) list + val ProdMeasures : Measure list -> Measure + val MeasureVarExponent : Typar -> Measure -> Rational + val MeasureExprConExponent : TcGlobals -> bool -> TyconRef -> Measure -> Rational + val normalizeMeasure : TcGlobals -> Measure -> Measure @@ -652,19 +883,26 @@ val normalizeMeasure : TcGlobals -> Measure -> Measure //------------------------------------------------------------------------- val GetTypeOfMemberInFSharpForm : TcGlobals -> ValRef -> Typars * CurriedArgInfos * TType * ArgReprInfo + val GetTypeOfMemberInMemberForm : TcGlobals -> ValRef -> Typars * CurriedArgInfos * TType option * ArgReprInfo + val GetTypeOfIntrinsicMemberInCompiledForm : TcGlobals -> ValRef -> Typars * CurriedArgInfos * TType option * ArgReprInfo + val GetMemberTypeInMemberForm : TcGlobals -> MemberFlags -> ValReprInfo -> TType -> range -> Typars * CurriedArgInfos * TType option * ArgReprInfo /// Returns (parentTypars,memberParentTypars,memberMethodTypars,memberToParentInst,tinst) val PartitionValTyparsForApparentEnclosingType : TcGlobals -> Val -> (Typars * Typars * Typars * TyparInst * TType list) option + /// Returns (parentTypars,memberParentTypars,memberMethodTypars,memberToParentInst,tinst) val PartitionValTypars : TcGlobals -> Val -> (Typars * Typars * Typars * TyparInst * TType list) option + /// Returns (parentTypars,memberParentTypars,memberMethodTypars,memberToParentInst,tinst) val PartitionValRefTypars : TcGlobals -> ValRef -> (Typars * Typars * Typars * TyparInst * TType list) option val ReturnTypeOfPropertyVal : TcGlobals -> Val -> TType + val ArgInfosOfPropertyVal : TcGlobals -> Val -> UncurriedArgInfos + val ArgInfosOfMember: TcGlobals -> ValRef -> CurriedArgInfos val GetMemberCallInfo : TcGlobals -> ValRef * ValUseFlag -> int * bool * bool * bool * bool * bool * bool * bool @@ -675,68 +913,95 @@ val GetMemberCallInfo : TcGlobals -> ValRef * ValUseFlag -> int * bool * bool * type TyparConstraintsWithTypars = (Typar * TyparConstraint) list - module PrettyTypes = + val NeedsPrettyTyparName : Typar -> bool + val NewPrettyTypars : TyparInst -> Typars -> string list -> Typars * TyparInst + val PrettyTyparNames : (Typar -> bool) -> string list -> Typars -> string list + val PrettifyType : TcGlobals -> TType -> TType * TyparConstraintsWithTypars + val PrettifyInstAndTyparsAndType : TcGlobals -> TyparInst * Typars * TType -> (TyparInst * Typars * TType) * TyparConstraintsWithTypars + val PrettifyTypePair : TcGlobals -> TType * TType -> (TType * TType) * TyparConstraintsWithTypars + val PrettifyTypes : TcGlobals -> TTypes -> TTypes * TyparConstraintsWithTypars + val PrettifyInst : TcGlobals -> TyparInst -> TyparInst * TyparConstraintsWithTypars + val PrettifyInstAndType : TcGlobals -> TyparInst * TType -> (TyparInst * TType) * TyparConstraintsWithTypars + val PrettifyInstAndTypes : TcGlobals -> TyparInst * TTypes -> (TyparInst * TTypes) * TyparConstraintsWithTypars + val PrettifyInstAndSig : TcGlobals -> TyparInst * TTypes * TType -> (TyparInst * TTypes * TType) * TyparConstraintsWithTypars + val PrettifyCurriedTypes : TcGlobals -> TType list list -> TType list list * TyparConstraintsWithTypars + val PrettifyCurriedSigTypes : TcGlobals -> TType list list * TType -> (TType list list * TType) * TyparConstraintsWithTypars + val PrettifyInstAndUncurriedSig : TcGlobals -> TyparInst * UncurriedArgInfos * TType -> (TyparInst * UncurriedArgInfos * TType) * TyparConstraintsWithTypars + val PrettifyInstAndCurriedSig : TcGlobals -> TyparInst * TTypes * CurriedArgInfos * TType -> (TyparInst * TTypes * CurriedArgInfos * TType) * TyparConstraintsWithTypars [] type DisplayEnv = - { includeStaticParametersInTypeNames : bool; - openTopPathsSorted: Lazy; - openTopPathsRaw: string list list; - shortTypeNames: bool; - suppressNestedTypes: bool; - maxMembers : int option; - showObsoleteMembers: bool; - showHiddenMembers: bool; - showTyparBinding: bool; - showImperativeTyparAnnotations: bool; - suppressInlineKeyword:bool; - suppressMutableKeyword:bool; - showMemberContainers: bool; - shortConstraints:bool; - useColonForReturnType:bool; - showAttributes: bool; - showOverrides:bool; - showConstraintTyparAnnotations:bool; - abbreviateAdditionalConstraints: bool; + { includeStaticParametersInTypeNames : bool + openTopPathsSorted: Lazy + openTopPathsRaw: string list list + shortTypeNames: bool + suppressNestedTypes: bool + maxMembers : int option + showObsoleteMembers: bool + showHiddenMembers: bool + showTyparBinding: bool + showImperativeTyparAnnotations: bool + suppressInlineKeyword:bool + suppressMutableKeyword:bool + showMemberContainers: bool + shortConstraints:bool + useColonForReturnType:bool + showAttributes: bool + showOverrides:bool + showConstraintTyparAnnotations:bool + abbreviateAdditionalConstraints: bool showTyparDefaultConstraints: bool g: TcGlobals contextAccessibility: Accessibility generatedValueLayout:(Val -> layout option) } + member SetOpenPaths: string list list -> DisplayEnv + static member Empty: TcGlobals -> DisplayEnv member AddAccessibility : Accessibility -> DisplayEnv + member AddOpenPath : string list -> DisplayEnv + member AddOpenModuleOrNamespace : ModuleOrNamespaceRef -> DisplayEnv val tagEntityRefName: xref: EntityRef -> name: string -> StructuredFormat.TaggedText /// Return the full text for an item as we want it displayed to the user as a fully qualified entity val fullDisplayTextOfModRef : ModuleOrNamespaceRef -> string -val fullDisplayTextOfParentOfModRef : ModuleOrNamespaceRef -> string option + +val fullDisplayTextOfParentOfModRef : ModuleOrNamespaceRef -> ValueOption + val fullDisplayTextOfValRef : ValRef -> string + val fullDisplayTextOfValRefAsLayout : ValRef -> StructuredFormat.Layout + val fullDisplayTextOfTyconRef : TyconRef -> string + val fullDisplayTextOfTyconRefAsLayout : TyconRef -> StructuredFormat.Layout + val fullDisplayTextOfExnRef : TyconRef -> string + val fullDisplayTextOfExnRefAsLayout : TyconRef -> StructuredFormat.Layout + val fullDisplayTextOfUnionCaseRef : UnionCaseRef -> string + val fullDisplayTextOfRecdFieldRef : RecdFieldRef -> string val ticksAndArgCountTextOfTyconRef : TyconRef -> string @@ -747,22 +1012,23 @@ val qualifiedMangledNameOfTyconRef : TyconRef -> string -> string val trimPathByDisplayEnv : DisplayEnv -> string list -> string val prefixOfStaticReq : TyparStaticReq -> string + val prefixOfRigidTypar : Typar -> string /// Utilities used in simplifying types for visual presentation module SimplifyTypes = + type TypeSimplificationInfo = - { singletons : Typar Zset; - inplaceConstraints : Zmap; - postfixConstraints : TyparConstraintsWithTypars; } + { singletons : Typar Zset + inplaceConstraints : Zmap + postfixConstraints : TyparConstraintsWithTypars } + val typeSimplificationInfo0 : TypeSimplificationInfo - val CollectInfo : bool -> TType list -> TyparConstraintsWithTypars -> TypeSimplificationInfo -//------------------------------------------------------------------------- -// -//------------------------------------------------------------------------- + val CollectInfo : bool -> TType list -> TyparConstraintsWithTypars -> TypeSimplificationInfo val superOfTycon : TcGlobals -> Tycon -> TType + val abstractSlotValsOfTycons : Tycon list -> Val list //------------------------------------------------------------------------- @@ -770,11 +1036,15 @@ val abstractSlotValsOfTycons : Tycon list -> Val list //------------------------------------------------------------------------- val emptyFreeVars : FreeVars + val unionFreeVars : FreeVars -> FreeVars -> FreeVars val accFreeInTargets : FreeVarOptions -> DecisionTreeTarget array -> FreeVars -> FreeVars + val accFreeInExprs : FreeVarOptions -> Exprs -> FreeVars -> FreeVars + val accFreeInSwitchCases : FreeVarOptions -> DecisionTreeCase list -> DecisionTree option -> FreeVars -> FreeVars + val accFreeInDecisionTree : FreeVarOptions -> DecisionTree -> FreeVars -> FreeVars /// Get the free variables in a module definition. @@ -786,277 +1056,382 @@ val freeInExpr : FreeVarOptions -> Expr -> FreeVars /// Get the free variables in the right hand side of a binding. val freeInBindingRhs : FreeVarOptions -> Binding -> FreeVars +/// Check if a set of free type variables are all public val freeTyvarsAllPublic : FreeTyvars -> bool -val freeVarsAllPublic : FreeVars -> bool -//------------------------------------------------------------------------- -// Mark/range/position information from expressions -//------------------------------------------------------------------------- +/// Check if a set of free variables are all public +val freeVarsAllPublic : FreeVars -> bool +/// Get the mark/range/position information from an expression type Expr with member Range : range -//------------------------------------------------------------------------- -// type-of operations on the expression tree -//------------------------------------------------------------------------- - +/// Compute the type of an expression from the expression itself val tyOfExpr : TcGlobals -> Expr -> TType -//------------------------------------------------------------------------- -// Top expressions to implement top types -//------------------------------------------------------------------------- - +/// A flag to govern whether arity inference should be type-directed or syntax-directed when +/// inferring an arity from a lambda expression. [] -type AllowTypeDirectedDetupling = Yes | No +type AllowTypeDirectedDetupling = + | Yes + | No +/// Given a (curried) lambda expression, pull off its arguments val stripTopLambda : Expr * TType -> Typars * Val list list * Expr * TType + +/// Given a lambda expression, extract the ValReprInfo for its arguments and other details val InferArityOfExpr : TcGlobals -> AllowTypeDirectedDetupling -> TType -> Attribs list list -> Attribs -> Expr -> ValReprInfo + +/// Given a lambda binding, extract the ValReprInfo for its arguments and other details val InferArityOfExprBinding : TcGlobals -> AllowTypeDirectedDetupling -> Val -> Expr -> ValReprInfo -//------------------------------------------------------------------------- -// Copy expressions and types -//------------------------------------------------------------------------- - +/// Mutate a value to indicate it should be considered a local rather than a module-bound definition // REVIEW: this mutation should not be needed val setValHasNoArity : Val -> Val +/// Indicate what should happen to value definitions when copying expressions type ValCopyFlag = | CloneAll | CloneAllAndMarkExprValsAsCompilerGenerated - // OnlyCloneExprVals is a nasty setting to reuse the cloning logic in a mode where all - // Tycon and "module/member" Val objects keep their identity, but the Val objects for all Expr bindings - // are cloned. This is used to 'fixup' the TAST created by tlr.fs - // - // This is a fragile mode of use. It's not really clear why TLR needs to create a "bad" expression tree that - // reuses Val objects as multiple value bindings, and its been the cause of several subtle bugs. + + /// OnlyCloneExprVals is a nasty setting to reuse the cloning logic in a mode where all + /// Tycon and "module/member" Val objects keep their identity, but the Val objects for all Expr bindings + /// are cloned. This is used to 'fixup' the TAST created by tlr.fs + /// + /// This is a fragile mode of use. It's not really clear why TLR needs to create a "bad" expression tree that + /// reuses Val objects as multiple value bindings, and its been the cause of several subtle bugs. | OnlyCloneExprVals +/// Remap a reference to a type definition using the given remapping substitution val remapTyconRef : TyconRefRemap -> TyconRef -> TyconRef + +/// Remap a reference to a union case using the given remapping substitution val remapUnionCaseRef : TyconRefRemap -> UnionCaseRef -> UnionCaseRef + +/// Remap a reference to a record field using the given remapping substitution val remapRecdFieldRef : TyconRefRemap -> RecdFieldRef -> RecdFieldRef + +/// Remap a reference to a value using the given remapping substitution val remapValRef : Remap -> ValRef -> ValRef + +/// Remap an expression using the given remapping substitution val remapExpr : TcGlobals -> ValCopyFlag -> Remap -> Expr -> Expr + +/// Remap an attribute using the given remapping substitution val remapAttrib : TcGlobals -> Remap -> Attrib -> Attrib + +/// Remap a (possible generic) type using the given remapping substitution val remapPossibleForallTy : TcGlobals -> Remap -> TType -> TType + +/// Copy an entire module or namespace type using the given copying flags val copyModuleOrNamespaceType : TcGlobals -> ValCopyFlag -> ModuleOrNamespaceType -> ModuleOrNamespaceType + +/// Copy an entire expression using the given copying flags val copyExpr : TcGlobals -> ValCopyFlag -> Expr -> Expr + +/// Copy an entire implementation file using the given copying flags val copyImplFile : TcGlobals -> ValCopyFlag -> TypedImplFile -> TypedImplFile + +/// Copy a method slot signature, including new generic type parameters if the slot signature represents a generic method val copySlotSig : SlotSig -> SlotSig + +/// Instantiate the generic type parameters in a method slot signature, building a new one val instSlotSig : TyparInst -> SlotSig -> SlotSig -val instExpr : TcGlobals -> TyparInst -> Expr -> Expr -//------------------------------------------------------------------------- -// Build the remapping that corresponds to a module meeting its signature -// and also report the set of tycons, tycon representations and values hidden in the process. -//------------------------------------------------------------------------- +/// Instantiate the generic type parameters in an expression, building a new one +val instExpr : TcGlobals -> TyparInst -> Expr -> Expr +/// The remapping that corresponds to a module meeting its signature +/// and also report the set of tycons, tycon representations and values hidden in the process. type SignatureRepackageInfo = - { mrpiVals: (ValRef * ValRef) list; - mrpiEntities: (TyconRef * TyconRef) list } + { /// The list of corresponding values + RepackagedVals: (ValRef * ValRef) list + /// The list of corresponding modules, namespacea and type definitions + RepackagedEntities: (TyconRef * TyconRef) list } + + /// The empty table static member Empty : SignatureRepackageInfo +/// A set of tables summarizing the items hidden by a signature type SignatureHidingInfo = - { mhiTycons : Zset; - mhiTyconReprs : Zset; - mhiVals : Zset; - mhiRecdFields : Zset; - mhiUnionCases : Zset } + { HiddenTycons: Zset + HiddenTyconReprs: Zset + HiddenVals: Zset + HiddenRecdFields: Zset + HiddenUnionCases: Zset } + + /// The empty table representing no hiding static member Empty : SignatureHidingInfo -val ComputeRemappingFromInferredSignatureToExplicitSignature : TcGlobals -> ModuleOrNamespaceType -> ModuleOrNamespaceType -> SignatureRepackageInfo * SignatureHidingInfo +/// Compute the remapping information implied by a signature being inferred for a particular implementation val ComputeRemappingFromImplementationToSignature : TcGlobals -> ModuleOrNamespaceExpr -> ModuleOrNamespaceType -> SignatureRepackageInfo * SignatureHidingInfo + +/// Compute the remapping information implied by an explicit signature being given for an inferred signature +val ComputeRemappingFromInferredSignatureToExplicitSignature : TcGlobals -> ModuleOrNamespaceType -> ModuleOrNamespaceType -> SignatureRepackageInfo * SignatureHidingInfo + +/// Compute the hiding information that corresponds to the hiding applied at an assembly boundary val ComputeHidingInfoAtAssemblyBoundary : ModuleOrNamespaceType -> SignatureHidingInfo -> SignatureHidingInfo + val mkRepackageRemapping : SignatureRepackageInfo -> Remap +/// Wrap one module or namespace implementation in a 'namespace N' outer wrapper val wrapModuleOrNamespaceExprInNamespace : Ident -> CompilationPath -> ModuleOrNamespaceExpr -> ModuleOrNamespaceExpr + +/// Wrap one module or namespace definition in a 'namespace N' outer wrapper val wrapModuleOrNamespaceTypeInNamespace : Ident -> CompilationPath -> ModuleOrNamespaceType -> ModuleOrNamespaceType * ModuleOrNamespace + +/// Wrap one module or namespace definition in a 'module M = ..' outer wrapper val wrapModuleOrNamespaceType : Ident -> CompilationPath -> ModuleOrNamespaceType -> ModuleOrNamespace +/// Given an implementation, fetch its recorded signature val SigTypeOfImplFile : TypedImplFile -> ModuleOrNamespaceType -//------------------------------------------------------------------------- -// Given a list of top-most signatures that together constrain the public compilation units -// of an assembly, compute a remapping that converts local references to non-local references. -// This remapping must be applied to all pickled expressions and types -// exported from the assembly. -//------------------------------------------------------------------------- - +/// Given a namespace, module or type definition, try to produce a reference to that entity. +val tryRescopeEntity : CcuThunk -> Entity -> ValueOption -val tryRescopeEntity : CcuThunk -> Entity -> EntityRef option -val tryRescopeVal : CcuThunk -> Remap -> Val -> ValRef option +/// Given a value definition, try to produce a reference to that value. Fails for local values. +val tryRescopeVal : CcuThunk -> Remap -> Val -> ValueOption +/// Make the substitution (remapping) table for viewing a module or namespace 'from the outside' +/// +/// Given the top-most signatures constrains the public compilation units +/// of an assembly, compute a remapping that converts local references to non-local references. +/// This remapping must be applied to all pickled expressions and types +/// exported from the assembly. val MakeExportRemapping : CcuThunk -> ModuleOrNamespace -> Remap + +/// Make a remapping table for viewing a module or namespace 'from the outside' val ApplyExportRemappingToEntity : TcGlobals -> Remap -> ModuleOrNamespace -> ModuleOrNamespace -/// Query SignatureRepackageInfo +/// Determine if a type definition is hidden by a signature val IsHiddenTycon : (Remap * SignatureHidingInfo) list -> Tycon -> bool + +/// Determine if the representation of a type definition is hidden by a signature val IsHiddenTyconRepr : (Remap * SignatureHidingInfo) list -> Tycon -> bool + +/// Determine if a member, function or value is hidden by a signature val IsHiddenVal : (Remap * SignatureHidingInfo) list -> Val -> bool -val IsHiddenRecdField : (Remap * SignatureHidingInfo) list -> RecdFieldRef -> bool -//------------------------------------------------------------------------- -// Adjust marks in expressions -//------------------------------------------------------------------------- +/// Determine if a record field is hidden by a signature +val IsHiddenRecdField : (Remap * SignatureHidingInfo) list -> RecdFieldRef -> bool +/// Adjust marks in expressions, replacing all marks by thegiven mark. +/// Used when inlining. val remarkExpr : range -> Expr -> Expr - -//------------------------------------------------------------------------- -// Make applications -//------------------------------------------------------------------------- +/// Build the application of a (possibly generic, possibly curried) function value to a set of type and expression arguments val primMkApp : (Expr * TType) -> TypeInst -> Exprs -> range -> Expr + +/// Build the application of a (possibly generic, possibly curried) function value to a set of type and expression arguments. +/// Reduce the application via let-bindings if the function value is a lambda expression. val mkApps : TcGlobals -> (Expr * TType) * TType list list * Exprs * range -> Expr + +/// Build the application of a generic construct to a set of type arguments. +/// Reduce the application via substitution if the function value is a typed lambda expression. val mkTyAppExpr : range -> Expr * TType -> TType list -> Expr +/// Build an expression to mutate a local /// localv <- e val mkValSet : range -> ValRef -> Expr -> Expr + +/// Build an expression to mutate the contents of a local pointer /// *localv_ptr = e val mkAddrSet : range -> ValRef -> Expr -> Expr + +/// Build an expression to dereference a local pointer /// *localv_ptr val mkAddrGet : range -> ValRef -> Expr + +/// Build an expression to take the address of a local /// &localv val mkValAddr : range -> readonly: bool -> ValRef -> Expr -//------------------------------------------------------------------------- -// Note these take the address of the record expression if it is a struct, and -// apply a type instantiation if it is a first-class polymorphic record field. -//------------------------------------------------------------------------- - +/// Build an exression representing the read of an instance class or record field. +/// First take the address of the record expression if it is a struct. val mkRecdFieldGet : TcGlobals -> Expr * RecdFieldRef * TypeInst * range -> Expr -//------------------------------------------------------------------------- -// Get the targets used in a decision graph (for reporting warnings) -//------------------------------------------------------------------------- - +/// Accumulate the targets actually used in a decision graph (for reporting warnings) val accTargetsOfDecisionTree : DecisionTree -> int list -> int list -//------------------------------------------------------------------------- -// Optimizations on decision graphs -//------------------------------------------------------------------------- - +/// Make a 'match' expression applying some peep-hole optimizations along the way, e.g to +/// pre-decide the branch taken at compile-time. val mkAndSimplifyMatch : SequencePointInfoForBinding -> range -> range -> TType -> DecisionTree -> DecisionTreeTarget list -> Expr +/// Make a 'match' expression without applying any peep-hole optimizations. val primMkMatch : SequencePointInfoForBinding * range * DecisionTree * DecisionTreeTarget array * range * TType -> Expr -//------------------------------------------------------------------------- -// Work out what things on the r.h.s. of a let rec need to be fixed up -//------------------------------------------------------------------------- - +/// Work out what things on the right-han-side of a 'let rec' recursive binding need to be fixed up val IterateRecursiveFixups : TcGlobals -> Val option -> (Val option -> Expr -> (Expr -> Expr) -> Expr -> unit) -> Expr * (Expr -> Expr) -> Expr -> unit -//------------------------------------------------------------------------- -// From lambdas taking multiple variables to lambdas taking a single variable -// of tuple type. -//------------------------------------------------------------------------- - +/// Given a lambda expression taking multiple variables, build a corresponding lambda taking a tuple val MultiLambdaToTupledLambda : TcGlobals -> Val list -> Expr -> Val * Expr -val AdjustArityOfLambdaBody : TcGlobals -> int -> Val list -> Expr -> Val list * Expr -//------------------------------------------------------------------------- -// Make applications, doing beta reduction by introducing let-bindings -//------------------------------------------------------------------------- +/// Given a lambda expression, adjust it to have be one or two lambda expressions (fun a -> (fun b -> ...)) +/// where the first has the given arity. +val AdjustArityOfLambdaBody : TcGlobals -> int -> Val list -> Expr -> Val list * Expr +/// Make an application expression, doing beta reduction by introducing let-bindings val MakeApplicationAndBetaReduce : TcGlobals -> Expr * TType * TypeInst list * Exprs * range -> Expr +/// COmbine two static-resolution requirements on a type parameter val JoinTyparStaticReq : TyparStaticReq -> TyparStaticReq -> TyparStaticReq -//------------------------------------------------------------------------- -// More layout - this is for debugging -//------------------------------------------------------------------------- +/// Layout for internal compiler debugging purposes module DebugPrint = + /// A global flag indicating whether debug output should include ranges val layoutRanges : bool ref + + /// Convert a type to a string for debugging purposes val showType : TType -> string + + /// Convert an expression to a string for debugging purposes val showExpr : Expr -> string + /// Debug layout for a reference to a value val valRefL : ValRef -> layout + + /// Debug layout for a reference to a union case val unionCaseRefL : UnionCaseRef -> layout - val vspecAtBindL : Val -> layout + + /// Debug layout for an value definition at its binding site + val valAtBindL : Val -> layout + + /// Debug layout for an integer val intL : int -> layout + + /// Debug layout for a value definition val valL : Val -> layout + + /// Debug layout for a type parameter definition val typarDeclL : Typar -> layout + + /// Debug layout for a trait constraint val traitL : TraitConstraintInfo -> layout + + /// Debug layout for a type parameter val typarL : Typar -> layout + + /// Debug layout for a set of type parameters val typarsL : Typars -> layout + + /// Debug layout for a type val typeL : TType -> layout + + /// Debug layout for a method slot signature val slotSigL : SlotSig -> layout + + /// Debug layout for the type signature of a module or namespace definition val entityTypeL : ModuleOrNamespaceType -> layout + + /// Debug layout for a module or namespace definition val entityL : ModuleOrNamespace -> layout + + /// Debug layout for the type of a value val typeOfValL : Val -> layout + + /// Debug layout for a binding of an expression to a value val bindingL : Binding -> layout + + /// Debug layout for an expression val exprL : Expr -> layout + + /// Debug layout for a type definition val tyconL : Tycon -> layout + + /// Debug layout for a decision tree val decisionTreeL : DecisionTree -> layout + + /// Debug layout for an implementation file val implFileL : TypedImplFile -> layout + + /// Debug layout for a list of implementation files val implFilesL : TypedImplFile list -> layout - val recdFieldRefL : RecdFieldRef -> layout -//------------------------------------------------------------------------- -// Fold on expressions -//------------------------------------------------------------------------- + /// Debug layout for class and record fields + val recdFieldRefL : RecdFieldRef -> layout +/// A set of function parameters (visitor) for folding over expressions type ExprFolder<'State> = - { exprIntercept : ('State -> Expr -> 'State) -> 'State -> Expr -> 'State option; - valBindingSiteIntercept : 'State -> bool * Val -> 'State; - nonRecBindingsIntercept : 'State -> Binding -> 'State; - recBindingsIntercept : 'State -> Bindings -> 'State; - dtreeIntercept : 'State -> DecisionTree -> 'State; - targetIntercept : ('State -> Expr -> 'State) -> 'State -> DecisionTreeTarget -> 'State option; - tmethodIntercept : ('State -> Expr -> 'State) -> 'State -> ObjExprMethod -> 'State option;} + { exprIntercept : ('State -> Expr -> 'State) -> 'State -> Expr -> 'State option + valBindingSiteIntercept : 'State -> bool * Val -> 'State + nonRecBindingsIntercept : 'State -> Binding -> 'State + recBindingsIntercept : 'State -> Bindings -> 'State + dtreeIntercept : 'State -> DecisionTree -> 'State + targetIntercept : ('State -> Expr -> 'State) -> 'State -> DecisionTreeTarget -> 'State option + tmethodIntercept : ('State -> Expr -> 'State) -> 'State -> ObjExprMethod -> 'State option} + +/// The empty set of actions for folding over expressions val ExprFolder0 : ExprFolder<'State> + +/// Fold over all the expressions in an implementation file val FoldImplFile: ExprFolder<'State> -> ('State -> TypedImplFile -> 'State) + +/// Fold over all the expressions in an expression val FoldExpr : ExprFolder<'State> -> ('State -> Expr -> 'State) #if DEBUG +/// Extract some statistics from an expression val ExprStats : Expr -> string #endif -//------------------------------------------------------------------------- -// Make some common types -//------------------------------------------------------------------------- - +/// Build a nativeptr type val mkNativePtrTy : TcGlobals -> TType -> TType + +/// Build a 'voidptr' type val mkVoidPtrTy : TcGlobals -> TType + +/// Build a single-dimensional array type val mkArrayType : TcGlobals -> TType -> TType + +/// Determine is a type is an option type val isOptionTy : TcGlobals -> TType -> bool + +/// Take apart an option type val destOptionTy : TcGlobals -> TType -> TType -val tryDestOptionTy : TcGlobals -> TType -> TType option +/// Try to take apart an option type +val tryDestOptionTy : TcGlobals -> TType -> ValueOption + +/// Determine if a type is a System.Linq.Expression type val isLinqExpressionTy : TcGlobals -> TType -> bool -val destLinqExpressionTy : TcGlobals -> TType -> TType -val tryDestLinqExpressionTy : TcGlobals -> TType -> TType option -(* -val isQuoteExprTy : TcGlobals -> TType -> bool -val destQuoteExprTy : TcGlobals -> TType -> TType -val tryDestQuoteExprTy : TcGlobals -> TType -> TType option -*) +/// Take apart a System.Linq.Expression type +val destLinqExpressionTy : TcGlobals -> TType -> TType -//------------------------------------------------------------------------- -// Primitives associated with compiling the IEvent idiom to .NET events -//------------------------------------------------------------------------- +/// Try to take apart a System.Linq.Expression type +val tryDestLinqExpressionTy : TcGlobals -> TType -> TType option +/// Determine if a type is an IDelegateEvent type val isIDelegateEventType : TcGlobals -> TType -> bool + +/// Take apart an IDelegateEvent type val destIDelegateEventType : TcGlobals -> TType -> TType + +/// Build an IEvent type val mkIEventType : TcGlobals -> TType -> TType -> TType + +/// Build an IObservable type val mkIObservableType : TcGlobals -> TType -> TType -val mkIObserverType : TcGlobals -> TType -> TType -//------------------------------------------------------------------------- -// Primitives associated with printf format string parsing -//------------------------------------------------------------------------- +/// Build an IObserver type +val mkIObserverType : TcGlobals -> TType -> TType +/// Build an Lazy type val mkLazyTy : TcGlobals -> TType -> TType + +/// Build an PrintFormat type val mkPrintfFormatTy : TcGlobals -> TType -> TType -> TType -> TType -> TType -> TType //------------------------------------------------------------------------- // Classify types //------------------------------------------------------------------------- +/// Represents metadata extracted from a nominal type type TypeDefMetadata = | ILTypeMetadata of TILObjectReprData | FSharpOrArrayOrByrefOrTupleOrExnTypeMetadata @@ -1064,43 +1439,94 @@ type TypeDefMetadata = | ProvidedTypeMetadata of TProvidedTypeInfo #endif +/// Extract metadata from a type definition val metadataOfTycon : Tycon -> TypeDefMetadata + +/// Extract metadata from a type val metadataOfTy : TcGlobals -> TType -> TypeDefMetadata -val isStringTy : TcGlobals -> TType -> bool -val isListTy : TcGlobals -> TType -> bool -val isILAppTy : TcGlobals -> TType -> bool -val isArrayTy : TcGlobals -> TType -> bool -val isArray1DTy : TcGlobals -> TType -> bool -val destArrayTy : TcGlobals -> TType -> TType -val destListTy : TcGlobals -> TType -> TType +/// Determine if a type is the System.String type +val isStringTy : TcGlobals -> TType -> bool + +/// Determine if a type is an F# list type +val isListTy : TcGlobals -> TType -> bool + +/// Determine if a type is a nominal .NET type +val isILAppTy : TcGlobals -> TType -> bool + +/// Determine if a type is any kind of array type +val isArrayTy : TcGlobals -> TType -> bool + +/// Determine if a type is a single-dimensional array type +val isArray1DTy : TcGlobals -> TType -> bool + +/// Get the element type of an array type +val destArrayTy : TcGlobals -> TType -> TType + +/// Get the element type of an F# list type +val destListTy : TcGlobals -> TType -> TType + +/// Build an array type of the given rank +val mkArrayTy : TcGlobals -> int -> TType -> range -> TType -val mkArrayTy : TcGlobals -> int -> TType -> range -> TType -val isArrayTyconRef : TcGlobals -> TyconRef -> bool +/// Check if a type definition is one of the artifical type definitions used for array types of different ranks +val isArrayTyconRef : TcGlobals -> TyconRef -> bool + +/// Determine the rank of one of the artifical type definitions used for array types val rankOfArrayTyconRef : TcGlobals -> TyconRef -> int -val isUnitTy : TcGlobals -> TType -> bool -val isObjTy : TcGlobals -> TType -> bool -val isVoidTy : TcGlobals -> TType -> bool +/// Determine if a type is the F# unit type +val isUnitTy : TcGlobals -> TType -> bool + +/// Determine if a type is the System.Object type +val isObjTy : TcGlobals -> TType -> bool + +/// Determine if a type is the System.Void type +val isVoidTy : TcGlobals -> TType -> bool /// Get the element type of an array type -val destArrayTy : TcGlobals -> TType -> TType +val destArrayTy : TcGlobals -> TType -> TType + /// Get the rank of an array type val rankOfArrayTy : TcGlobals -> TType -> int -val isInterfaceTyconRef : TyconRef -> bool +/// Determine if a reference to a type definition is an interface type +val isInterfaceTyconRef : TyconRef -> bool + +/// Determine if a type is a delegate type +val isDelegateTy : TcGlobals -> TType -> bool + +/// Determine if a type is an interface type +val isInterfaceTy : TcGlobals -> TType -> bool + +/// Determine if a type is a FSharpRef type +val isRefTy : TcGlobals -> TType -> bool -val isDelegateTy : TcGlobals -> TType -> bool -val isInterfaceTy : TcGlobals -> TType -> bool -val isRefTy : TcGlobals -> TType -> bool -val isSealedTy : TcGlobals -> TType -> bool -val isComInteropTy : TcGlobals -> TType -> bool -val underlyingTypeOfEnumTy : TcGlobals -> TType -> TType -val normalizeEnumTy : TcGlobals -> TType -> TType +/// Determine if a type is a sealed type +val isSealedTy : TcGlobals -> TType -> bool + +/// Determine if a type is a ComInterop type +val isComInteropTy : TcGlobals -> TType -> bool + +/// Determine the underlying type of an enum type (normally int32) +val underlyingTypeOfEnumTy : TcGlobals -> TType -> TType + +/// If the input type is an enum type, then convert to its underlying type, otherwise return the input type +val normalizeEnumTy : TcGlobals -> TType -> TType + +/// Determine if a type is a struct type val isStructTy : TcGlobals -> TType -> bool + +/// Determine if a type is an unmanaged type val isUnmanagedTy : TcGlobals -> TType -> bool + +/// Determine if a type is a class type val isClassTy : TcGlobals -> TType -> bool + +/// Determine if a type is an enum type val isEnumTy : TcGlobals -> TType -> bool + +/// Determine if a type is a struct, record or union type val isStructRecordOrUnionTyconTy : TcGlobals -> TType -> bool /// For "type Class as self", 'self' is fixed up after initialization. To support this, @@ -1108,9 +1534,16 @@ val isStructRecordOrUnionTyconTy : TcGlobals -> TType -> bool /// returns the underlying type. val StripSelfRefCell : TcGlobals * ValBaseOrThisInfo * TType -> TType +/// An active pattern to determine if a type is a nominal type, possibly instantiated val (|AppTy|_|) : TcGlobals -> TType -> (TyconRef * TType list) option + +/// An active pattern to match System.Nullable types val (|NullableTy|_|) : TcGlobals -> TType -> TType option + +/// An active pattern to transform System.Nullable types to their input, otherwise leave the input unchanged val (|StripNullableTy|) : TcGlobals -> TType -> TType + +/// Matches any byref type, yielding the target type val (|ByrefTy|_|) : TcGlobals -> TType -> TType option //------------------------------------------------------------------------- @@ -1118,35 +1551,53 @@ val (|ByrefTy|_|) : TcGlobals -> TType -> TType option //------------------------------------------------------------------------- val IsUnionTypeWithNullAsTrueValue: TcGlobals -> Tycon -> bool + val TyconHasUseNullAsTrueValueAttribute : TcGlobals -> Tycon -> bool + val CanHaveUseNullAsTrueValueAttribute : TcGlobals -> Tycon -> bool + val MemberIsCompiledAsInstance : TcGlobals -> TyconRef -> bool -> ValMemberInfo -> Attribs -> bool + val ValSpecIsCompiledAsInstance : TcGlobals -> Val -> bool + val ValRefIsCompiledAsInstanceMember : TcGlobals -> ValRef -> bool + val ModuleNameIsMangled : TcGlobals -> Attribs -> bool val CompileAsEvent : TcGlobals -> Attribs -> bool val TypeNullIsExtraValue : TcGlobals -> range -> TType -> bool + val TypeNullIsTrueValue : TcGlobals -> TType -> bool + val TypeNullNotLiked : TcGlobals -> range -> TType -> bool + val TypeNullNever : TcGlobals -> TType -> bool val TypeSatisfiesNullConstraint : TcGlobals -> range -> TType -> bool + val TypeHasDefaultValue : TcGlobals -> range -> TType -> bool val isAbstractTycon : Tycon -> bool val isUnionCaseRefDefinitelyMutable : UnionCaseRef -> bool + val isRecdOrUnionOrStructTyconRefDefinitelyMutable : TyconRef -> bool + val isExnDefinitelyMutable : TyconRef -> bool + val isUnionCaseFieldMutable : TcGlobals -> UnionCaseRef -> int -> bool + val isExnFieldMutable : TyconRef -> int -> bool + val isRecdOrStructTyconRefReadOnly: TcGlobals -> range -> TyconRef -> bool + val isRecdOrStructTyconRefAssumedImmutable: TcGlobals -> TyconRef -> bool + val isRecdOrStructTyReadOnly: TcGlobals -> range -> TType -> bool val useGenuineField : Tycon -> RecdField -> bool + val ComputeFieldName : Tycon -> RecdField -> string //------------------------------------------------------------------------- @@ -1154,6 +1605,7 @@ val ComputeFieldName : Tycon -> RecdField -> string //------------------------------------------------------------------------- val slotSigHasVoidReturnTy : SlotSig -> bool + val actualReturnTyOfSlotSig : TypeInst -> TypeInst -> SlotSig -> TType option val returnTyOfMethod : TcGlobals -> ObjExprMethod -> TType option @@ -1163,25 +1615,37 @@ val returnTyOfMethod : TcGlobals -> ObjExprMethod -> TType option //------------------------------------------------------------------------- val mkRefCell : TcGlobals -> range -> TType -> Expr -> Expr + val mkRefCellGet : TcGlobals -> range -> TType -> Expr -> Expr + val mkRefCellSet : TcGlobals -> range -> TType -> Expr -> Expr -> Expr + val mkLazyDelayed : TcGlobals -> range -> TType -> Expr -> Expr -val mkLazyForce : TcGlobals -> range -> TType -> Expr -> Expr +val mkLazyForce : TcGlobals -> range -> TType -> Expr -> Expr val mkRefCellContentsRef : TcGlobals -> RecdFieldRef + val isRefCellTy : TcGlobals -> TType -> bool + val destRefCellTy : TcGlobals -> TType -> TType + val mkRefCellTy : TcGlobals -> TType -> TType val mkSeqTy : TcGlobals -> TType -> TType + val mkIEnumeratorTy : TcGlobals -> TType -> TType + val mkListTy : TcGlobals -> TType -> TType + val mkOptionTy : TcGlobals -> TType -> TType + val mkNoneCase : TcGlobals -> UnionCaseRef + val mkSomeCase : TcGlobals -> UnionCaseRef val mkNil : TcGlobals -> range -> TType -> Expr + val mkCons : TcGlobals -> TType -> Expr -> Expr -> Expr //------------------------------------------------------------------------- @@ -1189,17 +1653,29 @@ val mkCons : TcGlobals -> TType -> Expr -> Expr -> Expr //------------------------------------------------------------------------- val mkSequential : SequencePointInfoForSeq -> range -> Expr -> Expr -> Expr + val mkCompGenSequential : range -> Expr -> Expr -> Expr + val mkSequentials : SequencePointInfoForSeq -> TcGlobals -> range -> Exprs -> Expr + val mkRecordExpr : TcGlobals -> RecordConstructionInfo * TyconRef * TypeInst * RecdFieldRef list * Exprs * range -> Expr + val mkUnbox : TType -> Expr -> range -> Expr + val mkBox : TType -> Expr -> range -> Expr + val mkIsInst : TType -> Expr -> range -> Expr + val mkNull : range -> TType -> Expr + val mkNullTest : TcGlobals -> range -> Expr -> Expr -> Expr -> Expr + val mkNonNullTest : TcGlobals -> range -> Expr -> Expr + val mkIsInstConditional : TcGlobals -> range -> TType -> Expr -> Val -> Expr -> Expr -> Expr + val mkThrow : range -> TType -> Expr -> Expr + val mkGetArg0 : range -> TType -> Expr val mkDefault : range * TType -> Expr @@ -1207,18 +1683,31 @@ val mkDefault : range * TType -> Expr val isThrow : Expr -> bool val mkString : TcGlobals -> range -> string -> Expr + val mkBool : TcGlobals -> range -> bool -> Expr + val mkByte : TcGlobals -> range -> byte -> Expr + val mkUInt16 : TcGlobals -> range -> uint16 -> Expr + val mkTrue : TcGlobals -> range -> Expr + val mkFalse : TcGlobals -> range -> Expr + val mkUnit : TcGlobals -> range -> Expr + val mkInt32 : TcGlobals -> range -> int32 -> Expr + val mkInt : TcGlobals -> range -> int -> Expr + val mkZero : TcGlobals -> range -> Expr + val mkOne : TcGlobals -> range -> Expr + val mkTwo : TcGlobals -> range -> Expr + val mkMinusOne : TcGlobals -> range -> Expr + val destInt32 : Expr -> int32 option //------------------------------------------------------------------------- @@ -1226,8 +1715,11 @@ val destInt32 : Expr -> int32 option //------------------------------------------------------------------------- val isQuotedExprTy : TcGlobals -> TType -> bool + val destQuotedExprTy : TcGlobals -> TType -> TType + val mkQuotedExprTy : TcGlobals -> TType -> TType + val mkRawQuotedExprTy : TcGlobals -> TType //------------------------------------------------------------------------- @@ -1235,9 +1727,13 @@ val mkRawQuotedExprTy : TcGlobals -> TType //------------------------------------------------------------------------- val mspec_Type_GetTypeFromHandle : TcGlobals -> ILMethodSpec + val fspec_Missing_Value : TcGlobals -> ILFieldSpec + val mkInitializeArrayMethSpec: TcGlobals -> ILMethodSpec + val mkByteArrayTy : TcGlobals -> TType + val mkInvalidCastExnNewobj: TcGlobals -> ILInstr @@ -1248,122 +1744,207 @@ val mkInvalidCastExnNewobj: TcGlobals -> ILInstr val mkCallNewFormat : TcGlobals -> range -> TType -> TType -> TType -> TType -> TType -> Expr -> Expr val mkCallUnbox : TcGlobals -> range -> TType -> Expr -> Expr + val mkCallGetGenericComparer : TcGlobals -> range -> Expr + val mkCallGetGenericEREqualityComparer : TcGlobals -> range -> Expr + val mkCallGetGenericPEREqualityComparer : TcGlobals -> range -> Expr val mkCallUnboxFast : TcGlobals -> range -> TType -> Expr -> Expr + val canUseUnboxFast : TcGlobals -> range -> TType -> bool val mkCallDispose : TcGlobals -> range -> TType -> Expr -> Expr + val mkCallSeq : TcGlobals -> range -> TType -> Expr -> Expr val mkCallTypeTest : TcGlobals -> range -> TType -> Expr -> Expr + val canUseTypeTestFast : TcGlobals -> TType -> bool val mkCallTypeOf : TcGlobals -> range -> TType -> Expr + val mkCallTypeDefOf : TcGlobals -> range -> TType -> Expr val mkCallCreateInstance : TcGlobals -> range -> TType -> Expr + val mkCallCreateEvent : TcGlobals -> range -> TType -> TType -> Expr -> Expr -> Expr -> Expr + val mkCallArrayLength : TcGlobals -> range -> TType -> Expr -> Expr + val mkCallArrayGet : TcGlobals -> range -> TType -> Expr -> Expr -> Expr + val mkCallArray2DGet : TcGlobals -> range -> TType -> Expr -> Expr -> Expr -> Expr + val mkCallArray3DGet : TcGlobals -> range -> TType -> Expr -> Expr -> Expr -> Expr -> Expr + val mkCallArray4DGet : TcGlobals -> range -> TType -> Expr -> Expr -> Expr -> Expr -> Expr -> Expr + val mkCallArraySet : TcGlobals -> range -> TType -> Expr -> Expr -> Expr -> Expr + val mkCallArray2DSet : TcGlobals -> range -> TType -> Expr -> Expr -> Expr -> Expr -> Expr + val mkCallArray3DSet : TcGlobals -> range -> TType -> Expr -> Expr -> Expr -> Expr -> Expr -> Expr + val mkCallArray4DSet : TcGlobals -> range -> TType -> Expr -> Expr -> Expr -> Expr -> Expr -> Expr -> Expr val mkCallHash : TcGlobals -> range -> TType -> Expr -> Expr + val mkCallBox : TcGlobals -> range -> TType -> Expr -> Expr + val mkCallIsNull : TcGlobals -> range -> TType -> Expr -> Expr + val mkCallIsNotNull : TcGlobals -> range -> TType -> Expr -> Expr + val mkCallRaise : TcGlobals -> range -> TType -> Expr -> Expr val mkCallGenericComparisonWithComparerOuter : TcGlobals -> range -> TType -> Expr -> Expr -> Expr -> Expr + val mkCallGenericEqualityEROuter : TcGlobals -> range -> TType -> Expr -> Expr -> Expr + val mkCallGenericEqualityWithComparerOuter : TcGlobals -> range -> TType -> Expr -> Expr -> Expr -> Expr + val mkCallGenericHashWithComparerOuter : TcGlobals -> range -> TType -> Expr -> Expr -> Expr val mkCallEqualsOperator : TcGlobals -> range -> TType -> Expr -> Expr -> Expr + val mkCallNotEqualsOperator : TcGlobals -> range -> TType -> Expr -> Expr -> Expr + val mkCallLessThanOperator : TcGlobals -> range -> TType -> Expr -> Expr -> Expr + val mkCallLessThanOrEqualsOperator : TcGlobals -> range -> TType -> Expr -> Expr -> Expr + val mkCallGreaterThanOperator : TcGlobals -> range -> TType -> Expr -> Expr -> Expr + val mkCallGreaterThanOrEqualsOperator : TcGlobals -> range -> TType -> Expr -> Expr -> Expr val mkCallAdditionOperator : TcGlobals -> range -> TType -> Expr -> Expr -> Expr + val mkCallSubtractionOperator : TcGlobals -> range -> TType -> Expr -> Expr -> Expr + val mkCallMultiplyOperator : TcGlobals -> range -> TType -> Expr -> Expr -> Expr + val mkCallDivisionOperator : TcGlobals -> range -> TType -> Expr -> Expr -> Expr + val mkCallModulusOperator : TcGlobals -> range -> TType -> Expr -> Expr -> Expr + val mkCallBitwiseAndOperator : TcGlobals -> range -> TType -> Expr -> Expr -> Expr + val mkCallBitwiseOrOperator : TcGlobals -> range -> TType -> Expr -> Expr -> Expr + val mkCallBitwiseXorOperator : TcGlobals -> range -> TType -> Expr -> Expr -> Expr + val mkCallShiftLeftOperator : TcGlobals -> range -> TType -> Expr -> Expr -> Expr + val mkCallShiftRightOperator : TcGlobals -> range -> TType -> Expr -> Expr -> Expr val mkCallUnaryNegOperator : TcGlobals -> range -> TType -> Expr -> Expr + val mkCallUnaryNotOperator : TcGlobals -> range -> TType -> Expr -> Expr val mkCallAdditionChecked : TcGlobals -> range -> TType -> Expr -> Expr -> Expr + val mkCallSubtractionChecked : TcGlobals -> range -> TType -> Expr -> Expr -> Expr + val mkCallMultiplyChecked : TcGlobals -> range -> TType -> Expr -> Expr -> Expr + val mkCallUnaryNegChecked : TcGlobals -> range -> TType -> Expr -> Expr val mkCallToByteChecked : TcGlobals -> range -> TType -> Expr -> Expr + val mkCallToSByteChecked : TcGlobals -> range -> TType -> Expr -> Expr + val mkCallToInt16Checked : TcGlobals -> range -> TType -> Expr -> Expr + val mkCallToUInt16Checked : TcGlobals -> range -> TType -> Expr -> Expr + val mkCallToIntChecked : TcGlobals -> range -> TType -> Expr -> Expr + val mkCallToInt32Checked : TcGlobals -> range -> TType -> Expr -> Expr + val mkCallToUInt32Checked : TcGlobals -> range -> TType -> Expr -> Expr + val mkCallToInt64Checked : TcGlobals -> range -> TType -> Expr -> Expr + val mkCallToUInt64Checked : TcGlobals -> range -> TType -> Expr -> Expr + val mkCallToIntPtrChecked : TcGlobals -> range -> TType -> Expr -> Expr + val mkCallToUIntPtrChecked : TcGlobals -> range -> TType -> Expr -> Expr val mkCallToByteOperator : TcGlobals -> range -> TType -> Expr -> Expr + val mkCallToSByteOperator : TcGlobals -> range -> TType -> Expr -> Expr + val mkCallToInt16Operator : TcGlobals -> range -> TType -> Expr -> Expr + val mkCallToUInt16Operator : TcGlobals -> range -> TType -> Expr -> Expr + val mkCallToIntOperator : TcGlobals -> range -> TType -> Expr -> Expr + val mkCallToInt32Operator : TcGlobals -> range -> TType -> Expr -> Expr + val mkCallToUInt32Operator : TcGlobals -> range -> TType -> Expr -> Expr + val mkCallToInt64Operator : TcGlobals -> range -> TType -> Expr -> Expr + val mkCallToUInt64Operator : TcGlobals -> range -> TType -> Expr -> Expr + val mkCallToSingleOperator : TcGlobals -> range -> TType -> Expr -> Expr + val mkCallToDoubleOperator : TcGlobals -> range -> TType -> Expr -> Expr + val mkCallToIntPtrOperator : TcGlobals -> range -> TType -> Expr -> Expr + val mkCallToUIntPtrOperator : TcGlobals -> range -> TType -> Expr -> Expr val mkCallToCharOperator : TcGlobals -> range -> TType -> Expr -> Expr + val mkCallToEnumOperator : TcGlobals -> range -> TType -> Expr -> Expr val mkCallDeserializeQuotationFSharp20Plus : TcGlobals -> range -> Expr -> Expr -> Expr -> Expr -> Expr + val mkCallDeserializeQuotationFSharp40Plus : TcGlobals -> range -> Expr -> Expr -> Expr -> Expr -> Expr -> Expr + val mkCallCastQuotation : TcGlobals -> range -> TType -> Expr -> Expr + val mkCallLiftValueWithName : TcGlobals -> range -> TType -> string -> Expr -> Expr + val mkCallLiftValueWithDefn : TcGlobals -> range -> TType -> Expr -> Expr + val mkCallSeqCollect : TcGlobals -> range -> TType -> TType -> Expr -> Expr -> Expr + val mkCallSeqUsing : TcGlobals -> range -> TType -> TType -> Expr -> Expr -> Expr + val mkCallSeqDelay : TcGlobals -> range -> TType -> Expr -> Expr + val mkCallSeqAppend : TcGlobals -> range -> TType -> Expr -> Expr -> Expr + val mkCallSeqFinally : TcGlobals -> range -> TType -> Expr -> Expr -> Expr + val mkCallSeqGenerated : TcGlobals -> range -> TType -> Expr -> Expr -> Expr + val mkCallSeqOfFunctions : TcGlobals -> range -> TType -> TType -> Expr -> Expr -> Expr -> Expr + val mkCallSeqToArray : TcGlobals -> range -> TType -> Expr -> Expr + val mkCallSeqToList : TcGlobals -> range -> TType -> Expr -> Expr + val mkCallSeqMap : TcGlobals -> range -> TType -> TType -> Expr -> Expr -> Expr + val mkCallSeqSingleton : TcGlobals -> range -> TType -> Expr -> Expr + val mkCallSeqEmpty : TcGlobals -> range -> TType -> Expr + val mkILAsmCeq : TcGlobals -> range -> Expr -> Expr -> Expr + val mkILAsmClt : TcGlobals -> range -> Expr -> Expr -> Expr val mkCallFailInit : TcGlobals -> range -> Expr + val mkCallFailStaticInit : TcGlobals -> range -> Expr + val mkCallCheckThis : TcGlobals -> range -> TType -> Expr -> Expr val mkCase : DecisionTreeTest * DecisionTree -> DecisionTreeCase @@ -1371,18 +1952,30 @@ val mkCase : DecisionTreeTest * DecisionTree -> DecisionTreeCase val mkCallQuoteToLinqLambdaExpression : TcGlobals -> range -> TType -> Expr -> Expr val mkCallGetQuerySourceAsEnumerable : TcGlobals -> range -> TType -> TType -> Expr -> Expr + val mkCallNewQuerySource : TcGlobals -> range -> TType -> TType -> Expr -> Expr val mkArray : TType * Exprs * range -> Expr +val mkStaticCall_String_Concat2 : TcGlobals -> range -> Expr -> Expr -> Expr + +val mkStaticCall_String_Concat3 : TcGlobals -> range -> Expr -> Expr -> Expr -> Expr + +val mkStaticCall_String_Concat4 : TcGlobals -> range -> Expr -> Expr -> Expr -> Expr -> Expr + +val mkStaticCall_String_Concat_Array : TcGlobals -> range -> Expr -> Expr + //------------------------------------------------------------------------- // operations primarily associated with the optimization to fix // up loops to generate .NET code that does not include array bound checks //------------------------------------------------------------------------- val mkDecr : TcGlobals -> range -> Expr -> Expr + val mkIncr : TcGlobals -> range -> Expr -> Expr + val mkLdlen : TcGlobals -> range -> Expr -> Expr + val mkLdelem : TcGlobals -> range -> TType -> Expr -> Expr -> Expr //------------------------------------------------------------------------- @@ -1390,18 +1983,29 @@ val mkLdelem : TcGlobals -> range -> TType -> Expr -> Expr -> Expr //------------------------------------------------------------------------- val TryDecodeILAttribute : TcGlobals -> ILTypeRef -> ILAttributes -> (ILAttribElem list * ILAttributeNamedArg list) option + val TryFindILAttribute : BuiltinAttribInfo -> ILAttributes -> bool + val TryFindILAttributeOpt : BuiltinAttribInfo option -> ILAttributes -> bool val IsMatchingFSharpAttribute : TcGlobals -> BuiltinAttribInfo -> Attrib -> bool + val IsMatchingFSharpAttributeOpt : TcGlobals -> BuiltinAttribInfo option -> Attrib -> bool + val HasFSharpAttribute : TcGlobals -> BuiltinAttribInfo -> Attribs -> bool + val HasFSharpAttributeOpt : TcGlobals -> BuiltinAttribInfo option -> Attribs -> bool + val TryFindFSharpAttribute : TcGlobals -> BuiltinAttribInfo -> Attribs -> Attrib option + val TryFindFSharpAttributeOpt : TcGlobals -> BuiltinAttribInfo option -> Attribs -> Attrib option + val TryFindFSharpBoolAttribute : TcGlobals -> BuiltinAttribInfo -> Attribs -> bool option + val TryFindFSharpBoolAttributeAssumeFalse : TcGlobals -> BuiltinAttribInfo -> Attribs -> bool option + val TryFindFSharpStringAttribute : TcGlobals -> BuiltinAttribInfo -> Attribs -> string option + val TryFindFSharpInt32Attribute : TcGlobals -> BuiltinAttribInfo -> Attribs -> int32 option /// Try to find a specific attribute on a type definition, where the attribute accepts a string argument. @@ -1422,19 +2026,29 @@ val TryFindAttributeUsageAttribute : TcGlobals -> range -> TyconRef -> bool opti /// returns Some(assemblyName) for success val TryDecodeTypeProviderAssemblyAttr : ILGlobals -> ILAttribute -> string option #endif + val IsSignatureDataVersionAttr : ILAttribute -> bool + val TryFindAutoOpenAttr : IL.ILGlobals -> ILAttribute -> string option + val TryFindInternalsVisibleToAttr : IL.ILGlobals -> ILAttribute -> string option -val IsMatchingSignatureDataVersionAttr : IL.ILGlobals -> ILVersionInfo -> ILAttribute -> bool +val IsMatchingSignatureDataVersionAttr : IL.ILGlobals -> ILVersionInfo -> ILAttribute -> bool val mkCompilationMappingAttr : TcGlobals -> int -> ILAttribute val mkCompilationMappingAttrWithSeqNum : TcGlobals -> int -> int -> ILAttribute + + val mkCompilationMappingAttrWithVariantNumAndSeqNum : TcGlobals -> int -> int -> int -> ILAttribute + val mkCompilationMappingAttrForQuotationResource : TcGlobals -> string * ILTypeRef list -> ILAttribute + val mkCompilationArgumentCountsAttr : TcGlobals -> int list -> ILAttribute + val mkCompilationSourceNameAttr : TcGlobals -> string -> ILAttribute + val mkSignatureDataVersionAttr : TcGlobals -> ILVersionInfo -> ILAttribute + val mkCompilerGeneratedAttr : TcGlobals -> int -> ILAttribute //------------------------------------------------------------------------- @@ -1442,16 +2056,23 @@ val mkCompilerGeneratedAttr : TcGlobals -> int -> ILAtt //------------------------------------------------------------------------- val isInByrefTy : TcGlobals -> TType -> bool + val isOutByrefTy : TcGlobals -> TType -> bool + val isByrefTy : TcGlobals -> TType -> bool val isNativePtrTy : TcGlobals -> TType -> bool + val destByrefTy : TcGlobals -> TType -> TType + val destNativePtrTy : TcGlobals -> TType -> TType val isByrefTyconRef : TcGlobals -> TyconRef -> bool + val isByrefLikeTyconRef : TcGlobals -> range -> TyconRef -> bool + val isSpanLikeTyconRef : TcGlobals -> range -> TyconRef -> bool + val isByrefLikeTy : TcGlobals -> range -> TType -> bool /// Check if the type is a byref-like but not a byref. @@ -1462,26 +2083,37 @@ val isSpanLikeTy : TcGlobals -> range -> TType -> bool //------------------------------------------------------------------------- val isRefTupleExpr : Expr -> bool + val tryDestRefTupleExpr : Expr -> Exprs val mkAnyTupledTy : TcGlobals -> TupInfo -> TType list -> TType val mkAnyTupled : TcGlobals -> range -> TupInfo -> Exprs -> TType list -> Expr + val mkRefTupled : TcGlobals -> range -> Exprs -> TType list -> Expr + val mkRefTupledNoTypes : TcGlobals -> range -> Exprs -> Expr + val mkRefTupledTy : TcGlobals -> TType list -> TType + val mkRefTupledVarsTy : TcGlobals -> Val list -> TType + val mkRefTupledVars : TcGlobals -> range -> Val list -> Expr + val mkMethodTy : TcGlobals -> TType list list -> TType -> TType -//------------------------------------------------------------------------- -// -//------------------------------------------------------------------------- +val mkAnyAnonRecdTy : TcGlobals -> AnonRecdTypeInfo -> TType list -> TType + +val mkAnonRecd : TcGlobals -> range -> AnonRecdTypeInfo -> Exprs -> TType list -> Expr val AdjustValForExpectedArity : TcGlobals -> range -> ValRef -> ValUseFlag -> ValReprInfo -> Expr * TType + val AdjustValToTopVal : Val -> ParentRef -> ValReprInfo -> unit + val LinearizeTopMatch : TcGlobals -> ParentRef -> Expr -> Expr + val AdjustPossibleSubsumptionExpr : TcGlobals -> Expr -> Exprs -> (Expr * Exprs) option + val NormalizeAndAdjustPossibleSubsumptionExprs : TcGlobals -> Expr -> Expr //------------------------------------------------------------------------- @@ -1491,28 +2123,35 @@ val NormalizeAndAdjustPossibleSubsumptionExprs : TcGlobals -> Expr -> Expr val buildAccessPath : CompilationPath option -> string val XmlDocArgsEnc : TcGlobals -> Typars * Typars -> TType list -> string + val XmlDocSigOfVal : TcGlobals -> string -> Val -> string + val XmlDocSigOfUnionCase : (string list -> string) + val XmlDocSigOfField : (string list -> string) + val XmlDocSigOfProperty : (string list -> string) + val XmlDocSigOfTycon : (string list -> string) + val XmlDocSigOfSubModul : (string list -> string) + val XmlDocSigOfEntity : EntityRef -> string //--------------------------------------------------------------------------- // Resolve static optimizations //------------------------------------------------------------------------- + type StaticOptimizationAnswer = | Yes = 1y | No = -1y | Unknown = 0y + val DecideStaticOptimizations : TcGlobals -> StaticOptimization list -> StaticOptimizationAnswer -val mkStaticOptimizationExpr : TcGlobals -> StaticOptimization list * Expr * Expr * range -> Expr -//--------------------------------------------------------------------------- -// Build for loops -//------------------------------------------------------------------------- +val mkStaticOptimizationExpr : TcGlobals -> StaticOptimization list * Expr * Expr * range -> Expr +/// Build for loops val mkFastForLoop : TcGlobals -> SequencePointInfoForForLoop * range * Val * Expr * bool * Expr * Expr -> Expr //--------------------------------------------------------------------------- @@ -1523,12 +2162,15 @@ type ActivePatternElemRef with member Name : string val TryGetActivePatternInfo : ValRef -> PrettyNaming.ActivePatternInfo option + val mkChoiceCaseRef : TcGlobals -> range -> int -> int -> UnionCaseRef type PrettyNaming.ActivePatternInfo with + member Names : string list member ResultType : TcGlobals -> range -> TType list -> TType + member OverallType : TcGlobals -> range -> TType -> TType list -> TType val doesActivePatternHaveFreeTypars : TcGlobals -> ValRef -> bool @@ -1539,61 +2181,84 @@ val doesActivePatternHaveFreeTypars : TcGlobals -> ValRef -> bool [] type ExprRewritingEnv = - {PreIntercept: ((Expr -> Expr) -> Expr -> Expr option) option; - PostTransform: Expr -> Expr option; - PreInterceptBinding: ((Expr -> Expr) -> Binding -> Binding option) option; - IsUnderQuotations: bool } + { PreIntercept: ((Expr -> Expr) -> Expr -> Expr option) option + PostTransform: Expr -> Expr option + PreInterceptBinding: ((Expr -> Expr) -> Binding -> Binding option) option + IsUnderQuotations: bool } val RewriteExpr : ExprRewritingEnv -> Expr -> Expr + val RewriteImplFile : ExprRewritingEnv -> TypedImplFile -> TypedImplFile val IsGenericValWithGenericContraints: TcGlobals -> Val -> bool type Entity with + member HasInterface : TcGlobals -> TType -> bool + member HasOverride : TcGlobals -> string -> TType list -> bool + member HasMember : TcGlobals -> string -> TType list -> bool type EntityRef with + member HasInterface : TcGlobals -> TType -> bool + member HasOverride : TcGlobals -> string -> TType list -> bool + member HasMember : TcGlobals -> string -> TType list -> bool val (|AttribBitwiseOrExpr|_|) : TcGlobals -> Expr -> (Expr * Expr) option + val (|EnumExpr|_|) : TcGlobals -> Expr -> Expr option + val (|TypeOfExpr|_|) : TcGlobals -> Expr -> TType option + val (|TypeDefOfExpr|_|) : TcGlobals -> Expr -> TType option val EvalLiteralExprOrAttribArg: TcGlobals -> Expr -> Expr + val EvaledAttribExprEquality : TcGlobals -> Expr -> Expr -> bool + val IsSimpleSyntacticConstantExpr: TcGlobals -> Expr -> bool val (|ConstToILFieldInit|_|): Const -> ILFieldInit option val (|ExtractAttribNamedArg|_|) : string -> AttribNamedArg list -> AttribExpr option + val (|AttribInt32Arg|_|) : AttribExpr -> int32 option + val (|AttribInt16Arg|_|) : AttribExpr -> int16 option + val (|AttribBoolArg|_|) : AttribExpr -> bool option + val (|AttribStringArg|_|) : AttribExpr -> string option + val (|Int32Expr|_|) : Expr -> int32 option /// Determines types that are potentially known to satisfy the 'comparable' constraint and returns /// a set of residual types that must also satisfy the constraint val (|SpecialComparableHeadType|_|) : TcGlobals -> TType -> TType list option + val (|SpecialEquatableHeadType|_|) : TcGlobals -> TType -> TType list option + val (|SpecialNotEquatableHeadType|_|) : TcGlobals -> TType -> unit option type OptimizeForExpressionOptions = OptimizeIntRangesOnly | OptimizeAllForExpressions + val DetectAndOptimizeForExpression : TcGlobals -> OptimizeForExpressionOptions -> Expr -> Expr val TryEliminateDesugaredConstants : TcGlobals -> range -> Const -> Expr option val MemberIsExplicitImpl : TcGlobals -> ValMemberInfo -> bool + val ValIsExplicitImpl : TcGlobals -> Val -> bool + val ValRefIsExplicitImpl : TcGlobals -> ValRef -> bool val (|LinearMatchExpr|_|) : Expr -> (SequencePointInfoForBinding * range * DecisionTree * DecisionTreeTarget * Expr * SequencePointInfoForTarget * range * TType) option + val rebuildLinearMatchExpr : (SequencePointInfoForBinding * range * DecisionTree * DecisionTreeTarget * Expr * SequencePointInfoForTarget * range * TType) -> Expr val mkCoerceIfNeeded : TcGlobals -> tgtTy: TType -> srcTy: TType -> Expr -> Expr diff --git a/src/fsharp/TastPickle.fs b/src/fsharp/TastPickle.fs index 3f184165ad..14998cc882 100755 --- a/src/fsharp/TastPickle.fs +++ b/src/fsharp/TastPickle.fs @@ -36,16 +36,16 @@ type PickledDataWithReferences<'rawData> = { /// The data that uses a collection of CcuThunks internally RawData: 'rawData /// The assumptions that need to be fixed up - FixupThunks: list } + FixupThunks: CcuThunk [] } member x.Fixup loader = - x.FixupThunks |> List.iter (fun reqd -> reqd.Fixup(loader reqd.AssemblyName)) + x.FixupThunks |> Array.iter (fun reqd -> reqd.Fixup(loader reqd.AssemblyName)) x.RawData /// Like Fixup but loader may return None, in which case there is no fixup. member x.OptionalFixup loader = x.FixupThunks - |> List.iter(fun reqd-> + |> Array.iter(fun reqd-> match loader reqd.AssemblyName with | Some(loaded) -> reqd.Fixup(loaded) | None -> reqd.FixupOrphaned() ) @@ -113,9 +113,10 @@ type WriterState = { os: ByteBuffer oscope: CcuThunk occus: Table - otycons: NodeOutTable + oentities: NodeOutTable otypars: NodeOutTable ovals: NodeOutTable + oanoninfos: NodeOutTable ostrings: Table opubpaths: Table onlerefs: Table @@ -144,9 +145,10 @@ type ReaderState = { is: ByteStream iilscope: ILScopeRef iccus: InputTable - itycons: NodeInTable + ientities: NodeInTable itypars: NodeInTable ivals: NodeInTable + ianoninfos: NodeInTable istrings: InputTable ipubpaths: InputTable inlerefs: InputTable @@ -317,10 +319,13 @@ let u_used_space1 f st = let inline u_tup2 p1 p2 (st:ReaderState) = let a = p1 st in let b = p2 st in (a,b) + let inline u_tup3 p1 p2 p3 (st:ReaderState) = let a = p1 st in let b = p2 st in let c = p3 st in (a,b,c) + let inline u_tup4 p1 p2 p3 p4 (st:ReaderState) = let a = p1 st in let b = p2 st in let c = p3 st in let d = p4 st in (a,b,c,d) + let inline u_tup5 p1 p2 p3 p4 p5 (st:ReaderState) = let a = p1 st let b = p2 st @@ -328,32 +333,41 @@ let inline u_tup5 p1 p2 p3 p4 p5 (st:ReaderState) = let d = p4 st let e = p5 st (a,b,c,d,e) + let inline u_tup6 p1 p2 p3 p4 p5 p6 (st:ReaderState) = let a = p1 st in let b = p2 st in let c = p3 st in let d = p4 st in let e = p5 st in let f = p6 st in (a,b,c,d,e,f) + let inline u_tup7 p1 p2 p3 p4 p5 p6 p7 (st:ReaderState) = let a = p1 st in let b = p2 st in let c = p3 st in let d = p4 st in let e = p5 st in let f = p6 st in let x7 = p7 st in (a,b,c,d,e,f,x7) + let inline u_tup8 p1 p2 p3 p4 p5 p6 p7 p8 (st:ReaderState) = let a = p1 st in let b = p2 st in let c = p3 st in let d = p4 st in let e = p5 st in let f = p6 st in let x7 = p7 st in let x8 = p8 st in (a,b,c,d,e,f,x7,x8) + let inline u_tup9 p1 p2 p3 p4 p5 p6 p7 p8 p9 (st:ReaderState) = let a = p1 st in let b = p2 st in let c = p3 st in let d = p4 st in let e = p5 st in let f = p6 st in let x7 = p7 st in let x8 = p8 st in let x9 = p9 st in (a,b,c,d,e,f,x7,x8,x9) + let inline u_tup10 p1 p2 p3 p4 p5 p6 p7 p8 p9 p10 (st:ReaderState) = let a = p1 st in let b = p2 st in let c = p3 st in let d = p4 st in let e = p5 st in let f = p6 st in let x7 = p7 st in let x8 = p8 st in let x9 = p9 st in let x10 = p10 st in (a,b,c,d,e,f,x7,x8,x9,x10) + let inline u_tup11 p1 p2 p3 p4 p5 p6 p7 p8 p9 p10 p11 (st:ReaderState) = let a = p1 st in let b = p2 st in let c = p3 st in let d = p4 st in let e = p5 st in let f = p6 st in let x7 = p7 st in let x8 = p8 st in let x9 = p9 st in let x10 = p10 st in let x11 = p11 st in (a,b,c,d,e,f,x7,x8,x9,x10,x11) + let inline u_tup12 p1 p2 p3 p4 p5 p6 p7 p8 p9 p10 p11 p12 (st:ReaderState) = let a = p1 st in let b = p2 st in let c = p3 st in let d = p4 st in let e = p5 st in let f = p6 st in let x7 = p7 st in let x8 = p8 st in let x9 = p9 st in let x10 = p10 st in let x11 = p11 st in let x12 = p12 st in (a,b,c,d,e,f,x7,x8,x9,x10,x11,x12) + let inline u_tup13 p1 p2 p3 p4 p5 p6 p7 p8 p9 p10 p11 p12 p13 (st:ReaderState) = let a = p1 st in let b = p2 st in let c = p3 st in let d = p4 st in let e = p5 st in let f = p6 st in let x7 = p7 st in let x8 = p8 st in let x9 = p9 st in let x10 = p10 st in let x11 = p11 st in let x12 = p12 st in let x13 = p13 st in (a,b,c,d,e,f,x7,x8,x9,x10,x11,x12,x13) + let inline u_tup14 p1 p2 p3 p4 p5 p6 p7 p8 p9 p10 p11 p12 p13 p14 (st:ReaderState) = let a = p1 st in let b = p2 st in let c = p3 st in let d = p4 st in let e = p5 st in let f = p6 st in let x7 = p7 st in let x8 = p8 st in @@ -391,7 +405,7 @@ let inline u_tup17 p1 p2 p3 p4 p5 p6 p7 p8 p9 p10 p11 p12 p13 p14 p15 p16 p17 (s // ctxt is for debugging let p_osgn_ref (_ctxt:string) (outMap : NodeOutTable<_,_>) x st = let idx = outMap.Table.FindOrAdd (outMap.NodeStamp x) - //if ((idx = 0) && outMap.Name = "otycons") then + //if ((idx = 0) && outMap.Name = "oentities") then // System.Diagnostics.Debug.Assert(false, sprintf "idx %d#%d in table %s has name '%s', was defined at '%s' and is referenced from context %s\n" idx (outMap.NodeStamp x) outMap.Name (outMap.NodeName x) (stringOfRange (outMap.GetRange x)) _ctxt) p_int idx st @@ -447,9 +461,21 @@ let p_array_ext extraf f (x: 'T[]) st = | Some f -> f st p_array_core f x st - -let p_list f x st = p_array f (Array.ofList x) st -let p_list_ext extraf f x st = p_array_ext extraf f (Array.ofList x) st +let p_list_core f (xs: 'T list) st = + for x in xs do + f x st + +let p_list f x st = + p_int (List.length x) st + p_list_core f x st +let p_list_ext extraf f x st = + let n = List.length x + let n = if Option.isSome extraf then n ||| 0x80000000 else n + p_int n st + match extraf with + | None -> () + | Some f -> f st + p_list_core f x st let p_List f (x: 'T list) st = p_list f x st @@ -479,7 +505,7 @@ let private p_lazy_impl p v st = let fixupPos7 = st.os.Position prim_p_int32 0 st let idx1 = st.os.Position - let otyconsIdx1 = st.otycons.Size + let otyconsIdx1 = st.oentities.Size let otyparsIdx1 = st.otypars.Size let ovalsIdx1 = st.ovals.Size // Run the pickler @@ -488,7 +514,7 @@ let private p_lazy_impl p v st = let idx2 = st.os.Position st.os.FixupInt32 fixupPos1 (idx2-idx1) // Determine and fixup the ranges of OSGN nodes defined within the lazy portion - let otyconsIdx2 = st.otycons.Size + let otyconsIdx2 = st.oentities.Size let otyparsIdx2 = st.otypars.Size let ovalsIdx2 = st.ovals.Size st.os.FixupInt32 fixupPos2 otyconsIdx1 @@ -534,8 +560,22 @@ let u_array_ext extraf f st = let arr = u_array_core f (n &&& 0x7FFFFFFF) st extraItem, arr -let u_list f st = Array.toList (u_array f st) -let u_list_ext extra f st = let v, res = u_array_ext extra f st in v, Array.toList res +let u_list_core f n st = + [ for _ in 1..n do + yield f st ] + +let u_list f st = + let n = u_int st + u_list_core f n st +let u_list_ext extra f st = + let n = u_int st + let extraItem = + if n &&& 0x80000000 = 0x80000000 then + Some (extra st) + else + None + let list = u_list_core f (n &&& 0x7FFFFFFF) st + extraItem, list #if FLAT_LIST_AS_LIST #else @@ -558,7 +598,10 @@ let u_array_revi f st = res // Mark up default constraints with a priority in reverse order: last gets 0 etc. See comment on TyparConstraint.DefaultsTo -let u_list_revi f st = Array.toList (u_array_revi f st) +let u_list_revi f st = + let n = u_int st + [ for i = 0 to n-1 do + yield f st (n-1-i) ] let u_wrap (f: 'U -> 'T) (u : 'U unpickler) : 'T unpickler = (fun st -> f (u st)) @@ -599,7 +642,7 @@ let u_lazy u st = lazy (let st = { st with is = st.is.CloneAndSeek idx1 } u st) /// Force the reading of the data as a "tripwire" for each of the OSGN thunks - for i = otyconsIdx1 to otyconsIdx2-1 do wire (st.itycons.Get(i)) res done + for i = otyconsIdx1 to otyconsIdx2-1 do wire (st.ientities.Get(i)) res done for i = ovalsIdx1 to ovalsIdx2-1 do wire (st.ivals.Get(i)) res done for i = otyparsIdx1 to otyparsIdx2-1 do wire (st.itypars.Get(i)) res done res @@ -692,21 +735,23 @@ let p_nleref x st = p_int (encode_nleref st.occus st.ostrings st.onlerefs st.osc let decode_simpletyp st _ccuTab _stringTab nlerefTab a = TType_app(ERefNonLocal (lookup_nleref st nlerefTab a),[]) let lookup_simpletyp st simpleTyTab x = lookup_uniq st simpleTyTab x let u_encoded_simpletyp st = u_int st +let u_encoded_anoninfo st = u_int st let u_simpletyp st = lookup_uniq st st.isimpletys (u_int st) let encode_simpletyp ccuTab stringTab nlerefTab simpleTyTab thisCcu a = encode_uniq simpleTyTab (encode_nleref ccuTab stringTab nlerefTab thisCcu a) let p_encoded_simpletyp x st = p_int x st +let p_encoded_anoninfo x st = p_int x st let p_simpletyp x st = p_int (encode_simpletyp st.occus st.ostrings st.onlerefs st.osimpletys st.oscope x) st -type sizes = int * int * int let pickleObjWithDanglingCcus inMem file g scope p x = - let ccuNameTab,(sizes: sizes),stringTab,pubpathTab,nlerefTab,simpleTyTab,phase1bytes = + let ccuNameTab,(ntycons, ntypars, nvals, nanoninfos),stringTab,pubpathTab,nlerefTab,simpleTyTab,phase1bytes = let st1 = { os = ByteBuffer.Create 100000 oscope=scope occus= Table<_>.Create "occus" - otycons=NodeOutTable<_,_>.Create((fun (tc:Tycon) -> tc.Stamp),(fun tc -> tc.LogicalName),(fun tc -> tc.Range),(fun osgn -> osgn),"otycons") + oentities=NodeOutTable<_,_>.Create((fun (tc:Tycon) -> tc.Stamp),(fun tc -> tc.LogicalName),(fun tc -> tc.Range),(fun osgn -> osgn),"otycons") otypars=NodeOutTable<_,_>.Create((fun (tp:Typar) -> tp.Stamp),(fun tp -> tp.DisplayName),(fun tp -> tp.Range),(fun osgn -> osgn),"otypars") ovals=NodeOutTable<_,_>.Create((fun (v:Val) -> v.Stamp),(fun v -> v.LogicalName),(fun v -> v.Range),(fun osgn -> osgn),"ovals") + oanoninfos=NodeOutTable<_,_>.Create((fun (v:AnonRecdTypeInfo) -> v.Stamp),(fun v -> string v.Stamp),(fun _ -> range0),id,"oanoninfos") ostrings=Table<_>.Create "ostrings" onlerefs=Table<_>.Create "onlerefs" opubpaths=Table<_>.Create "opubpaths" @@ -716,19 +761,21 @@ let pickleObjWithDanglingCcus inMem file g scope p x = oInMem=inMem } p x st1 let sizes = - st1.otycons.Size, + st1.oentities.Size, st1.otypars.Size, - st1.ovals.Size + st1.ovals.Size, + st1.oanoninfos.Size st1.occus, sizes, st1.ostrings, st1.opubpaths,st1.onlerefs, st1.osimpletys, st1.os.Close() - let phase2data = (ccuNameTab.AsArray,sizes,stringTab.AsArray,pubpathTab.AsArray,nlerefTab.AsArray,simpleTyTab.AsArray,phase1bytes) + let phase2bytes = let st2 = { os = ByteBuffer.Create 100000 oscope=scope occus= Table<_>.Create "occus (fake)" - otycons=NodeOutTable<_,_>.Create((fun (tc:Tycon) -> tc.Stamp),(fun tc -> tc.LogicalName),(fun tc -> tc.Range),(fun osgn -> osgn),"otycons") + oentities=NodeOutTable<_,_>.Create((fun (tc:Tycon) -> tc.Stamp),(fun tc -> tc.LogicalName),(fun tc -> tc.Range),(fun osgn -> osgn),"otycons") otypars=NodeOutTable<_,_>.Create((fun (tp:Typar) -> tp.Stamp),(fun tp -> tp.DisplayName),(fun tp -> tp.Range),(fun osgn -> osgn),"otypars") ovals=NodeOutTable<_,_>.Create((fun (v:Val) -> v.Stamp),(fun v -> v.LogicalName),(fun v -> v.Range),(fun osgn -> osgn),"ovals") + oanoninfos=NodeOutTable<_,_>.Create((fun (v:AnonRecdTypeInfo) -> v.Stamp),(fun v -> string v.Stamp),(fun _ -> range0),id,"oanoninfos") ostrings=Table<_>.Create "ostrings (fake)" opubpaths=Table<_>.Create "opubpaths (fake)" onlerefs=Table<_>.Create "onlerefs (fake)" @@ -736,15 +783,21 @@ let pickleObjWithDanglingCcus inMem file g scope p x = oglobals=g ofile=file oInMem=inMem } - p_tup7 - (p_array p_encoded_ccuref) - (p_tup3 p_int p_int p_int) - (p_array p_encoded_string) - (p_array p_encoded_pubpath) - (p_array p_encoded_nleref) - (p_array p_encoded_simpletyp) - p_bytes - phase2data st2 + p_array p_encoded_ccuref ccuNameTab.AsArray st2 + // Add a 4th integer indicated by a negative 1st integer + let z1 = if nanoninfos > 0 then -ntycons-1 else ntycons + p_int z1 st2 + p_tup2 p_int p_int (ntypars, nvals) st2 + if nanoninfos > 0 then + p_int nanoninfos st2 + p_tup5 + (p_array p_encoded_string) + (p_array p_encoded_pubpath) + (p_array p_encoded_nleref) + (p_array p_encoded_simpletyp) + p_bytes + (stringTab.AsArray,pubpathTab.AsArray,nlerefTab.AsArray,simpleTyTab.AsArray,phase1bytes) + st2 st2.os.Close() phase2bytes @@ -760,59 +813,62 @@ let unpickleObjWithDanglingCcus file ilscope (iILModule:ILModuleDef option) u (p { is = ByteStream.FromBytes (phase2bytes,0,phase2bytes.Length) iilscope= ilscope iccus= new_itbl "iccus (fake)" [| |] - itycons= NodeInTable<_,_>.Create (Tycon.NewUnlinked, (fun osgn tg -> osgn.Link tg),(fun osgn -> osgn.IsLinked),"itycons",0) + ientities= NodeInTable<_,_>.Create (Tycon.NewUnlinked, (fun osgn tg -> osgn.Link tg),(fun osgn -> osgn.IsLinked),"itycons",0) itypars= NodeInTable<_,_>.Create (Typar.NewUnlinked, (fun osgn tg -> osgn.Link tg),(fun osgn -> osgn.IsLinked),"itypars",0) ivals = NodeInTable<_,_>.Create (Val.NewUnlinked , (fun osgn tg -> osgn.Link tg),(fun osgn -> osgn.IsLinked),"ivals",0) + ianoninfos=NodeInTable<_,_>.Create(AnonRecdTypeInfo.NewUnlinked, (fun osgn tg -> osgn.Link tg),(fun osgn -> osgn.IsLinked),"ianoninfos",0); istrings = new_itbl "istrings (fake)" [| |] inlerefs = new_itbl "inlerefs (fake)" [| |] ipubpaths = new_itbl "ipubpaths (fake)" [| |] isimpletys = new_itbl "isimpletys (fake)" [| |] ifile=file iILModule = iILModule } - let phase2data = - u_tup7 - (u_array u_encoded_ccuref) - (u_tup3 u_int u_int u_int) - (u_array u_encoded_string) - (u_array u_encoded_pubpath) - (u_array u_encoded_nleref) - (u_array u_encoded_simpletyp) - u_bytes st2 - let ccuNameTab,sizes,stringTab,pubpathTab,nlerefTab,simpleTyTab,phase1bytes = phase2data + let ccuNameTab = u_array u_encoded_ccuref st2 + let z1 = u_int st2 + let ntycons = if z1 < 0 then -z1-1 else z1 + let ntypars, nvals = u_tup2 u_int u_int st2 + let nanoninfos = if z1 < 0 then u_int st2 else 0 + let stringTab,pubpathTab,nlerefTab,simpleTyTab,phase1bytes = + u_tup5 + (u_array u_encoded_string) + (u_array u_encoded_pubpath) + (u_array u_encoded_nleref) + (u_array u_encoded_simpletyp) + u_bytes + st2 let ccuTab = new_itbl "iccus" (Array.map (CcuThunk.CreateDelayed) ccuNameTab) let stringTab = new_itbl "istrings" (Array.map decode_string stringTab) let pubpathTab = new_itbl "ipubpaths" (Array.map (decode_pubpath st2 stringTab) pubpathTab) let nlerefTab = new_itbl "inlerefs" (Array.map (decode_nleref st2 ccuTab stringTab) nlerefTab) - let simpleTyTab = new_itbl "isimpletys" (Array.map (decode_simpletyp st2 ccuTab stringTab nlerefTab) simpleTyTab) - let ((ntycons,ntypars,nvals) : sizes) = sizes + let simpletypTab = new_itbl "simpleTyTab" (Array.map (decode_simpletyp st2 ccuTab stringTab nlerefTab) simpleTyTab) let data = let st1 = { is = ByteStream.FromBytes (phase1bytes,0,phase1bytes.Length) iccus= ccuTab iilscope= ilscope - itycons= NodeInTable<_,_>.Create(Tycon.NewUnlinked,(fun osgn tg -> osgn.Link tg),(fun osgn -> osgn.IsLinked),"itycons",ntycons) + ientities= NodeInTable<_,_>.Create(Tycon.NewUnlinked,(fun osgn tg -> osgn.Link tg),(fun osgn -> osgn.IsLinked),"itycons",ntycons) itypars= NodeInTable<_,_>.Create(Typar.NewUnlinked,(fun osgn tg -> osgn.Link tg),(fun osgn -> osgn.IsLinked),"itypars",ntypars) ivals= NodeInTable<_,_>.Create(Val.NewUnlinked ,(fun osgn tg -> osgn.Link tg),(fun osgn -> osgn.IsLinked),"ivals",nvals) + ianoninfos=NodeInTable<_,_>.Create(AnonRecdTypeInfo.NewUnlinked, (fun osgn tg -> osgn.Link tg),(fun osgn -> osgn.IsLinked),"ianoninfos",nanoninfos); istrings = stringTab ipubpaths = pubpathTab inlerefs = nlerefTab - isimpletys = simpleTyTab + isimpletys = simpletypTab ifile=file iILModule = iILModule } let res = u st1 -#if LAZY_UNPICKLE -#else - check ilscope st1.itycons +#if !LAZY_UNPICKLE + check ilscope st1.ientities check ilscope st1.ivals check ilscope st1.itypars #endif res - {RawData=data; FixupThunks=Array.toList ccuTab.itbl_rows } + {RawData=data; FixupThunks=ccuTab.itbl_rows } //========================================================================= -// PART II *) +// PART II //========================================================================= //--------------------------------------------------------------------------- @@ -823,7 +879,9 @@ let p_ILPublicKey x st = match x with | PublicKey b -> p_byte 0 st; p_bytes b st | PublicKeyToken b -> p_byte 1 st; p_bytes b st + let p_ILVersion x st = p_tup4 p_uint16 p_uint16 p_uint16 p_uint16 x st + let p_ILModuleRef (x:ILModuleRef) st = p_tup3 p_string p_bool (p_option p_bytes) (x.Name,x.HasMetadata,x.Hash) st @@ -947,8 +1005,11 @@ let rec u_ILType st = | 7 -> u_uint16 st |> mkILTyvarTy | 8 -> u_tup3 u_bool u_ILTypeRef u_ILType st |> ILType.Modified | _ -> ufailwith st "u_ILType" + and u_ILTypes st = u_list u_ILType st + and u_ILCallSig = u_wrap (fun (a,b,c) -> {CallingConv=a; ArgTypes=b; ReturnType=c}) (u_tup3 u_ILCallConv u_ILTypes u_ILType) + and u_ILTypeSpec st = let a,b = u_tup2 u_ILTypeRef u_ILTypes st in ILTypeSpec.Create(a,b) @@ -1244,7 +1305,7 @@ let p_local_item_ref ctxt tab st = p_osgn_ref ctxt tab st let p_tcref ctxt (x:EntityRef) st = match x with - | ERefLocal x -> p_byte 0 st; p_local_item_ref ctxt st.otycons x st + | ERefLocal x -> p_byte 0 st; p_local_item_ref ctxt st.oentities x st | ERefNonLocal x -> p_byte 1 st; p_nleref x st let p_ucref (UCRef(a,b)) st = p_tup2 (p_tcref "ucref") p_string (a,b) st @@ -1256,7 +1317,7 @@ let u_local_item_ref tab st = u_osgn_ref tab st let u_tcref st = let tag = u_byte st match tag with - | 0 -> u_local_item_ref st.itycons st |> ERefLocal + | 0 -> u_local_item_ref st.ientities st |> ERefLocal | 1 -> u_nleref st |> ERefNonLocal | _ -> ufailwith st "u_item_ref" @@ -1374,6 +1435,12 @@ let u_MemberFlags st = let fill_u_Expr_hole,u_expr_fwd = u_hole() let fill_p_Expr_hole,p_expr_fwd = p_hole() +let p_anonInfo_data (anonInfo: AnonRecdTypeInfo) st = + p_tup3 p_ccuref p_bool (p_array p_ident) (anonInfo.Assembly, evalTupInfoIsStruct anonInfo.TupInfo, anonInfo.SortedIds) st + +let p_anonInfo x st = + p_osgn_decl st.oanoninfos p_anonInfo_data x st + let p_trait_sln sln st = match sln with | ILMethSln(a,b,c,d) -> @@ -1386,10 +1453,20 @@ let p_trait_sln sln st = p_byte 3 st; p_expr_fwd expr st | FSRecdFieldSln(a,b,c) -> p_byte 4 st; p_tup3 p_tys p_rfref p_bool (a,b,c) st + | FSAnonRecdFieldSln(a, b, c) -> + p_byte 5 st; p_tup3 p_anonInfo p_tys p_int (a,b,c) st + let p_trait (TTrait(a,b,c,d,e,f)) st = p_tup6 p_tys p_string p_MemberFlags p_tys (p_option p_ty) (p_option p_trait_sln) (a,b,c,d,e,!f) st +let u_anonInfo_data st = + let (ccu, info, nms) = u_tup3 u_ccuref u_bool (u_array u_ident) st + AnonRecdTypeInfo.Create (ccu, mkTupInfo info, nms) + +let u_anonInfo st = + u_osgn_decl st.ianoninfos u_anonInfo_data st + // We have to store trait solutions since they can occur in optimization data let u_trait_sln st = let tag = u_byte st @@ -1407,6 +1484,9 @@ let u_trait_sln st = | 4 -> let (a,b,c) = u_tup3 u_tys u_rfref u_bool st FSRecdFieldSln(a,b,c) + | 5 -> + let (a,b,c) = u_tup3 u_anonInfo u_tys u_int st + FSAnonRecdFieldSln(a, b, c) | _ -> ufailwith st "u_trait_sln" let u_trait st = @@ -1417,7 +1497,9 @@ let u_trait st = let p_rational q st = p_int32 (GetNumerator q) st; p_int32 (GetDenominator q) st let p_measure_con tcref st = p_byte 0 st; p_tcref "measure" tcref st + let p_measure_var v st = p_byte 3 st; p_tpref v st + let p_measure_one = p_byte 4 // Pickle a unit-of-measure variable or constructor @@ -1527,7 +1609,6 @@ let p_tyar_spec_data (x:Typar) st = p_int64 p_tyar_constraints p_xmldoc - (x.typar_id,x.Attribs,int64 x.typar_flags.PickledBits,x.Constraints,x.XmlDoc) st let p_tyar_spec (x:Typar) st = @@ -1585,7 +1666,12 @@ let _ = fill_p_ty2 (fun isStructThisArgPos ty st -> // Note, the "this" argument may be found in the body of a generic forall type, so propagate the isStructThisArgPos value p_ty2 isStructThisArgPos r st | TType_measure unt -> p_byte 6 st; p_measure_expr unt st - | TType_ucase (uc,tinst) -> p_byte 7 st; p_tup2 p_ucref p_tys (uc,tinst) st) + | TType_ucase (uc,tinst) -> p_byte 7 st; p_tup2 p_ucref p_tys (uc,tinst) st + // p_byte 8 taken by TType_tuple above + | TType_anon (anonInfo, l) -> + p_byte 9 st + p_anonInfo anonInfo st + p_tys l st) let _ = fill_u_ty (fun st -> let tag = u_byte st @@ -1599,7 +1685,8 @@ let _ = fill_u_ty (fun st -> | 6 -> let unt = u_measure_expr st in TType_measure unt | 7 -> let uc = u_ucref st in let tinst = u_tys st in TType_ucase (uc,tinst) | 8 -> let l = u_tys st in TType_tuple (tupInfoStruct, l) - | _ -> ufailwith st "u_ty") + | 9 -> let anonInfo = u_anonInfo st in let l = u_tys st in TType_anon (anonInfo, l) + | _ -> ufailwith st "u_typ") let fill_p_binds,p_binds = p_hole() @@ -1675,7 +1762,7 @@ and p_tycon_repr x st = // The leading "p_byte 1" and "p_byte 0" come from the F# 2.0 format, which used an option value at this point. match x with | TRecdRepr fs -> p_byte 1 st; p_byte 0 st; p_rfield_table fs st; false - | TUnionRepr x -> p_byte 1 st; p_byte 1 st; p_list p_unioncase_spec (Array.toList x.CasesTable.CasesByIndex) st; false + | TUnionRepr x -> p_byte 1 st; p_byte 1 st; p_array p_unioncase_spec (x.CasesTable.CasesByIndex) st; false | TAsmRepr ilty -> p_byte 1 st; p_byte 2 st; p_ILType ilty st; false | TFSharpObjectRepr r -> p_byte 1 st; p_byte 3 st; p_tycon_objmodel_data r st; false | TMeasureableRepr ty -> p_byte 1 st; p_byte 4 st; p_ty ty st; false @@ -1717,7 +1804,7 @@ and p_exnc_repr x st = | TExnFresh x -> p_byte 2 st; p_rfield_table x st | TExnNone -> p_byte 3 st -and p_exnc_spec x st = p_tycon_spec x st +and p_exnc_spec x st = p_entity_spec x st and p_access (TAccess n) st = p_list p_cpath n st @@ -1735,7 +1822,7 @@ and p_recdfield_spec x st = p_access x.rfield_access st and p_rfield_table x st = - p_list p_recdfield_spec (Array.toList x.FieldsByIndex) st + p_array p_recdfield_spec (x.FieldsByIndex) st and p_entity_spec_data (x:Entity) st = p_tyar_specs (x.entity_typars.Force(x.entity_range)) st @@ -1789,7 +1876,7 @@ and p_tcaug p st = p.tcaug_abstract, space) st -and p_tycon_spec x st = p_osgn_decl st.otycons p_entity_spec_data x st +and p_entity_spec x st = p_osgn_decl st.oentities p_entity_spec_data x st and p_parentref x st = match x with @@ -1873,7 +1960,7 @@ and p_modul_typ (x: ModuleOrNamespaceType) st = p_tup3 p_istype (p_qlist p_Val) - (p_qlist p_tycon_spec) + (p_qlist p_entity_spec) (x.ModuleOrNamespaceKind,x.AllValsAndMembers,x.AllEntities) st @@ -1958,7 +2045,7 @@ and u_exnc_repr st = | 3 -> TExnNone | _ -> ufailwith st "u_exnc_repr" -and u_exnc_spec st = u_tycon_spec st +and u_exnc_spec st = u_entity_spec st and u_access st = match u_list u_cpath st with @@ -2065,8 +2152,8 @@ and u_tcaug st = tcaug_closed=true tcaug_abstract=g} -and u_tycon_spec st = - u_osgn_decl st.itycons u_entity_spec_data st +and u_entity_spec st = + u_osgn_decl st.ientities u_entity_spec_data st and u_parentref st = let tag = u_byte st @@ -2184,7 +2271,7 @@ and u_modul_typ st = u_tup3 u_istype (u_qlist u_Val) - (u_qlist u_tycon_spec) st + (u_qlist u_entity_spec) st ModuleOrNamespaceType(x1,x3,x5) @@ -2340,6 +2427,10 @@ and p_op x st = | TOp.UnionCaseFieldGetAddr (a,b, _) -> p_byte 28 st; p_tup2 p_ucref p_int (a,b) st // Note tag byte 29 is taken for struct tuples, see above // Note tag byte 30 is taken for struct tuples, see above + (* 29: TOp.Tuple when evalTupInfoIsStruct tupInfo = true *) + (* 30: TOp.TupleFieldGet when evalTupInfoIsStruct tupInfo = true *) + | TOp.AnonRecd info -> p_byte 31 st; p_anonInfo info st + | TOp.AnonRecdGet (info, n) -> p_byte 32 st; p_anonInfo info st; p_int n st | TOp.Goto _ | TOp.Label _ | TOp.Return -> failwith "unexpected backend construct in pickled TAST" and u_op st = @@ -2406,6 +2497,11 @@ and u_op st = | 29 -> TOp.Tuple tupInfoStruct | 30 -> let a = u_int st TOp.TupleFieldGet (tupInfoStruct, a) + | 31 -> let info = u_anonInfo st + TOp.AnonRecd (info) + | 32 -> let info = u_anonInfo st + let n = u_int st + TOp.AnonRecdGet (info, n) | _ -> ufailwith st "u_op" and p_expr expr st = @@ -2559,11 +2655,12 @@ let _ = fill_u_Vals (u_list u_Val) // Pickle/unpickle F# interface data //--------------------------------------------------------------------------- -let pickleModuleOrNamespace mspec st = p_tycon_spec mspec st +let pickleModuleOrNamespace mspec st = p_entity_spec mspec st + let pickleCcuInfo (minfo: PickledCcuInfo) st = p_tup4 pickleModuleOrNamespace p_string p_bool (p_space 3) (minfo.mspec, minfo.compileTimeWorkingDir, minfo.usesQuotations,()) st -let unpickleModuleOrNamespace st = u_tycon_spec st +let unpickleModuleOrNamespace st = u_entity_spec st let unpickleCcuInfo st = let a,b,c,_space = u_tup4 unpickleModuleOrNamespace u_string u_bool (u_space 3) st diff --git a/src/fsharp/TastPickle.fsi b/src/fsharp/TastPickle.fsi index 4bf6aca3ef..97eab4b30b 100644 --- a/src/fsharp/TastPickle.fsi +++ b/src/fsharp/TastPickle.fsi @@ -18,7 +18,7 @@ type PickledDataWithReferences<'RawData> = { /// The data that uses a collection of CcuThunks internally RawData: 'RawData /// The assumptions that need to be fixed up - FixupThunks: list } + FixupThunks: CcuThunk [] } member Fixup : (CcuReference -> CcuThunk) -> 'RawData /// Like Fixup but loader may return None, in which case there is no fixup. diff --git a/src/fsharp/TcGlobals.fs b/src/fsharp/TcGlobals.fs index d6fb7cd3c7..85f12f8b3f 100755 --- a/src/fsharp/TcGlobals.fs +++ b/src/fsharp/TcGlobals.fs @@ -255,7 +255,7 @@ type public TcGlobals(compilingFslib: bool, ilg:ILGlobals, fslibCcu: CcuThunk, d let path, typeName = splitILTypeName nm let scoref = match tryFindSysTypeCcu path typeName with - | None -> ILScopeRef.Assembly (mkSimpleAssRef (dummyAssemblyNameCarryingUsefulErrorInformation path typeName)) + | None -> ILScopeRef.Assembly (mkSimpleAssemblyRef (dummyAssemblyNameCarryingUsefulErrorInformation path typeName)) | Some ccu -> ccu.ILScopeRef mkILTyRef (scoref, nm) diff --git a/src/fsharp/TypeChecker.fs b/src/fsharp/TypeChecker.fs index badd093e4d..a20b3743ca 100755 --- a/src/fsharp/TypeChecker.fs +++ b/src/fsharp/TypeChecker.fs @@ -504,8 +504,8 @@ type cenv = /// Used to resolve names nameResolver: NameResolver - /// The set of active conditional defines - conditionalDefines: string list + /// The set of active conditional defines. The value is None when conditional erasure is disabled in tooling. + conditionalDefines: string list option isInternalTestSpanStackReferring: bool } @@ -707,38 +707,72 @@ let UnifyRefTupleType contextInfo cenv denv m ty ps = AddCxTypeEqualsType contextInfo denv cenv.css m ty (TType_tuple (tupInfoRef, ptys)) ptys -/// Optimized unification routine that avoids creating new inference -/// variables unnecessarily -let UnifyStructTupleType contextInfo cenv denv m ty ps = - let ptys = - if isStructTupleTy cenv.g ty then - let ptys = destStructTupleTy cenv.g ty - if List.length ps = List.length ptys then ptys - else NewInferenceTypes ps - else NewInferenceTypes ps - AddCxTypeEqualsType contextInfo denv cenv.css m ty (TType_tuple (tupInfoStruct, ptys)) +/// Allow the inference of structness from the known type, e.g. +/// let (x : struct (int * int)) = (3,4) +let UnifyTupleTypeAndInferCharacteristics contextInfo cenv denv m knownTy isExplicitStruct ps = + let tupInfo, ptys = + if isAnyTupleTy cenv.g knownTy then + let tupInfo, ptys = destAnyTupleTy cenv.g knownTy + let tupInfo = (if isExplicitStruct then tupInfoStruct else tupInfo) + let ptys = + if List.length ps = List.length ptys then ptys + else NewInferenceTypes ps + tupInfo, ptys + else + mkTupInfo isExplicitStruct, NewInferenceTypes ps + + let contextInfo = + match contextInfo with + | ContextInfo.RecordFields -> ContextInfo.TupleInRecordFields + | _ -> contextInfo + + let ty2 = TType_tuple (tupInfo, ptys) + AddCxTypeEqualsType contextInfo denv cenv.css m knownTy ty2 + tupInfo, ptys + +// Allow inference of assembly-affinity and structness from the known type - even from another assembly. This is a rule of +// the language design and allows effective cross-assembly use of anonymous types in some limited circumstances. +let UnifyAnonRecdTypeAndInferCharacteristics contextInfo cenv denv m ty isExplicitStruct unsortedNames = + let anonInfo, ptys = + match tryDestAnonRecdTy cenv.g ty with + | ValueSome (anonInfo, ptys) -> + // Note: use the assembly of the known type, not the current assembly + // Note: use the structness of the known type, unless explicit + // Note: use the names of our type, since they are always explicit + let tupInfo = (if isExplicitStruct then tupInfoStruct else anonInfo.TupInfo) + let anonInfo = AnonRecdTypeInfo.Create(anonInfo.Assembly, tupInfo, unsortedNames) + let ptys = + if List.length ptys = Array.length unsortedNames then ptys + else NewInferenceTypes (Array.toList anonInfo.SortedNames) + anonInfo, ptys + | ValueNone -> + // Note: no known anonymous record type - use our assembly + let anonInfo = AnonRecdTypeInfo.Create(cenv.topCcu, mkTupInfo isExplicitStruct, unsortedNames) + anonInfo, NewInferenceTypes (Array.toList anonInfo.SortedNames) + let ty2 = TType_anon (anonInfo, ptys) + AddCxTypeEqualsType contextInfo denv cenv.css m ty ty2 + anonInfo, ptys - ptys /// Optimized unification routine that avoids creating new inference /// variables unnecessarily let UnifyFunctionTypeUndoIfFailed cenv denv m ty = match tryDestFunTy cenv.g ty with - | None -> + | ValueNone -> let domainTy = NewInferenceType () let resultTy = NewInferenceType () if AddCxTypeEqualsTypeUndoIfFailed denv cenv.css m ty (domainTy --> resultTy) then - Some(domainTy, resultTy) + ValueSome(domainTy, resultTy) else - None + ValueNone | r -> r /// Optimized unification routine that avoids creating new inference /// variables unnecessarily let UnifyFunctionType extraInfo cenv denv mFunExpr ty = match UnifyFunctionTypeUndoIfFailed cenv denv mFunExpr ty with - | Some res -> res - | None -> + | ValueSome res -> res + | ValueNone -> match extraInfo with | Some argm -> error (NotAFunction(denv, ty, mFunExpr, argm)) | None -> error (FunctionExpected(denv, ty, mFunExpr)) @@ -1507,7 +1541,7 @@ let MakeAndPublishBaseVal cenv env baseIdOpt ty = let InstanceMembersNeedSafeInitCheck cenv m thisTy = ExistsInEntireHierarchyOfType - (fun ty -> not (isStructTy cenv.g ty) && (match tryDestAppTy cenv.g ty with Some tcref when tcref.HasSelfReferentialConstructor -> true | _ -> false)) + (fun ty -> not (isStructTy cenv.g ty) && (match tryDestAppTy cenv.g ty with ValueSome tcref when tcref.HasSelfReferentialConstructor -> true | _ -> false)) cenv.g cenv.amap m @@ -1901,7 +1935,7 @@ let FreshenAbstractSlot g amap m synTyparDecls absMethInfo = isNil synTypars - let (CompiledSig (argtys, retTy, fmtps, _)) = CompiledSigOfMeth g amap m absMethInfo + let (CompiledSig (argTys, retTy, fmtps, _)) = CompiledSigOfMeth g amap m absMethInfo // If the virtual method is a generic method then copy its type parameters let typarsFromAbsSlot, typarInstFromAbsSlot, _ = @@ -1911,7 +1945,7 @@ let FreshenAbstractSlot g amap m synTyparDecls absMethInfo = ConstraintSolver.FreshenAndFixupTypars m rigid ttps ttinst fmtps // Work out the required type of the member - let argTysFromAbsSlot = argtys |> List.mapSquared (instType typarInstFromAbsSlot) + let argTysFromAbsSlot = argTys |> List.mapSquared (instType typarInstFromAbsSlot) let retTyFromAbsSlot = retTy |> GetFSharpViewOfReturnType g |> instType typarInstFromAbsSlot typarsFromAbsSlotAreRigid, typarsFromAbsSlot, argTysFromAbsSlot, retTyFromAbsSlot @@ -1923,6 +1957,7 @@ let FreshenAbstractSlot g amap m synTyparDecls absMethInfo = let BuildFieldMap cenv env isPartial ty flds m = let ad = env.eAccessRights if isNil flds then invalidArg "flds" "BuildFieldMap" + let fldCount = flds.Length let frefSets = let allFields = flds |> List.map (fun ((_, ident), _) -> ident) @@ -1942,7 +1977,7 @@ let BuildFieldMap cenv env isPartial ty flds m = warning (Error(FSComp.SR.tcFieldsDoNotDetermineUniqueRecordType(), m)) // try finding a record type with the same number of fields as the ones that are given. - match tcrefs |> List.tryFind (fun tc -> tc.TrueFieldsAsList.Length = flds.Length) with + match tcrefs |> List.tryFind (fun tc -> tc.TrueFieldsAsList.Length = fldCount) with | Some tcref -> tcref | _ -> // OK, there isn't a unique, good type dictated by the intersection for the field refs. @@ -2011,20 +2046,20 @@ let ApplyUnionCaseOrExnTypesForPat m cenv env overallTy c = ApplyUnionCaseOrExn ((fun (a, b) mArgs args -> TPat_unioncase(a, b, args, unionRanges m mArgs)), (fun a mArgs args -> TPat_exnconstr(a, args, unionRanges m mArgs))) m cenv env overallTy c -let UnionCaseOrExnCheck (env: TcEnv) nargtys nargs m = - if nargs <> nargtys then error (UnionCaseWrongArguments(env.DisplayEnv, nargtys, nargs, m)) +let UnionCaseOrExnCheck (env: TcEnv) numArgTys numArgs m = + if numArgs <> numArgTys then error (UnionCaseWrongArguments(env.DisplayEnv, numArgTys, numArgs, m)) let TcUnionCaseOrExnField cenv (env: TcEnv) ty1 m c n funcs = let ad = env.eAccessRights - let mkf, argtys, _argNames = + let mkf, argTys, _argNames = match ResolvePatternLongIdent cenv.tcSink cenv.nameResolver AllIdsOK false m ad env.eNameResEnv TypeNameResolutionInfo.Default c with | (Item.UnionCase _ | Item.ExnCase _) as item -> ApplyUnionCaseOrExn funcs m cenv env ty1 item | _ -> error(Error(FSComp.SR.tcUnknownUnion(), m)) - let argstysLength = List.length argtys + let argstysLength = List.length argTys if n >= argstysLength then error (UnionCaseWrongNumberOfArgs(env.DisplayEnv, argstysLength, n, m)) - let ty2 = List.item n argtys + let ty2 = List.item n argTys mkf, ty2 //------------------------------------------------------------------------- @@ -2204,11 +2239,11 @@ module GeneralizationHelpers = let lhsConstraintTypars = allUntupledArgTys |> List.collect (fun ty -> match tryDestTyparTy cenv.g ty with - | Some tp -> + | ValueSome tp -> match relevantUniqueSubtypeConstraint tp with | Some cxty -> freeInTypeLeftToRight cenv.g false cxty | None -> [] - | None -> []) + | _ -> []) let IsCondensationTypar (tp:Typar) = // A condensation typar may not a user-generated type variable nor has it been unified with any user type variable @@ -2220,7 +2255,7 @@ module GeneralizationHelpers = // A condensation typar can't be used in the constraints of any candidate condensation typars not (ListSet.contains typarEq tp lhsConstraintTypars) && // A condensation typar must occur precisely once in tyIJ, and must not occur free in any other tyIJ - (match allUntupledArgTysWithFreeVars |> List.partition (fun (ty, _) -> match tryDestTyparTy cenv.g ty with Some destTypar -> typarEq destTypar tp | _ -> false) with + (match allUntupledArgTysWithFreeVars |> List.partition (fun (ty, _) -> match tryDestTyparTy cenv.g ty with ValueSome destTypar -> typarEq destTypar tp | _ -> false) with | [_], rest -> not (rest |> List.exists (fun (_, fvs) -> ListSet.contains typarEq tp fvs)) | _ -> false) @@ -2923,54 +2958,54 @@ let MakeApplicableExprWithFlex cenv (env: TcEnv) expr = /// Checks, warnings and constraint assertions for downcasts -let TcRuntimeTypeTest isCast isOperator cenv denv m tgty srcTy = - if TypeDefinitelySubsumesTypeNoCoercion 0 cenv.g cenv.amap m tgty srcTy then +let TcRuntimeTypeTest isCast isOperator cenv denv m tgtTy srcTy = + if TypeDefinitelySubsumesTypeNoCoercion 0 cenv.g cenv.amap m tgtTy srcTy then warning(TypeTestUnnecessary(m)) if isTyparTy cenv.g srcTy && not (destTyparTy cenv.g srcTy).IsCompatFlex then - error(IndeterminateRuntimeCoercion(denv, srcTy, tgty, m)) + error(IndeterminateRuntimeCoercion(denv, srcTy, tgtTy, m)) if isSealedTy cenv.g srcTy then error(RuntimeCoercionSourceSealed(denv, srcTy, m)) - if isSealedTy cenv.g tgty || isTyparTy cenv.g tgty || not (isInterfaceTy cenv.g srcTy) then + if isSealedTy cenv.g tgtTy || isTyparTy cenv.g tgtTy || not (isInterfaceTy cenv.g srcTy) then if isCast then - AddCxTypeMustSubsumeType (ContextInfo.RuntimeTypeTest isOperator) denv cenv.css m NoTrace srcTy tgty + AddCxTypeMustSubsumeType (ContextInfo.RuntimeTypeTest isOperator) denv cenv.css m NoTrace srcTy tgtTy else - AddCxTypeMustSubsumeType ContextInfo.NoContext denv cenv.css m NoTrace srcTy tgty + AddCxTypeMustSubsumeType ContextInfo.NoContext denv cenv.css m NoTrace srcTy tgtTy - if isErasedType cenv.g tgty then + if isErasedType cenv.g tgtTy then if isCast then - warning(Error(FSComp.SR.tcTypeCastErased(NicePrint.minimalStringOfType denv tgty, NicePrint.minimalStringOfType denv (stripTyEqnsWrtErasure EraseAll cenv.g tgty)), m)) + warning(Error(FSComp.SR.tcTypeCastErased(NicePrint.minimalStringOfType denv tgtTy, NicePrint.minimalStringOfType denv (stripTyEqnsWrtErasure EraseAll cenv.g tgtTy)), m)) else - error(Error(FSComp.SR.tcTypeTestErased(NicePrint.minimalStringOfType denv tgty, NicePrint.minimalStringOfType denv (stripTyEqnsWrtErasure EraseAll cenv.g tgty)), m)) + error(Error(FSComp.SR.tcTypeTestErased(NicePrint.minimalStringOfType denv tgtTy, NicePrint.minimalStringOfType denv (stripTyEqnsWrtErasure EraseAll cenv.g tgtTy)), m)) else - getErasedTypes cenv.g tgty |> + getErasedTypes cenv.g tgtTy |> List.iter (fun ety -> if isMeasureTy cenv.g ety then warning(Error(FSComp.SR.tcTypeTestLosesMeasures(NicePrint.minimalStringOfType denv ety), m)) else warning(Error(FSComp.SR.tcTypeTestLossy(NicePrint.minimalStringOfType denv ety, NicePrint.minimalStringOfType denv (stripTyEqnsWrtErasure EraseAll cenv.g ety)), m))) /// Checks, warnings and constraint assertions for upcasts -let TcStaticUpcast cenv denv m tgty srcTy = - if isTyparTy cenv.g tgty then - if not (destTyparTy cenv.g tgty).IsCompatFlex then - error(IndeterminateStaticCoercion(denv, srcTy, tgty, m)) +let TcStaticUpcast cenv denv m tgtTy srcTy = + if isTyparTy cenv.g tgtTy then + if not (destTyparTy cenv.g tgtTy).IsCompatFlex then + error(IndeterminateStaticCoercion(denv, srcTy, tgtTy, m)) //else warning(UpcastUnnecessary(m)) - if isSealedTy cenv.g tgty && not (isTyparTy cenv.g tgty) then - warning(CoercionTargetSealed(denv, tgty, m)) + if isSealedTy cenv.g tgtTy && not (isTyparTy cenv.g tgtTy) then + warning(CoercionTargetSealed(denv, tgtTy, m)) - if typeEquiv cenv.g srcTy tgty then + if typeEquiv cenv.g srcTy tgtTy then warning(UpcastUnnecessary(m)) - AddCxTypeMustSubsumeType ContextInfo.NoContext denv cenv.css m NoTrace tgty srcTy + AddCxTypeMustSubsumeType ContextInfo.NoContext denv cenv.css m NoTrace tgtTy srcTy let BuildPossiblyConditionalMethodCall cenv env isMutable m isProp minfo valUseFlags minst objArgs args = let conditionalCallDefineOpt = TryFindMethInfoStringAttribute cenv.g m cenv.g.attrib_ConditionalAttribute minfo - match conditionalCallDefineOpt with - | Some d when not (List.contains d cenv.conditionalDefines) -> + match conditionalCallDefineOpt, cenv.conditionalDefines with + | Some d, Some defines when not (List.contains d defines) -> // Methods marked with 'Conditional' must return 'unit' UnifyTypes cenv env m cenv.g.unit_ty (minfo.GetFSharpReturnTy(cenv.amap, m, minst)) @@ -3087,13 +3122,12 @@ let BuildILStaticFieldSet m (finfo:ILFieldInfo) argExpr = mkAsmExpr ([ mkNormalStsfld fspec ], tinst, [argExpr], [], m) let BuildRecdFieldSet g m objExpr (rfinfo:RecdFieldInfo) argExpr = - let tgty = rfinfo.DeclaringType - let valu = isStructTy g tgty - let objExpr = if valu then objExpr else mkCoerceExpr(objExpr, tgty, m, tyOfExpr g objExpr) + let tgtTy = rfinfo.DeclaringType + let valu = isStructTy g tgtTy + let objExpr = if valu then objExpr else mkCoerceExpr(objExpr, tgtTy, m, tyOfExpr g objExpr) let wrap, objExpr, _readonly, _writeonly = mkExprAddrOfExpr g valu false DefinitelyMutates objExpr None m wrap (mkRecdFieldSetViaExprAddr (objExpr, rfinfo.RecdFieldRef, rfinfo.TypeInst, argExpr, m) ) - //------------------------------------------------------------------------- // Helpers dealing with named and optional args at callsites //------------------------------------------------------------------------- @@ -3156,7 +3190,7 @@ let GetMethodArgs arg = let args = match arg with | SynExpr.Const (SynConst.Unit, _) -> [] - | SynExprParen(SynExpr.Tuple (args, _, _), _, _, _) | SynExpr.Tuple (args, _, _) -> args + | SynExprParen(SynExpr.Tuple (false, args, _, _), _, _, _) | SynExpr.Tuple (false, args, _, _) -> args | SynExprParen(arg, _, _, _) | arg -> [arg] let unnamedCallerArgs, namedCallerArgs = args |> List.takeUntil IsNamedArg @@ -3178,24 +3212,22 @@ let GetMethodArgs arg = // Helpers dealing with pattern match compilation //------------------------------------------------------------------------- -let CompilePatternForMatch cenv (env: TcEnv) mExpr matchm warnOnUnused actionOnFailure (v, generalizedTypars) clauses inputTy resultTy = - let dtree, targets = CompilePattern cenv.g env.DisplayEnv cenv.amap mExpr matchm warnOnUnused actionOnFailure (v, generalizedTypars) clauses inputTy resultTy +let CompilePatternForMatch cenv (env: TcEnv) mExpr matchm warnOnUnused actionOnFailure (inputVal, generalizedTypars, inputExprOpt) clauses inputTy resultTy = + let dtree, targets = CompilePattern cenv.g env.DisplayEnv cenv.amap mExpr matchm warnOnUnused actionOnFailure (inputVal, generalizedTypars, inputExprOpt) clauses inputTy resultTy mkAndSimplifyMatch NoSequencePointAtInvisibleBinding mExpr matchm resultTy dtree targets /// Compile a pattern -let CompilePatternForMatchClauses cenv env mExpr matchm warnOnUnused actionOnFailure inputTy resultTy tclauses = +let CompilePatternForMatchClauses cenv env mExpr matchm warnOnUnused actionOnFailure inputExprOpt inputTy resultTy tclauses = // Avoid creating a dummy in the common cases where we are about to bind a name for the expression // CLEANUP: avoid code duplication with code further below, i.e.all callers should call CompilePatternForMatch match tclauses with - | [TClause(TPat_as (pat1, PBind (v, TypeScheme(generalizedTypars, _)), _), None, TTarget(vs, e, spTarget), m2)] -> - let expr = CompilePatternForMatch cenv env mExpr matchm warnOnUnused actionOnFailure (v, generalizedTypars) [TClause(pat1, None, TTarget(ListSet.remove valEq v vs, e, spTarget), m2)] inputTy resultTy - v, expr + | [TClause(TPat_as (pat1, PBind (asVal, TypeScheme(generalizedTypars, _)), _), None, TTarget(vs, e, spTarget), m2)] -> + let expr = CompilePatternForMatch cenv env mExpr matchm warnOnUnused actionOnFailure (asVal, generalizedTypars, None) [TClause(pat1, None, TTarget(ListSet.remove valEq asVal vs, e, spTarget), m2)] inputTy resultTy + asVal, expr | _ -> - let idv, _ = Tastops.mkCompGenLocal mExpr "matchValue" inputTy - let expr = CompilePatternForMatch cenv env mExpr matchm warnOnUnused actionOnFailure (idv, []) tclauses inputTy resultTy - idv, expr - - + let matchValueTmp, _ = Tastops.mkCompGenLocal mExpr "matchValue" inputTy + let expr = CompilePatternForMatch cenv env mExpr matchm warnOnUnused actionOnFailure (matchValueTmp, [], inputExprOpt) tclauses inputTy resultTy + matchValueTmp, expr //------------------------------------------------------------------------- // Helpers dealing with sequence expressions @@ -3427,11 +3459,10 @@ let mkSeqFinally cenv env m genTy e1 e2 = let mkSeqExprMatchClauses (pat', vspecs) innerExpr = [TClause(pat', None, TTarget(vspecs, innerExpr, SequencePointAtTarget), pat'.Range) ] -let compileSeqExprMatchClauses cenv env inputExprMark (pat':Pattern, vspecs) innerExpr bindPatTy genInnerTy = - let patMark = pat'.Range - let tclauses = mkSeqExprMatchClauses (pat', vspecs) innerExpr - CompilePatternForMatchClauses cenv env inputExprMark patMark false ThrowIncompleteMatchException bindPatTy genInnerTy tclauses - +let compileSeqExprMatchClauses cenv env inputExprMark (pat:Pattern, vspecs) innerExpr inputExprOpt bindPatTy genInnerTy = + let patMark = pat.Range + let tclauses = mkSeqExprMatchClauses (pat, vspecs) innerExpr + CompilePatternForMatchClauses cenv env inputExprMark patMark false ThrowIncompleteMatchException inputExprOpt bindPatTy genInnerTy tclauses let elimFastIntegerForLoop (spBind, id, start, dir, finish, innerExpr, m) = let pseudoEnumExpr = @@ -3442,10 +3473,10 @@ let elimFastIntegerForLoop (spBind, id, start, dir, finish, innerExpr, m) = let (|ExprAsPat|_|) (f:SynExpr) = match f with | SingleIdent v1 | SynExprParen(SingleIdent v1, _, _, _) -> Some (mkSynPatVar None v1) - | SynExprParen(SynExpr.Tuple (elems, _, _), _, _, _) -> + | SynExprParen(SynExpr.Tuple (false, elems, _, _), _, _, _) -> let elems = elems |> List.map (|SingleIdent|_|) if elems |> List.forall (fun x -> x.IsSome) then - Some (SynPat.Tuple((elems |> List.map (fun x -> mkSynPatVar None x.Value)), f.Range)) + Some (SynPat.Tuple(false, (elems |> List.map (fun x -> mkSynPatVar None x.Value)), f.Range)) else None | _ -> None @@ -3461,7 +3492,7 @@ let (|SimpleSemicolonSequence|_|) acceptDeprecated c = | SynExpr.Sequential (_, _, e1, e2, _) -> YieldFree e1 && YieldFree e2 | SynExpr.IfThenElse (_, e2, e3opt, _, _, _, _) -> YieldFree e2 && Option.forall YieldFree e3opt | SynExpr.TryWith (e1, _, clauses, _, _, _, _) -> YieldFree e1 && clauses |> List.forall (fun (Clause(_, _, e, _, _)) -> YieldFree e) - | (SynExpr.Match (_, _, clauses, _, _) | SynExpr.MatchBang (_, _, clauses, _, _)) -> + | (SynExpr.Match (_, _, clauses, _) | SynExpr.MatchBang (_, _, clauses, _)) -> clauses |> List.forall (fun (Clause(_, _, e, _, _)) -> YieldFree e) | SynExpr.For (_, _, _, _, _, body, _) | SynExpr.TryFinally (body, _, _, _, _) @@ -4274,8 +4305,8 @@ let rec TcTyparConstraint ridx cenv newOk checkCxs occ (env: TcEnv) tpenv c = | WhereTyparSupportsMember(tps, memSpfn, m) -> let traitInfo, tpenv = TcPseudoMemberSpec cenv newOk env tps tpenv memSpfn m match traitInfo with - | TTrait(objtys, ".ctor", memberFlags, argtys, returnTy, _) when memberFlags.MemberKind = MemberKind.Constructor -> - match objtys, argtys with + | TTrait(objtys, ".ctor", memberFlags, argTys, returnTy, _) when memberFlags.MemberKind = MemberKind.Constructor -> + match objtys, argTys with | [ty], [] when typeEquiv cenv.g ty (GetFSharpViewOfReturnType cenv.g returnTy) -> AddCxTypeMustSupportDefaultCtor env.DisplayEnv cenv.css m NoTrace ty tpenv @@ -4303,14 +4334,14 @@ and TcPseudoMemberSpec cenv newOk env synTypes tpenv memSpfn m = let topValInfo = TranslatePartialArity memberConstraintTypars partialValReprInfo let _, curriedArgInfos, returnTy, _ = GetTopValTypeInCompiledForm cenv.g topValInfo memberConstraintTy m //if curriedArgInfos.Length > 1 then error(Error(FSComp.SR.tcInvalidConstraint(), m)) - let argtys = List.concat curriedArgInfos - let argtys = List.map fst argtys + let argTys = List.concat curriedArgInfos + let argTys = List.map fst argTys let logicalCompiledName = ComputeLogicalName id memberFlags let item = Item.ArgName (id, memberConstraintTy, None) CallNameResolutionSink cenv.tcSink (id.idRange, env.NameEnv, item, item, emptyTyparInst, ItemOccurence.Use, env.DisplayEnv, env.eAccessRights) - TTrait(tys, logicalCompiledName, memberFlags, argtys, returnTy, ref None), tpenv + TTrait(tys, logicalCompiledName, memberFlags, argTys, returnTy, ref None), tpenv | _ -> error(Error(FSComp.SR.tcInvalidConstraint(), m)) | _ -> error(Error(FSComp.SR.tcInvalidConstraint(), m)) @@ -4401,15 +4432,15 @@ and TcValSpec cenv env declKind newOk containerInfo memFlagsOpt thisTyOpt tpenv let ty' = if SynInfo.HasOptionalArgs valSynInfo then - let argtysl, returnTy = GetTopTauTypeInFSharpForm cenv.g argsData ty' m - let argtysl = - (List.zip (List.mapSquared fst argtysl) valSynInfo.ArgInfos) - |> List.map (fun (argtys, argInfos) -> - (List.zip argtys argInfos) + let curriedArgTys, returnTy = GetTopTauTypeInFSharpForm cenv.g argsData ty' m + let curriedArgTys = + (List.zip (List.mapSquared fst curriedArgTys) valSynInfo.ArgInfos) + |> List.map (fun (argTys, argInfos) -> + (List.zip argTys argInfos) |> List.map (fun (argty, argInfo) -> if SynInfo.IsOptionalArg argInfo then mkOptionTy cenv.g argty else argty)) - mkIteratedFunTy (List.map (mkRefTupledTy cenv.g) argtysl) returnTy + mkIteratedFunTy (List.map (mkRefTupledTy cenv.g) curriedArgTys) returnTy else ty' let memberInfoOpt = @@ -4474,9 +4505,9 @@ and TcTyparOrMeasurePar optKind cenv (env:TcEnv) newOk tpenv (Typar(id, _, _) as // CallNameResolutionSink cenv.tcSink (tp.Range.StartRange, env.NameEnv, item, item, ItemOccurence.UseInType, env.DisplayEnv, env.eAccessRights) res, tpenv let key = id.idText - match env.eNameResEnv.eTypars.TryFind key with - | Some res -> checkRes res - | None -> + match env.eNameResEnv.eTypars.TryGetValue key with + | true, res -> checkRes res + | _ -> match TryFindUnscopedTypar key tpenv with | Some res -> checkRes res | None -> @@ -4584,21 +4615,34 @@ and TcTypeOrMeasure optKind cenv newOk checkCxs occ env (tpenv:SyntacticUnscoped match ltyp with | AppTy cenv.g (tcref, tinst) -> let tcref = ResolveTypeLongIdentInTyconRef cenv.tcSink cenv.nameResolver env.eNameResEnv (TypeNameResolutionInfo.ResolveToTypeRefs (TypeNameResolutionStaticArgsInfo.FromTyArgs args.Length)) ad m tcref longId - TcTypeApp cenv newOk checkCxs occ env tpenv m tcref tinst args + TcTypeApp cenv newOk checkCxs occ env tpenv m tcref tinst args | _ -> error(Error(FSComp.SR.tcTypeHasNoNestedTypes(), m)) - | SynType.Tuple(args, m) -> - let isMeasure = match optKind with Some TyparKind.Measure -> true | None -> List.exists (fun (isquot, _) -> isquot) args | _ -> false - if isMeasure then - let ms, tpenv = TcMeasuresAsTuple cenv newOk checkCxs occ env tpenv args m - TType_measure ms, tpenv + | SynType.Tuple(isStruct, args, m) -> + let tupInfo = mkTupInfo isStruct + if isStruct then + let args',tpenv = TcTypesAsTuple cenv newOk checkCxs occ env tpenv args m + TType_tuple(tupInfo,args'),tpenv else - let args', tpenv = TcTypesAsTuple cenv newOk checkCxs occ env tpenv args m - TType_tuple(tupInfoRef, args'), tpenv - - | SynType.StructTuple(args, m) -> - let args', tpenv = TcTypesAsTuple cenv newOk checkCxs occ env tpenv args m - TType_tuple(tupInfoStruct, args'), tpenv + let isMeasure = match optKind with Some TyparKind.Measure -> true | None -> List.exists (fun (isquot,_) -> isquot) args | _ -> false + if isMeasure then + let ms,tpenv = TcMeasuresAsTuple cenv newOk checkCxs occ env tpenv args m + TType_measure ms,tpenv + else + let args',tpenv = TcTypesAsTuple cenv newOk checkCxs occ env tpenv args m + TType_tuple(tupInfo,args'),tpenv + + | SynType.AnonRecd(isStruct, args,m) -> + let tupInfo = mkTupInfo isStruct + let args',tpenv = TcTypesAsTuple cenv newOk checkCxs occ env tpenv (args |> List.map snd |> List.map (fun x -> (false,x))) m + let unsortedIds = args |> List.map fst |> List.toArray + let anonInfo = AnonRecdTypeInfo.Create(cenv.topCcu, tupInfo, unsortedIds) + // Sort into canonical order + let sortedArgTys, sortedCheckedArgTys = List.zip args args' |> List.indexed |> List.sortBy (fun (i,_) -> unsortedIds.[i].idText) |> List.map snd |> List.unzip + sortedArgTys |> List.iteri (fun i (x,_) -> + let item = Item.AnonRecdField(anonInfo, sortedCheckedArgTys, i, x.idRange) + CallNameResolutionSink cenv.tcSink (x.idRange,env.NameEnv,item,item,emptyTyparInst,ItemOccurence.UseInType,env.DisplayEnv,env.eAccessRights)) + TType_anon(anonInfo, sortedCheckedArgTys),tpenv | SynType.Fun(domainTy, resultTy, _) -> let domainTy', tpenv = TcTypeAndRecover cenv newOk checkCxs occ env tpenv domainTy @@ -5105,17 +5149,17 @@ and TcPatBindingName cenv env id ty isMemberThis vis1 topValData (inlineFlag, de let names = Map.add id.idText (PrelimValScheme1(id, declaredTypars, ty, topValData, None, isMutable, inlineFlag, baseOrThis, argAttribs, vis, compgen)) names let takenNames = Set.add id.idText takenNames (fun (TcPatPhase2Input (values, isLeftMost)) -> - let (vspec, typeScheme) = - match values.TryFind id.idText with - | Some value -> - let name = id.idText + let (vspec, typeScheme) = + let name = id.idText + match values.TryGetValue name with + | true, value -> if not (String.IsNullOrEmpty name) && Char.IsLower(name.[0]) then - match TryFindPatternByName name env.eNameResEnv with - | Some (Item.Value vref) when vref.LiteralValue.IsSome -> - warning(Error(FSComp.SR.checkLowercaseLiteralBindingInPattern(id.idText), id.idRange)) - | Some _ | None -> () + match env.eNameResEnv.ePatItems.TryGetValue name with + | true, Item.Value vref when vref.LiteralValue.IsSome -> + warning(Error(FSComp.SR.checkLowercaseLiteralBindingInPattern name, id.idRange)) + | _ -> () value - | None -> error(Error(FSComp.SR.tcNameNotBoundInPattern(id.idText), id.idRange)) + | _ -> error(Error(FSComp.SR.tcNameNotBoundInPattern name, id.idRange)) // isLeftMost indicates we are processing the left-most path through a disjunctive or pattern. // For those binding locations, CallNameResolutionSink is called in MakeAndPublishValue, like all other bindings @@ -5166,14 +5210,14 @@ and TcPat warnOnUpper cenv env topValInfo vFlags (tpenv, names, takenNames) ty p | SynPat.IsInst(cty, m) | SynPat.Named (SynPat.IsInst(cty, m), _, _, _, _) -> let srcTy = ty - let tgty, tpenv = TcTypeAndRecover cenv NewTyparsOKButWarnIfNotRigid CheckCxs ItemOccurence.UseInType env tpenv cty - TcRuntimeTypeTest (*isCast*)false (*isOperator*)true cenv env.DisplayEnv m tgty srcTy + let tgtTy, tpenv = TcTypeAndRecover cenv NewTyparsOKButWarnIfNotRigid CheckCxs ItemOccurence.UseInType env tpenv cty + TcRuntimeTypeTest (*isCast*)false (*isOperator*)true cenv env.DisplayEnv m tgtTy srcTy match pat with | SynPat.IsInst(_, m) -> - (fun _ -> TPat_isinst (srcTy, tgty, None, m)), (tpenv, names, takenNames) + (fun _ -> TPat_isinst (srcTy, tgtTy, None, m)), (tpenv, names, takenNames) | SynPat.Named (SynPat.IsInst _, id, isMemberThis, vis, m) -> - let bindf, names, takenNames = TcPatBindingName cenv env id tgty isMemberThis vis None vFlags (names, takenNames) - (fun values -> TPat_isinst (srcTy, tgty, Some(bindf values), m)), + let bindf, names, takenNames = TcPatBindingName cenv env id tgtTy isMemberThis vis None vFlags (names, takenNames) + (fun values -> TPat_isinst (srcTy, tgtTy, Some(bindf values), m)), (tpenv, names, takenNames) | _ -> failwith "TcPat" @@ -5202,10 +5246,10 @@ and TcPat warnOnUpper cenv env topValInfo vFlags (tpenv, names, takenNames) ty p // matching error (UnionPatternsBindDifferentNames m) names1 |> Map.iter (fun _ (PrelimValScheme1(id1, _, ty1, _, _, _, _, _, _, _, _)) -> - match Map.tryFind id1.idText names2 with - | None -> () - | Some (PrelimValScheme1(_, _, ty2, _, _, _, _, _, _, _, _)) -> - UnifyTypes cenv env m ty1 ty2) + match names2.TryGetValue id1.idText with + | true, PrelimValScheme1(_, _, ty2, _, _, _, _, _, _, _, _) -> + UnifyTypes cenv env m ty1 ty2 + | _ -> ()) (fun values -> TPat_disjs ([pat1' values;pat2' values.RightPath], m)), (tpenv, names1, takenNames1) | SynPat.Ands (pats, m) -> @@ -5220,11 +5264,11 @@ and TcPat warnOnUpper cenv env topValInfo vFlags (tpenv, names, takenNames) ty p | _ -> AllIdsOK let checkNoArgsForLiteral() = - let nargs = + let numArgs = match args with | SynConstructorArgs.Pats args -> args.Length | SynConstructorArgs.NamePatPairs (pairs, _) -> pairs.Length - if nargs <> 0 then error(Error(FSComp.SR.tcLiteralDoesNotTakeArguments(), m)) + if numArgs <> 0 then error(Error(FSComp.SR.tcLiteralDoesNotTakeArguments(), m)) match ResolvePatternLongIdent cenv.tcSink cenv.nameResolver warnOnUpperForId false m ad env.eNameResEnv TypeNameResolutionInfo.Default longId with | Item.NewDef id -> @@ -5273,10 +5317,10 @@ and TcPat warnOnUpper cenv env topValInfo vFlags (tpenv, names, takenNames) ty p SynExpr.DiscardAfterMissingQualificationAfterDot(e, unionRanges e.Range (List.last dotms)) else SynExpr.LongIdent(false, lidwd, None, m) List.fold (fun f x -> mkSynApp1 f (convSynPatToSynExpr x) m) e args - | SynPat.Tuple (args, m) -> SynExpr.Tuple(List.map convSynPatToSynExpr args, [], m) + | SynPat.Tuple (isStruct, args, m) -> SynExpr.Tuple(isStruct, List.map convSynPatToSynExpr args, [], m) | SynPat.Paren (p, _) -> convSynPatToSynExpr p - | SynPat.ArrayOrList (isArray, args, m) -> SynExpr.ArrayOrList(isArray, List.map convSynPatToSynExpr args, m) - | SynPat.QuoteExpr (e, _) -> e + | SynPat.ArrayOrList (isArray, args, m) -> SynExpr.ArrayOrList(isArray,List.map convSynPatToSynExpr args, m) + | SynPat.QuoteExpr (e,_) -> e | SynPat.Null m -> SynExpr.Null(m) | _ -> error(Error(FSComp.SR.tcInvalidArgForParameterizedPattern(), x.Range)) let activePatArgsAsSynExprs = List.map convSynPatToSynExpr activePatArgsAsSynPats @@ -5303,8 +5347,8 @@ and TcPat warnOnUpper cenv env topValInfo vFlags (tpenv, names, takenNames) ty p | (Item.UnionCase _ | Item.ExnCase _) as item -> // DATA MATCH CONSTRUCTORS - let mkf, argtys, argNames = ApplyUnionCaseOrExnTypesForPat m cenv env ty item - let nargtys = argtys.Length + let mkf, argTys, argNames = ApplyUnionCaseOrExnTypesForPat m cenv env ty item + let numArgTys = argTys.Length let args = match args with @@ -5315,16 +5359,18 @@ and TcPat warnOnUpper cenv env topValInfo vFlags (tpenv, names, takenNames) ty p // | Case(value = v) // will become // | Case(_, v) - let result = Array.zeroCreate nargtys + let result = Array.zeroCreate numArgTys for (id, pat) in pairs do match argNames |> List.tryFindIndex (fun id2 -> id.idText = id2.idText) with | None -> - let caseName = - match item with - | Item.UnionCase(uci, _) -> uci.Name - | Item.ExnCase tcref -> tcref.DisplayName - | _ -> failwith "impossible" - error(Error(FSComp.SR.tcUnionCaseConstructorDoesNotHaveFieldWithGivenName(caseName, id.idText), id.idRange)) + match item with + | Item.UnionCase(uci, _) -> + error(Error(FSComp.SR.tcUnionCaseConstructorDoesNotHaveFieldWithGivenName(uci.Name, id.idText), id.idRange)) + | Item.ExnCase tcref -> + error(Error(FSComp.SR.tcExceptionConstructorDoesNotHaveFieldWithGivenName(tcref.DisplayName, id.idText), id.idRange)) + | _ -> + error(Error(FSComp.SR.tcConstructorDoesNotHaveFieldWithGivenName(id.idText), id.idRange)) + | Some idx -> match box result.[idx] with | null -> @@ -5333,33 +5379,33 @@ and TcPat warnOnUpper cenv env topValInfo vFlags (tpenv, names, takenNames) ty p | Item.UnionCase(uci, _) -> Some(ArgumentContainer.UnionCase(uci)) | Item.ExnCase tref -> Some(ArgumentContainer.Type(tref)) | _ -> None - let argItem = Item.ArgName (argNames.[idx], argtys.[idx], argContainerOpt) + let argItem = Item.ArgName (argNames.[idx], argTys.[idx], argContainerOpt) CallNameResolutionSink cenv.tcSink (id.idRange, env.NameEnv, argItem, argItem, emptyTyparInst, ItemOccurence.Pattern, env.DisplayEnv, ad) | _ -> error(Error(FSComp.SR.tcUnionCaseFieldCannotBeUsedMoreThanOnce(id.idText), id.idRange)) - for i = 0 to nargtys - 1 do + for i = 0 to numArgTys - 1 do if isNull (box result.[i]) then result.[i] <- SynPat.Wild(m.MakeSynthetic()) let args = List.ofArray result if result.Length = 1 then args - else [ SynPat.Tuple(args, m) ] + else [ SynPat.Tuple(false, args, m) ] let args = match args with | []-> [] // note: the next will always be parenthesized - | [SynPatErrorSkip(SynPat.Tuple (args, _)) | SynPatErrorSkip(SynPat.Paren(SynPatErrorSkip(SynPat.Tuple (args, _)), _))] when nargtys > 1 -> args + | [SynPatErrorSkip(SynPat.Tuple (false, args, _)) | SynPatErrorSkip(SynPat.Paren(SynPatErrorSkip(SynPat.Tuple (false, args, _)), _))] when numArgTys > 1 -> args // note: we allow both 'C _' and 'C (_)' regardless of number of argument of the pattern - | [SynPatErrorSkip(SynPat.Wild _ as e) | SynPatErrorSkip(SynPat.Paren(SynPatErrorSkip(SynPat.Wild _ as e), _))] -> Array.toList (Array.create nargtys e) + | [SynPatErrorSkip(SynPat.Wild _ as e) | SynPatErrorSkip(SynPat.Paren(SynPatErrorSkip(SynPat.Wild _ as e), _))] -> Array.toList (Array.create numArgTys e) | [arg] -> [arg] - | _ when nargtys = 0 -> error(Error(FSComp.SR.tcUnionCaseDoesNotTakeArguments(), m)) - | _ when nargtys = 1 -> error(Error(FSComp.SR.tcUnionCaseRequiresOneArgument(), m)) - | _ -> error(Error(FSComp.SR.tcUnionCaseExpectsTupledArguments(nargtys), m)) - UnionCaseOrExnCheck env nargtys args.Length m + | _ when numArgTys = 0 -> error(Error(FSComp.SR.tcUnionCaseDoesNotTakeArguments(), m)) + | _ when numArgTys = 1 -> error(Error(FSComp.SR.tcUnionCaseRequiresOneArgument(), m)) + | _ -> error(Error(FSComp.SR.tcUnionCaseExpectsTupledArguments(numArgTys), m)) + UnionCaseOrExnCheck env numArgTys args.Length m - let args', acc = TcPatterns warnOnUpper cenv env vFlags (tpenv, names, takenNames) argtys args + let args', acc = TcPatterns warnOnUpper cenv env vFlags (tpenv, names, takenNames) argTys args (fun values -> // Report information about the case occurrence to IDE CallNameResolutionSink cenv.tcSink (rangeOfLid longId, env.NameEnv, item, item, emptyTyparInst, ItemOccurence.Pattern, env.DisplayEnv, env.eAccessRights) @@ -5413,17 +5459,10 @@ and TcPat warnOnUpper cenv env topValInfo vFlags (tpenv, names, takenNames) ty p | SynPat.QuoteExpr(_, m) -> error (Error(FSComp.SR.tcInvalidPattern(), m)) - | SynPat.Tuple (args, m) -> - let argtys = NewInferenceTypes args - UnifyTypes cenv env m ty (TType_tuple (tupInfoRef, argtys)) - let args', acc = TcPatterns warnOnUpper cenv env vFlags (tpenv, names, takenNames) argtys args - (fun values -> TPat_tuple(tupInfoRef, List.map (fun f -> f values) args', argtys, m)), acc - - | SynPat.StructTuple (args, m) -> - let argtys = NewInferenceTypes args - UnifyTypes cenv env m ty (TType_tuple (tupInfoStruct, argtys)) - let args', acc = TcPatterns warnOnUpper cenv env vFlags (tpenv, names, takenNames) argtys args - (fun values -> TPat_tuple(tupInfoStruct, List.map (fun f -> f values) args', argtys, m)), acc + | SynPat.Tuple (isExplicitStruct, args, m) -> + let tupInfo, argTys = UnifyTupleTypeAndInferCharacteristics env.eContextInfo cenv env.DisplayEnv m ty isExplicitStruct args + let args', acc = TcPatterns warnOnUpper cenv env vFlags (tpenv, names, takenNames) argTys args + (fun values -> TPat_tuple(tupInfo, List.map (fun f -> f values) args', argTys, m)), acc | SynPat.Paren (p, _) -> TcPat warnOnUpper cenv env None vFlags (tpenv, names, takenNames) ty p @@ -5446,9 +5485,9 @@ and TcPat warnOnUpper cenv env topValInfo vFlags (tpenv, names, takenNames) ty p let ftys = fields |> List.map (fun fsp -> actualTyOfRecdField inst fsp, fsp) let fldsmap', acc = ((tpenv, names, takenNames), ftys) ||> List.mapFold (fun s (ty, fsp) -> - match Map.tryFind fsp.rfield_id.idText fldsmap with - | Some v -> TcPat warnOnUpper cenv env None vFlags s ty v - | None -> (fun _ -> TPat_wild m), s) + match fldsmap.TryGetValue fsp.rfield_id.idText with + | true, v -> TcPat warnOnUpper cenv env None vFlags s ty v + | _ -> (fun _ -> TPat_wild m), s) (fun values -> TPat_recd (tcref, tinst, List.map (fun f -> f values) fldsmap', m)), acc @@ -5467,9 +5506,9 @@ and TcPat warnOnUpper cenv env topValInfo vFlags (tpenv, names, takenNames) ty p | SynPat.FromParseError (pat, _) -> suppressErrorReporting (fun () -> TcPatAndRecover warnOnUpper cenv env topValInfo vFlags (tpenv, names, takenNames) (NewErrorType()) pat) -and TcPatterns warnOnUpper cenv env vFlags s argtys args = - assert (List.length args = List.length argtys) - List.mapFold (fun s (ty, pat) -> TcPat warnOnUpper cenv env None vFlags s ty pat) s (List.zip argtys args) +and TcPatterns warnOnUpper cenv env vFlags s argTys args = + assert (List.length args = List.length argTys) + List.mapFold (fun s (ty, pat) -> TcPat warnOnUpper cenv env None vFlags s ty pat) s (List.zip argTys args) and solveTypAsError cenv denv m ty = @@ -5651,15 +5690,15 @@ and TcExprThen cenv overallTy env tpenv synExpr delayed = let expr, exprty, tpenv = TcExprUndelayedNoType cenv env tpenv synExpr PropagateThenTcDelayed cenv overallTy env tpenv synExpr.Range (MakeApplicableExprNoFlex cenv expr) exprty ExprAtomicFlag.NonAtomic delayed -and TcExprs cenv env m tpenv flexes argtys args = - if List.length args <> List.length argtys then error(Error(FSComp.SR.tcExpressionCountMisMatch((List.length argtys), (List.length args)), m)) - (tpenv, List.zip3 flexes argtys args) ||> List.mapFold (fun tpenv (flex, ty, e) -> +and TcExprs cenv env m tpenv flexes argTys args = + if List.length args <> List.length argTys then error(Error(FSComp.SR.tcExpressionCountMisMatch((List.length argTys), (List.length args)), m)) + (tpenv, List.zip3 flexes argTys args) ||> List.mapFold (fun tpenv (flex, ty, e) -> TcExprFlex cenv flex false ty env tpenv e) and CheckSuperInit cenv objTy m = // Check the type is not abstract match tryDestAppTy cenv.g objTy with - | Some tcref when isAbstractTycon tcref.Deref -> + | ValueSome tcref when isAbstractTycon tcref.Deref -> errorR(Error(FSComp.SR.tcAbstractTypeCannotBeInstantiated(), m)) | _ -> () @@ -5667,13 +5706,13 @@ and CheckSuperInit cenv objTy m = // TcExprUndelayed //------------------------------------------------------------------------- -and TcExprUndelayedNoType cenv env tpenv expr : Expr * TType * _ = - let exprty = NewInferenceType () - let expr', tpenv = TcExprUndelayed cenv exprty env tpenv expr - expr', exprty, tpenv +and TcExprUndelayedNoType cenv env tpenv synExpr : Expr * TType * _ = + let overallTy = NewInferenceType () + let expr, tpenv = TcExprUndelayed cenv overallTy env tpenv synExpr + expr, overallTy, tpenv -and TcExprUndelayed cenv overallTy env tpenv (expr: SynExpr) = - match expr with +and TcExprUndelayed cenv overallTy env tpenv (synExpr: SynExpr) = + match synExpr with | SynExpr.Paren (expr2, _, _, mWholeExprIncludingParentheses) -> // We invoke CallExprHasTypeSink for every construct which is atomic in the syntax, i.e. where a '.' immediately following the // construct is a dot-lookup for the result of the construct. @@ -5682,24 +5721,26 @@ and TcExprUndelayed cenv overallTy env tpenv (expr: SynExpr) = TcExpr cenv overallTy env tpenv expr2 | SynExpr.DotIndexedGet _ | SynExpr.DotIndexedSet _ - | SynExpr.TypeApp _ | SynExpr.Ident _ | SynExpr.LongIdent _ | SynExpr.App _ | SynExpr.DotGet _ -> error(Error(FSComp.SR.tcExprUndelayed(), expr.Range)) + | SynExpr.TypeApp _ | SynExpr.Ident _ | SynExpr.LongIdent _ | SynExpr.App _ | SynExpr.DotGet _ -> error(Error(FSComp.SR.tcExprUndelayed(), synExpr.Range)) | SynExpr.Const (SynConst.String (s, m), _) -> CallExprHasTypeSink cenv.tcSink (m, env.NameEnv, overallTy, env.DisplayEnv, env.eAccessRights) TcConstStringExpr cenv overallTy env m tpenv s - | SynExpr.Const (c, m) -> + | SynExpr.Const (synConst, m) -> CallExprHasTypeSink cenv.tcSink (m, env.NameEnv, overallTy, env.DisplayEnv, env.eAccessRights) - TcConstExpr cenv overallTy env m tpenv c + TcConstExpr cenv overallTy env m tpenv synConst - | SynExpr.Lambda _ -> TcIteratedLambdas cenv true env overallTy Set.empty tpenv expr + | SynExpr.Lambda _ -> + TcIteratedLambdas cenv true env overallTy Set.empty tpenv synExpr - | SynExpr.Match (spMatch, x, matches, isExnMatch, _m) -> + | SynExpr.Match (spMatch, synInputExpr, synClauses, _m) -> - let x', inputTy, tpenv = TcExprOfUnknownType cenv env tpenv x - let mExpr = x'.Range - let v, e, tpenv = TcAndPatternCompileMatchClauses mExpr mExpr (if isExnMatch then Throw else ThrowIncompleteMatchException) cenv inputTy overallTy env tpenv matches - (mkLet spMatch mExpr v x' e, tpenv) + let inputExpr, inputTy, tpenv = TcExprOfUnknownType cenv env tpenv synInputExpr + let mInputExpr = inputExpr.Range + let matchVal, matchExpr, tpenv = TcAndPatternCompileMatchClauses mInputExpr mInputExpr ThrowIncompleteMatchException cenv (Some inputExpr) inputTy overallTy env tpenv synClauses + let overallExpr = mkLet spMatch mInputExpr matchVal inputExpr matchExpr + overallExpr, tpenv // (function[spMatch] pat1 -> expr1 ... | patN -> exprN) // @@ -5711,12 +5752,12 @@ and TcExprUndelayed cenv overallTy env tpenv (expr: SynExpr) = // is // Lambda (_arg2, Let (x, _arg2, x)) - | SynExpr.MatchLambda (isExnMatch, argm, clauses, spMatch, m) -> // (spMatch, x, matches, isExnMatch, m) -> + | SynExpr.MatchLambda (isExnMatch, mArg, clauses, spMatch, m) -> let domainTy, resultTy = UnifyFunctionType None cenv env.DisplayEnv m overallTy - let idv1, idve1 = mkCompGenLocal argm (cenv.synArgNameGenerator.New()) domainTy + let idv1, idve1 = mkCompGenLocal mArg (cenv.synArgNameGenerator.New()) domainTy let envinner = ExitFamilyRegion env - let idv2, matchExpr, tpenv = TcAndPatternCompileMatchClauses m argm (if isExnMatch then Throw else ThrowIncompleteMatchException) cenv domainTy resultTy envinner tpenv clauses + let idv2, matchExpr, tpenv = TcAndPatternCompileMatchClauses m mArg (if isExnMatch then Throw else ThrowIncompleteMatchException) cenv None domainTy resultTy envinner tpenv clauses let overallExpr = mkMultiLambda m [idv1] ((mkLet spMatch m idv2 idve1 matchExpr), resultTy) overallExpr, tpenv @@ -5727,81 +5768,80 @@ and TcExprUndelayed cenv overallTy env tpenv (expr: SynExpr) = error(Error(FSComp.SR.tcFixedNotAllowed(), m)) // e : ty - | SynExpr.Typed (e, cty, m) -> - let tgty, tpenv = TcTypeAndRecover cenv NewTyparsOK CheckCxs ItemOccurence.UseInType env tpenv cty - UnifyTypes cenv env m overallTy tgty - let e', tpenv = TcExpr cenv overallTy env tpenv e - e', tpenv + | SynExpr.Typed (synBodyExpr, synType, m) -> + let tgtTy, tpenv = TcTypeAndRecover cenv NewTyparsOK CheckCxs ItemOccurence.UseInType env tpenv synType + UnifyTypes cenv env m overallTy tgtTy + let expr, tpenv = TcExpr cenv overallTy env tpenv synBodyExpr + expr, tpenv // e :? ty - | SynExpr.TypeTest (e, tgty, m) -> - let e', srcTy, tpenv = TcExprOfUnknownType cenv env tpenv e + | SynExpr.TypeTest (synInnerExpr, tgtTy, m) -> + let innerExpr, srcTy, tpenv = TcExprOfUnknownType cenv env tpenv synInnerExpr UnifyTypes cenv env m overallTy cenv.g.bool_ty - let tgty, tpenv = TcType cenv NewTyparsOK CheckCxs ItemOccurence.UseInType env tpenv tgty - TcRuntimeTypeTest (*isCast*)false (*isOperator*)true cenv env.DisplayEnv m tgty srcTy - let e' = mkCallTypeTest cenv.g m tgty e' - e', tpenv + let tgtTy, tpenv = TcType cenv NewTyparsOK CheckCxs ItemOccurence.UseInType env tpenv tgtTy + TcRuntimeTypeTest (*isCast*)false (*isOperator*)true cenv env.DisplayEnv m tgtTy srcTy + let expr = mkCallTypeTest cenv.g m tgtTy innerExpr + expr, tpenv // SynExpr.AddressOf is noted in the syntax ast in order to recognize it as concrete type information // during type checking, in particular prior to resolving overloads. This helps distinguish // its use at method calls from the use of the conflicting 'ref' mechanism for passing byref parameters - | SynExpr.AddressOf(byref, e, opm, m) -> - TcExpr cenv overallTy env tpenv (mkSynPrefixPrim opm m (if byref then "~&" else "~&&") e) + | SynExpr.AddressOf(byref, synInnerExpr, opm, m) -> + TcExpr cenv overallTy env tpenv (mkSynPrefixPrim opm m (if byref then "~&" else "~&&") synInnerExpr) - | SynExpr.Upcast (e, _, m) | SynExpr.InferredUpcast (e, m) -> - let e', srcTy, tpenv = TcExprOfUnknownType cenv env tpenv e - let tgty, tpenv = - match expr with - | SynExpr.Upcast (_, tgty, m) -> - let tgty, tpenv = TcType cenv NewTyparsOK CheckCxs ItemOccurence.UseInType env tpenv tgty - UnifyTypes cenv env m tgty overallTy - tgty, tpenv + | SynExpr.Upcast (synInnerExpr, _, m) | SynExpr.InferredUpcast (synInnerExpr, m) -> + let innerExpr, srcTy, tpenv = TcExprOfUnknownType cenv env tpenv synInnerExpr + let tgtTy, tpenv = + match synExpr with + | SynExpr.Upcast (_, tgtTy, m) -> + let tgtTy, tpenv = TcType cenv NewTyparsOK CheckCxs ItemOccurence.UseInType env tpenv tgtTy + UnifyTypes cenv env m tgtTy overallTy + tgtTy, tpenv | SynExpr.InferredUpcast _ -> overallTy, tpenv | _ -> failwith "upcast" - TcStaticUpcast cenv env.DisplayEnv m tgty srcTy - mkCoerceExpr(e', tgty, m, srcTy), tpenv - - | SynExpr.Downcast(e, _, m) | SynExpr.InferredDowncast (e, m) -> - let e', srcTy, tpenv = TcExprOfUnknownType cenv env tpenv e - let tgty, tpenv, isOperator = - match expr with - | SynExpr.Downcast (_, tgty, m) -> - let tgty, tpenv = TcType cenv NewTyparsOK CheckCxs ItemOccurence.UseInType env tpenv tgty - UnifyTypes cenv env m tgty overallTy - tgty, tpenv, true + TcStaticUpcast cenv env.DisplayEnv m tgtTy srcTy + let expr = mkCoerceExpr(innerExpr, tgtTy, m, srcTy) + expr, tpenv + + | SynExpr.Downcast(synInnerExpr, _, m) | SynExpr.InferredDowncast (synInnerExpr, m) -> + let innerExpr, srcTy, tpenv = TcExprOfUnknownType cenv env tpenv synInnerExpr + let tgtTy, tpenv, isOperator = + match synExpr with + | SynExpr.Downcast (_, tgtTy, m) -> + let tgtTy, tpenv = TcType cenv NewTyparsOK CheckCxs ItemOccurence.UseInType env tpenv tgtTy + UnifyTypes cenv env m tgtTy overallTy + tgtTy, tpenv, true | SynExpr.InferredDowncast _ -> overallTy, tpenv, false | _ -> failwith "downcast" - TcRuntimeTypeTest (*isCast*)true isOperator cenv env.DisplayEnv m tgty srcTy + TcRuntimeTypeTest (*isCast*)true isOperator cenv env.DisplayEnv m tgtTy srcTy - // TcRuntimeTypeTest ensures tgty is a nominal type. Hence we can insert a check here + // TcRuntimeTypeTest ensures tgtTy is a nominal type. Hence we can insert a check here // based on the nullness semantics of the nominal type. - let e' = mkCallUnbox cenv.g m tgty e' - e', tpenv + let expr = mkCallUnbox cenv.g m tgtTy innerExpr + expr, tpenv | SynExpr.Null m -> AddCxTypeMustSupportNull env.DisplayEnv cenv.css m NoTrace overallTy mkNull m overallTy, tpenv - | SynExpr.Lazy (e, m) -> - let ety = NewInferenceType () - UnifyTypes cenv env m overallTy (mkLazyTy cenv.g ety) - let e', tpenv = TcExpr cenv ety env tpenv e - mkLazyDelayed cenv.g m ety (mkUnitDelayLambda cenv.g m e'), tpenv + | SynExpr.Lazy (synInnerExpr, m) -> + let innerTy = NewInferenceType () + UnifyTypes cenv env m overallTy (mkLazyTy cenv.g innerTy) + let innerExpr, tpenv = TcExpr cenv innerTy env tpenv synInnerExpr + let expr = mkLazyDelayed cenv.g m innerTy (mkUnitDelayLambda cenv.g m innerExpr) + expr, tpenv - | SynExpr.Tuple (args, _, m) -> - let argtys = UnifyRefTupleType env.eContextInfo cenv env.DisplayEnv m overallTy args + | SynExpr.Tuple (isExplicitStruct, args, _, m) -> + let tupInfo, argTys = UnifyTupleTypeAndInferCharacteristics env.eContextInfo cenv env.DisplayEnv m overallTy isExplicitStruct args // No subsumption at tuple construction - let flexes = argtys |> List.map (fun _ -> false) - let args', tpenv = TcExprs cenv env m tpenv flexes argtys args - mkRefTupled cenv.g m args' argtys, tpenv + let flexes = argTys |> List.map (fun _ -> false) + let args', tpenv = TcExprs cenv env m tpenv flexes argTys args + let expr = mkAnyTupled cenv.g m tupInfo args' argTys + expr, tpenv - | SynExpr.StructTuple (args, _, m) -> - let argtys = UnifyStructTupleType env.eContextInfo cenv env.DisplayEnv m overallTy args - // No subsumption at tuple construction - let flexes = argtys |> List.map (fun _ -> false) - let args', tpenv = TcExprs cenv env m tpenv flexes argtys args - mkAnyTupled cenv.g m tupInfoStruct args' argtys, tpenv + | SynExpr.AnonRecd (isStruct, optOrigExpr, unsortedArgs, mWholeExpr) -> + TcAnonRecdExpr cenv overallTy env tpenv (isStruct, optOrigExpr, unsortedArgs, mWholeExpr) | SynExpr.ArrayOrList (isArray, args, m) -> CallExprHasTypeSink cenv.tcSink (m, env.NameEnv, overallTy, env.DisplayEnv, env.eAccessRights) @@ -5839,16 +5879,16 @@ and TcExprUndelayed cenv overallTy env tpenv (expr: SynExpr) = CallExprHasTypeSink cenv.tcSink (mWholeExpr, env.NameEnv, overallTy, env.DisplayEnv, env.eAccessRights) TcRecdExpr cenv overallTy env tpenv (inherits, optOrigExpr, flds, mWholeExpr) - | SynExpr.While (spWhile, e1, e2, m) -> + | SynExpr.While (spWhile, synGuardExpr, synBodyExpr, m) -> UnifyTypes cenv env m overallTy cenv.g.unit_ty - let e1', tpenv = TcExpr cenv (cenv.g.bool_ty) env tpenv e1 - let e2', tpenv = TcStmt cenv env tpenv e2 - mkWhile cenv.g (spWhile, NoSpecialWhileLoopMarker, e1', e2', m), tpenv + let guardExpr, tpenv = TcExpr cenv cenv.g.bool_ty env tpenv synGuardExpr + let bodyExpr, tpenv = TcStmt cenv env tpenv synBodyExpr + mkWhile cenv.g (spWhile, NoSpecialWhileLoopMarker, guardExpr, bodyExpr, m), tpenv | SynExpr.For (spBind, id, start, dir, finish, body, m) -> UnifyTypes cenv env m overallTy cenv.g.unit_ty - let startExpr , tpenv = TcExpr cenv (cenv.g.int_ty) env tpenv start - let finishExpr, tpenv = TcExpr cenv (cenv.g.int_ty) env tpenv finish + let startExpr , tpenv = TcExpr cenv cenv.g.int_ty env tpenv start + let finishExpr, tpenv = TcExpr cenv cenv.g.int_ty env tpenv finish let idv, _ = mkLocal id.idRange id.idText cenv.g.int_ty let envinner = AddLocalVal cenv.tcSink m idv env @@ -5939,22 +5979,22 @@ and TcExprUndelayed cenv overallTy env tpenv (expr: SynExpr) = expr, tpenv | SynExpr.LetOrUse _ -> - TcLinearExprs (TcExprThatCanBeCtorBody cenv) cenv env overallTy tpenv false expr (fun x -> x) + TcLinearExprs (TcExprThatCanBeCtorBody cenv) cenv env overallTy tpenv false synExpr (fun x -> x) - | SynExpr.TryWith (e1, _mTryToWith, clauses, mWithToLast, mTryToLast, spTry, spWith) -> - let e1', tpenv = TcExpr cenv overallTy env tpenv e1 + | SynExpr.TryWith (synBodyExpr, _mTryToWith, synWithClauses, mWithToLast, mTryToLast, spTry, spWith) -> + let bodyExpr, tpenv = TcExpr cenv overallTy env tpenv synBodyExpr // Compile the pattern twice, once as a List.filter with all succeeding targets returning "1", and once as a proper catch block. - let filterClauses = clauses |> List.map (function (Clause(pat, optWhenExpr, _, m, _)) -> Clause(pat, optWhenExpr, (SynExpr.Const(SynConst.Int32 1, m)), m, SuppressSequencePointAtTarget)) + let filterClauses = synWithClauses |> List.map (function (Clause(pat, optWhenExpr, _, m, _)) -> Clause(pat, optWhenExpr, (SynExpr.Const(SynConst.Int32 1, m)), m, SuppressSequencePointAtTarget)) let checkedFilterClauses, tpenv = TcMatchClauses cenv cenv.g.exn_ty cenv.g.int_ty env tpenv filterClauses - let checkedHandlerClauses, tpenv = TcMatchClauses cenv cenv.g.exn_ty overallTy env tpenv clauses - let v1, filter_expr = CompilePatternForMatchClauses cenv env mWithToLast mWithToLast true FailFilter cenv.g.exn_ty cenv.g.int_ty checkedFilterClauses - let v2, handler_expr = CompilePatternForMatchClauses cenv env mWithToLast mWithToLast true Rethrow cenv.g.exn_ty overallTy checkedHandlerClauses - mkTryWith cenv.g (e1', v1, filter_expr, v2, handler_expr, mTryToLast, overallTy, spTry, spWith), tpenv + let checkedHandlerClauses, tpenv = TcMatchClauses cenv cenv.g.exn_ty overallTy env tpenv synWithClauses + let v1, filterExpr = CompilePatternForMatchClauses cenv env mWithToLast mWithToLast true FailFilter None cenv.g.exn_ty cenv.g.int_ty checkedFilterClauses + let v2, handlerExpr = CompilePatternForMatchClauses cenv env mWithToLast mWithToLast true Rethrow None cenv.g.exn_ty overallTy checkedHandlerClauses + mkTryWith cenv.g (bodyExpr, v1, filterExpr, v2, handlerExpr, mTryToLast, overallTy, spTry, spWith), tpenv - | SynExpr.TryFinally (e1, e2, mTryToLast, spTry, spFinally) -> - let e1', tpenv = TcExpr cenv overallTy env tpenv e1 - let e2', tpenv = TcStmt cenv env tpenv e2 - mkTryFinally cenv.g (e1', e2', mTryToLast, overallTy, spTry, spFinally), tpenv + | SynExpr.TryFinally (synBodyExpr, synFinallyExpr, mTryToLast, spTry, spFinally) -> + let bodyExpr, tpenv = TcExpr cenv overallTy env tpenv synBodyExpr + let finallyExpr, tpenv = TcStmt cenv env tpenv synFinallyExpr + mkTryFinally cenv.g (bodyExpr, finallyExpr, mTryToLast, overallTy, spTry, spFinally), tpenv | SynExpr.JoinIn(e1, mInToken, e2, mAll) -> errorR(Error(FSComp.SR.parsUnfinishedExpression("in"), mInToken)) @@ -5976,47 +6016,47 @@ and TcExprUndelayed cenv overallTy env tpenv (expr: SynExpr) = let _, tpenv = suppressErrorReporting (fun () -> TcExpr cenv overallTy env tpenv e1) mkDefault(m, overallTy), tpenv - | SynExpr.Sequential (sp, dir, e1, e2, m) -> + | SynExpr.Sequential (sp, dir, synExpr1, synExpr2, m) -> if dir then - TcLinearExprs (TcExprThatCanBeCtorBody cenv) cenv env overallTy tpenv false expr (fun x -> x) + TcLinearExprs (TcExprThatCanBeCtorBody cenv) cenv env overallTy tpenv false synExpr (fun x -> x) else // Constructors using "new (...) = then " - let e1', tpenv = TcExprThatCanBeCtorBody cenv overallTy env tpenv e1 + let expr1, tpenv = TcExprThatCanBeCtorBody cenv overallTy env tpenv synExpr1 if (GetCtorShapeCounter env) <> 1 then errorR(Error(FSComp.SR.tcExpressionFormRequiresObjectConstructor(), m)) - let e2', tpenv = TcStmtThatCantBeCtorBody cenv env tpenv e2 - Expr.Sequential(e1', e2', ThenDoSeq, sp, m), tpenv + let expr2, tpenv = TcStmtThatCantBeCtorBody cenv env tpenv synExpr2 + Expr.Sequential(expr1, expr2, ThenDoSeq, sp, m), tpenv - | SynExpr.Do (e1, m) -> - UnifyTypes cenv env m overallTy cenv.g.unit_ty - TcStmtThatCantBeCtorBody cenv env tpenv e1 + | SynExpr.Do (synInnerExpr, m) -> + UnifyTypes cenv env m overallTy cenv.g.unit_ty + TcStmtThatCantBeCtorBody cenv env tpenv synInnerExpr - | SynExpr.IfThenElse (e1, e2, e3opt, spIfToThen, isRecovery, mIfToThen, m) -> - let e1', tpenv = TcExprThatCantBeCtorBody cenv cenv.g.bool_ty env tpenv e1 - let e2', tpenv = + | SynExpr.IfThenElse (synBoolExpr, synThenExpr, synElseExprOpt, spIfToThen, isRecovery, mIfToThen, m) -> + let boolExpr, tpenv = TcExprThatCantBeCtorBody cenv cenv.g.bool_ty env tpenv synBoolExpr + let thenExpr, tpenv = let env = match env.eContextInfo with - | ContextInfo.ElseBranchResult _ -> { env with eContextInfo = ContextInfo.ElseBranchResult e2.Range } + | ContextInfo.ElseBranchResult _ -> { env with eContextInfo = ContextInfo.ElseBranchResult synThenExpr.Range } | _ -> - match e3opt with - | None -> { env with eContextInfo = ContextInfo.OmittedElseBranch e2.Range } - | _ -> { env with eContextInfo = ContextInfo.IfExpression e2.Range } + match synElseExprOpt with + | None -> { env with eContextInfo = ContextInfo.OmittedElseBranch synThenExpr.Range } + | _ -> { env with eContextInfo = ContextInfo.IfExpression synThenExpr.Range } - if not isRecovery && Option.isNone e3opt then + if not isRecovery && Option.isNone synElseExprOpt then UnifyTypes cenv env m cenv.g.unit_ty overallTy - TcExprThatCanBeCtorBody cenv overallTy env tpenv e2 + TcExprThatCanBeCtorBody cenv overallTy env tpenv synThenExpr - let e3', sp2, tpenv = - match e3opt with + let elseExpr, spElse, tpenv = + match synElseExprOpt with | None -> mkUnit cenv.g mIfToThen, SuppressSequencePointAtTarget, tpenv // the fake 'unit' value gets exactly the same range as spIfToThen - | Some e3 -> - let env = { env with eContextInfo = ContextInfo.ElseBranchResult e3.Range } - let e3', tpenv = TcExprThatCanBeCtorBody cenv overallTy env tpenv e3 - e3', SequencePointAtTarget, tpenv + | Some synElseExpr -> + let env = { env with eContextInfo = ContextInfo.ElseBranchResult synElseExpr.Range } + let elseExpr, tpenv = TcExprThatCanBeCtorBody cenv overallTy env tpenv synElseExpr + elseExpr, SequencePointAtTarget, tpenv - primMkCond spIfToThen SequencePointAtTarget sp2 m overallTy e1' e2' e3', tpenv + primMkCond spIfToThen SequencePointAtTarget spElse m overallTy boolExpr thenExpr elseExpr, tpenv // This is for internal use in the libraries only | SynExpr.LibraryOnlyStaticOptimization (constraints, e2, e3, m) -> @@ -6068,7 +6108,7 @@ and TcExprUndelayed cenv overallTy env tpenv (expr: SynExpr) = | SynExpr.TraitCall(tps, memSpfn, arg, m) -> let synTypes = tps |> List.map (fun tp -> SynType.Var(tp, m)) - let (TTrait(_, logicalCompiledName, _, argtys, returnTy, _) as traitInfo), tpenv = TcPseudoMemberSpec cenv NewTyparsOK env synTypes tpenv memSpfn m + let (TTrait(_, logicalCompiledName, _, argTys, returnTy, _) as traitInfo), tpenv = TcPseudoMemberSpec cenv NewTyparsOK env synTypes tpenv memSpfn m if BakedInTraitConstraintNames.Contains logicalCompiledName then warning(BakedInMemberConstraintName(logicalCompiledName, m)) @@ -6076,8 +6116,8 @@ and TcExprUndelayed cenv overallTy env tpenv (expr: SynExpr) = let args, namedCallerArgs = GetMethodArgs arg if not (isNil namedCallerArgs) then errorR(Error(FSComp.SR.tcNamedArgumentsCannotBeUsedInMemberTraits(), m)) // Subsumption at trait calls if arguments have nominal type prior to unification of any arguments or return type - let flexes = argtys |> List.map (isTyparTy cenv.g >> not) - let args', tpenv = TcExprs cenv env m tpenv flexes argtys args + let flexes = argTys |> List.map (isTyparTy cenv.g >> not) + let args', tpenv = TcExprs cenv env m tpenv flexes argTys args AddCxMethodConstraint env.DisplayEnv cenv.css m NoTrace traitInfo UnifyTypes cenv env m overallTy returnTy Expr.Op(TOp.TraitCall(traitInfo), [], args', m), tpenv @@ -6104,11 +6144,11 @@ and TcExprUndelayed cenv overallTy env tpenv (expr: SynExpr) = mkf n e2', tpenv | SynExpr.LibraryOnlyILAssembly (s, tyargs, args, rtys, m) -> - let argtys = NewInferenceTypes args + let argTys = NewInferenceTypes args let tyargs', tpenv = TcTypes cenv NewTyparsOK CheckCxs ItemOccurence.UseInType env tpenv tyargs // No subsumption at uses of IL assembly code - let flexes = argtys |> List.map (fun _ -> false) - let args', tpenv = TcExprs cenv env m tpenv flexes argtys args + let flexes = argTys |> List.map (fun _ -> false) + let args', tpenv = TcExprs cenv env m tpenv flexes argTys args let rtys', tpenv = TcTypes cenv NewTyparsOK CheckCxs ItemOccurence.UseInType env tpenv rtys let returnTy = match rtys' with @@ -6125,17 +6165,21 @@ and TcExprUndelayed cenv overallTy env tpenv (expr: SynExpr) = | SynExpr.YieldOrReturn ((isTrueYield, _), _, m) | SynExpr.YieldOrReturnFrom ((isTrueYield, _), _, m) when isTrueYield -> error(Error(FSComp.SR.tcConstructRequiresListArrayOrSequence(), m)) + | SynExpr.YieldOrReturn ((_, isTrueReturn), _, m) | SynExpr.YieldOrReturnFrom ((_, isTrueReturn), _, m) when isTrueReturn -> error(Error(FSComp.SR.tcConstructRequiresComputationExpressions(), m)) + | SynExpr.YieldOrReturn (_, _, m) | SynExpr.YieldOrReturnFrom (_, _, m) | SynExpr.ImplicitZero m -> error(Error(FSComp.SR.tcConstructRequiresSequenceOrComputations(), m)) + | SynExpr.DoBang (_, m) | SynExpr.LetOrUseBang (_, _, _, _, _, _, m) -> error(Error(FSComp.SR.tcConstructRequiresComputationExpression(), m)) - | SynExpr.MatchBang (_, _, _, _, m) -> + + | SynExpr.MatchBang (_, _, _, m) -> error(Error(FSComp.SR.tcConstructRequiresComputationExpression(), m)) /// Check lambdas as a group, to catch duplicate names in patterns @@ -6177,9 +6221,9 @@ and TcIndexerThen cenv env overallTy mWholeExpr mDot tpenv wholeExpr e1 indexArg match acc with | None -> match tryDestAppTy cenv.g ty with - | Some tcref -> + | ValueSome tcref -> TryFindTyconRefStringAttribute cenv.g mWholeExpr cenv.g.attrib_DefaultMemberAttribute tcref - | None -> + | _ -> match AllPropInfosOfTypeInScope cenv.infoReader env.NameEnv (Some "Item", ad) IgnoreOverrides mWholeExpr ty with | [] -> None | _ -> Some "Item" @@ -6203,7 +6247,7 @@ and TcIndexerThen cenv env overallTy mWholeExpr mDot tpenv wholeExpr e1 indexArg match indexArgs with | [] -> failwith "unexpected empty index list" | [SynIndexerArg.One h] -> SynExpr.Paren(h, range0, None, idxRange) - | _ -> SynExpr.Paren(SynExpr.Tuple(GetIndexArgs indexArgs @ Option.toList vopt, [], idxRange), range0, None, idxRange) + | _ -> SynExpr.Paren(SynExpr.Tuple(false, GetIndexArgs indexArgs @ Option.toList vopt, [], idxRange), range0, None, idxRange) let attemptArrayString = if isArray || isString then @@ -6212,13 +6256,13 @@ and TcIndexerThen cenv env overallTy mWholeExpr mDot tpenv wholeExpr e1 indexArg let sliceOpPath = ["Microsoft";"FSharp";"Core";"Operators";"OperatorIntrinsics"] let info = match isString, isArray, wholeExpr with - | false, true, SynExpr.DotIndexedGet(_, [SynIndexerArg.One(SynExpr.Tuple ([_;_] as idxs, _, _))], _, _) -> Some (indexOpPath, "GetArray2D", idxs) - | false, true, SynExpr.DotIndexedGet(_, [SynIndexerArg.One(SynExpr.Tuple ([_;_;_] as idxs, _, _))], _, _) -> Some (indexOpPath, "GetArray3D", idxs) - | false, true, SynExpr.DotIndexedGet(_, [SynIndexerArg.One(SynExpr.Tuple ([_;_;_;_] as idxs, _, _))], _, _) -> Some (indexOpPath, "GetArray4D", idxs) + | false, true, SynExpr.DotIndexedGet(_, [SynIndexerArg.One(SynExpr.Tuple (false, ([_;_] as idxs), _, _))], _, _) -> Some (indexOpPath, "GetArray2D", idxs) + | false, true, SynExpr.DotIndexedGet(_, [SynIndexerArg.One(SynExpr.Tuple (false, ([_;_;_] as idxs), _, _))], _, _) -> Some (indexOpPath, "GetArray3D", idxs) + | false, true, SynExpr.DotIndexedGet(_, [SynIndexerArg.One(SynExpr.Tuple (false, ([_;_;_;_] as idxs), _, _))], _, _) -> Some (indexOpPath, "GetArray4D", idxs) | false, true, SynExpr.DotIndexedGet(_, [SynIndexerArg.One idx], _, _) -> Some (indexOpPath, "GetArray", [idx]) - | false, true, SynExpr.DotIndexedSet(_, [SynIndexerArg.One(SynExpr.Tuple ([_;_] as idxs, _, _))] , e3, _, _, _) -> Some (indexOpPath, "SetArray2D", (idxs @ [e3])) - | false, true, SynExpr.DotIndexedSet(_, [SynIndexerArg.One(SynExpr.Tuple ([_;_;_] as idxs, _, _))] , e3, _, _, _) -> Some (indexOpPath, "SetArray3D", (idxs @ [e3])) - | false, true, SynExpr.DotIndexedSet(_, [SynIndexerArg.One(SynExpr.Tuple ([_;_;_;_] as idxs, _, _))] , e3, _, _, _) -> Some (indexOpPath, "SetArray4D", (idxs @ [e3])) + | false, true, SynExpr.DotIndexedSet(_, [SynIndexerArg.One(SynExpr.Tuple (false, ([_;_] as idxs), _, _))] , e3, _, _, _) -> Some (indexOpPath, "SetArray2D", (idxs @ [e3])) + | false, true, SynExpr.DotIndexedSet(_, [SynIndexerArg.One(SynExpr.Tuple (false, ([_;_;_] as idxs), _, _))] , e3, _, _, _) -> Some (indexOpPath, "SetArray3D", (idxs @ [e3])) + | false, true, SynExpr.DotIndexedSet(_, [SynIndexerArg.One(SynExpr.Tuple (false, ([_;_;_;_] as idxs), _, _))] , e3, _, _, _) -> Some (indexOpPath, "SetArray4D", (idxs @ [e3])) | false, true, SynExpr.DotIndexedSet(_, [SynIndexerArg.One _], e3, _, _, _) -> Some (indexOpPath, "SetArray", (GetIndexArgs indexArgs @ [e3])) | true, false, SynExpr.DotIndexedGet(_, [SynIndexerArg.Two _], _, _) -> Some (sliceOpPath, "GetStringSlice", GetIndexArgs indexArgs) | true, false, SynExpr.DotIndexedGet(_, [SynIndexerArg.One _], _, _) -> Some (indexOpPath, "GetString", GetIndexArgs indexArgs) @@ -6335,12 +6379,8 @@ and TcCtorCall isNaked cenv env tpenv overallTy objTy mObjTyOpt item superInit a error(Error(FSComp.SR.tcSyntaxCanOnlyBeUsedToCreateObjectTypes(if superInit then "inherit" else "new"), mWholeCall)) -//------------------------------------------------------------------------- -// TcRecordConstruction -//------------------------------------------------------------------------- - // Check a record construction expression -and TcRecordConstruction cenv overallTy env tpenv optOrigExpr objTy fldsList m = +and TcRecordConstruction cenv overallTy env tpenv optOrigExprInfo objTy fldsList m = let tcref, tinst = destAppTy cenv.g objTy let tycon = tcref.Deref UnifyTypes cenv env m overallTy objTy @@ -6371,18 +6411,17 @@ and TcRecordConstruction cenv overallTy env tpenv optOrigExpr objTy fldsList m = // Add rebindings for unbound field when an "old value" is available // Effect order: mutable fields may get modified by other bindings... - let oldFldsList, wrap = - match optOrigExpr with - | None -> [], id - | Some (_, _, oldve) -> - let wrap, oldveaddr, _readonly, _writeonly = mkExprAddrOfExpr cenv.g tycon.IsStructOrEnumTycon false NeverMutates oldve None m + let oldFldsList = + match optOrigExprInfo with + | None -> [] + | Some (_, _, oldvaddre) -> let fieldNameUnbound nom = List.forall (fun (name, _) -> name <> nom) fldsList let flds = fspecs |> List.choose (fun rfld -> if fieldNameUnbound rfld.Name && not rfld.IsZeroInit - then Some(rfld.Name, mkRecdFieldGetViaExprAddr (oldveaddr, tcref.MakeNestedRecdFieldRef rfld, tinst, m)) + then Some(rfld.Name, mkRecdFieldGetViaExprAddr (oldvaddre, tcref.MakeNestedRecdFieldRef rfld, tinst, m)) else None) - flds, wrap + flds let fldsList = fldsList @ oldFldsList @@ -6398,7 +6437,7 @@ and TcRecordConstruction cenv overallTy env tpenv optOrigExpr objTy fldsList m = let ns1 = NameSet.ofList (List.map fst fldsList) let ns2 = NameSet.ofList (List.map (fun x -> x.rfield_id.idText) fspecs) - if Option.isNone optOrigExpr && not (Zset.subset ns2 ns1) then + if optOrigExprInfo.IsNone && not (Zset.subset ns2 ns1) then error (MissingFields(Zset.elements (Zset.diff ns2 ns1), m)) if not (Zset.subset ns1 ns2) then @@ -6415,18 +6454,19 @@ and TcRecordConstruction cenv overallTy env tpenv optOrigExpr objTy fldsList m = let args = List.map snd fldsList - let expr = wrap (mkRecordExpr cenv.g (GetRecdInfo env, tcref, tinst, rfrefs, args, m)) + let expr = mkRecordExpr cenv.g (GetRecdInfo env, tcref, tinst, rfrefs, args, m) let expr = - match optOrigExpr with + match optOrigExprInfo with | None -> // '{ recd fields }'. // expr - | Some (old, oldv, _) -> + | Some (old, oldvaddr, _) -> // '{ recd with fields }'. // Assign the first object to a tmp and then construct - mkCompGenLet m oldv old expr + let wrap, oldaddr, _readonly, _writeonly = mkExprAddrOfExpr cenv.g tycon.IsStructOrEnumTycon false NeverMutates old None m + wrap (mkCompGenLet m oldvaddr oldaddr expr) expr, tpenv @@ -6661,8 +6701,8 @@ and TcObjectExpr cenv overallTy env tpenv (synObjTy, argopt, binds, extraImpls, let objTy, tpenv = TcType cenv NewTyparsOK CheckCxs ItemOccurence.UseInType env tpenv synObjTy match tryDestAppTy cenv.g objTy with - | None -> error(Error(FSComp.SR.tcNewMustBeUsedWithNamedType(), mNewExpr)) - | Some tcref -> + | ValueNone -> error(Error(FSComp.SR.tcNewMustBeUsedWithNamedType(), mNewExpr)) + | ValueSome tcref -> let isRecordTy = isRecdTy cenv.g objTy if not isRecordTy && not (isInterfaceTy cenv.g objTy) && isSealedTy cenv.g objTy then errorR(Error(FSComp.SR.tcCannotCreateExtensionOfSealedType(), mNewExpr)) @@ -6678,9 +6718,9 @@ and TcObjectExpr cenv overallTy env tpenv (synObjTy, argopt, binds, extraImpls, if // record construction ? isRecordTy || // object construction? - (isFSharpObjModelTy cenv.g objTy && not (isInterfaceTy cenv.g objTy) && Option.isNone argopt) then + (isFSharpObjModelTy cenv.g objTy && not (isInterfaceTy cenv.g objTy) && argopt.IsNone) then - if Option.isSome argopt then error(Error(FSComp.SR.tcNoArgumentsForRecordValue(), mWholeExpr)) + if argopt.IsSome then error(Error(FSComp.SR.tcNoArgumentsForRecordValue(), mWholeExpr)) if not (isNil extraImpls) then error(Error(FSComp.SR.tcNoInterfaceImplementationForConstructionExpression(), mNewExpr)) if isFSharpObjModelTy cenv.g objTy && GetCtorShapeCounter env <> 1 then error(Error(FSComp.SR.tcObjectConstructionCanOnlyBeUsedInClassTypes(), mNewExpr)) @@ -6887,17 +6927,12 @@ and TcAssertExpr cenv overallTy env (m:range) tpenv x = TcExpr cenv overallTy env tpenv callDiagnosticsExpr - -//------------------------------------------------------------------------- -// TcRecdExpr -//------------------------------------------------------------------------- - and TcRecdExpr cenv overallTy env tpenv (inherits, optOrigExpr, flds, mWholeExpr) = let requiresCtor = (GetCtorShapeCounter env = 1) // Get special expression forms for constructors let haveCtor = Option.isSome inherits - let optOrigExpr, tpenv = + let optOrigExprInfo, tpenv = match optOrigExpr with | None -> None, tpenv | Some (origExpr, _) -> @@ -6905,10 +6940,10 @@ and TcRecdExpr cenv overallTy env tpenv (inherits, optOrigExpr, flds, mWholeExpr | Some (_, _, mInherits, _, _) -> error(Error(FSComp.SR.tcInvalidRecordConstruction(), mInherits)) | None -> let olde, tpenv = TcExpr cenv overallTy env tpenv origExpr - let oldv, oldve = mkCompGenLocal mWholeExpr "inputRecord" overallTy - Some (olde, oldv, oldve), tpenv + let oldvaddr, oldvaddre = mkCompGenLocal mWholeExpr "inputRecord" (if isStructTy cenv.g overallTy then mkByrefTy cenv.g overallTy else overallTy) + Some (olde, oldvaddr, oldvaddre), tpenv - let hasOrigExpr = Option.isSome optOrigExpr + let hasOrigExpr = optOrigExprInfo.IsSome let fldsList = let flds = @@ -6968,7 +7003,7 @@ and TcRecdExpr cenv overallTy env tpenv (inherits, optOrigExpr, flds, mWholeExpr errorR(InternalError("Unexpected failure in getting super type", mWholeExpr)) None, tpenv - let expr, tpenv = TcRecordConstruction cenv overallTy env tpenv optOrigExpr overallTy fldsList mWholeExpr + let expr, tpenv = TcRecordConstruction cenv overallTy env tpenv optOrigExprInfo overallTy fldsList mWholeExpr let expr = match superTy with @@ -6978,9 +7013,104 @@ and TcRecdExpr cenv overallTy env tpenv (inherits, optOrigExpr, flds, mWholeExpr expr, tpenv -//------------------------------------------------------------------------- -// TcForEachExpr -//------------------------------------------------------------------------- +// Check '{| .... |}' +and TcAnonRecdExpr cenv overallTy env tpenv (isStruct, optOrigExpr, unsortedArgs, mWholeExpr) = + + match optOrigExpr with + | None -> + let unsortedIds = unsortedArgs |> List.map fst |> List.toArray + let anonInfo, sortedArgTys = UnifyAnonRecdTypeAndInferCharacteristics env.eContextInfo cenv env.DisplayEnv mWholeExpr overallTy isStruct unsortedIds + + // Sort into canonical order + let sortedIndexedArgs = unsortedArgs |> List.indexed |> List.sortBy (fun (i,_) -> unsortedIds.[i].idText) + let sigma = List.map fst sortedIndexedArgs |> List.toArray + let sortedArgs = List.map snd sortedIndexedArgs + sortedArgs |> List.iteri (fun j (x, _) -> + let item = Item.AnonRecdField(anonInfo, sortedArgTys, j, x.idRange) + CallNameResolutionSink cenv.tcSink (x.idRange, env.NameEnv, item, item, emptyTyparInst, ItemOccurence.Use, env.DisplayEnv, env.eAccessRights)) + let unsortedArgTys = sortedArgTys |> List.indexed |> List.sortBy (fun (j, _) -> sigma.[j]) |> List.map snd + let flexes = unsortedArgTys |> List.map (fun _ -> true) + let unsortedCheckedArgs, tpenv = TcExprs cenv env mWholeExpr tpenv flexes unsortedArgTys (List.map snd unsortedArgs) + let sortedCheckedArgs = unsortedCheckedArgs |> List.indexed |> List.sortBy (fun (i,_) -> unsortedIds.[i].idText) |> List.map snd + + mkAnonRecd cenv.g mWholeExpr anonInfo sortedCheckedArgs sortedArgTys, tpenv + + | Some (origExpr, _) -> + // The fairly complex case '{| origExpr with X = 1; Y = 2 |}' + // The origExpr may be either a record or anonymous record. + // The origExpr may be either a struct or not. + // All the properties of origExpr are copied across except where they are overridden. + // The result is a field-sorted anonymous record. + // + // Unlike in the case of record type copy-and-update we do _not_ assume that the origExpr has the same type as the overall expression. + // Unlike in the case of record type copy-and-update {| a with X = 1 |} does not force a.X to exist or have had type 'int' + + let origExprTy = NewInferenceType() + let origExprChecked, tpenv = TcExpr cenv origExprTy env tpenv origExpr + let oldv, oldve = mkCompGenLocal mWholeExpr "inputRecord" origExprTy + let mOrigExpr = origExpr.Range + + if not (isAppTy cenv.g origExprTy || isAnonRecdTy cenv.g origExprTy) then + error (Error (FSComp.SR.tcCopyAndUpdateNeedsRecordType(), mOrigExpr)) + + let origExprIsStruct = + match tryDestAnonRecdTy cenv.g origExprTy with + | ValueSome (anonInfo, _) -> evalTupInfoIsStruct anonInfo.TupInfo + | ValueNone -> + let tcref, _ = destAppTy cenv.g origExprTy + tcref.IsStructOrEnumTycon + + let wrap, oldveaddr, _readonly, _writeonly = mkExprAddrOfExpr cenv.g origExprIsStruct false NeverMutates oldve None mOrigExpr + + // Put all the expressions in unsorted order. The new bindings come first. The origin of each is tracked using + /// - Choice1Of2 for a new binding + /// - Choice2Of2 for a binding coming from the original expression + let unsortedIdAndExprsAll = + [| for (id, e) in unsortedArgs do + yield (id, Choice1Of2 e) + match tryDestAnonRecdTy cenv.g origExprTy with + | ValueSome (anonInfo, tinst) -> + for (i, id) in Array.indexed anonInfo.SortedIds do + yield id, Choice2Of2 (mkAnonRecdFieldGetViaExprAddr (anonInfo, oldveaddr, tinst, i, mOrigExpr)) + | ValueNone -> + if isRecdTy cenv.g origExprTy then + let tcref, tinst = destAppTy cenv.g origExprTy + let fspecs = tcref.Deref.TrueInstanceFieldsAsList + for fspec in fspecs do + yield fspec.Id, Choice2Of2 (mkRecdFieldGetViaExprAddr (oldveaddr , tcref.MakeNestedRecdFieldRef fspec, tinst, mOrigExpr)) + else + error (Error (FSComp.SR.tcCopyAndUpdateNeedsRecordType(), mOrigExpr)) |] + |> Array.distinctBy (fst >> textOfId) + + let unsortedIdsAll = Array.map fst unsortedIdAndExprsAll + let anonInfo, sortedArgTysAll = UnifyAnonRecdTypeAndInferCharacteristics env.eContextInfo cenv env.DisplayEnv mWholeExpr overallTy isStruct unsortedIdsAll + let sortedIndexedArgsAll = unsortedIdAndExprsAll |> Array.indexed |> Array.sortBy (snd >> fst >> textOfId) + let sigma = Array.map fst sortedIndexedArgsAll // map from sorted indexes to unsorted indexes + let sortedArgsAll = Array.map snd sortedIndexedArgsAll + sortedArgsAll |> Array.iteri (fun j (x, expr) -> + match expr with + | Choice1Of2 _ -> + let item = Item.AnonRecdField(anonInfo, sortedArgTysAll, j, x.idRange) + CallNameResolutionSink cenv.tcSink (x.idRange, env.NameEnv, item, item, emptyTyparInst, ItemOccurence.Use, env.DisplayEnv, env.eAccessRights) + | Choice2Of2 _ -> ()) + + let unsortedArgTysNew = sortedArgTysAll |> List.indexed |> List.sortBy (fun (j, _) -> sigma.[j]) |> List.take unsortedArgs.Length |> List.map snd + let flexes = unsortedArgTysNew |> List.map (fun _ -> true) + + let unsortedCheckedArgsNew, tpenv = TcExprs cenv env mWholeExpr tpenv flexes unsortedArgTysNew (List.map snd unsortedArgs) + let sortedArgTysAllArray = Array.ofList sortedArgTysAll + let unsortedCheckedArgsNewArray = unsortedCheckedArgsNew |> List.toArray + let sortedCheckedArgsAll = + sortedArgsAll |> Array.mapi (fun j (_, expr) -> + match expr with + | Choice1Of2 _ -> unsortedCheckedArgsNewArray.[sigma.[j]] + | Choice2Of2 subExpr -> UnifyTypes cenv env mOrigExpr (tyOfExpr cenv.g subExpr) sortedArgTysAllArray.[j]; subExpr) + + let expr = mkAnonRecd cenv.g mWholeExpr anonInfo (List.ofArray sortedCheckedArgsAll) sortedArgTysAll + let expr = wrap expr + let expr = mkCompGenLet mOrigExpr oldv origExprChecked expr + expr, tpenv + and TcForEachExpr cenv overallTy env tpenv (pat, enumSynExpr, bodySynExpr, mWholeExpr, spForLoop) = UnifyTypes cenv env mWholeExpr overallTy cenv.g.unit_ty @@ -7041,7 +7171,7 @@ and TcForEachExpr cenv overallTy env tpenv (pat, enumSynExpr, bodySynExpr, mWhol let bodyExpr = let valsDefinedByMatching = ListSet.remove valEq elemVar vspecs CompilePatternForMatch - cenv env enumSynExpr.Range pat.Range false IgnoreWithWarning (elemVar, []) + cenv env enumSynExpr.Range pat.Range false IgnoreWithWarning (elemVar, [], None) [TClause(pat, None, TTarget(valsDefinedByMatching, bodyExpr, SequencePointAtTarget), mForLoopStart)] enumElemTy overallTy @@ -7144,7 +7274,7 @@ and TcComputationExpression cenv env overallTy mWhole interpExpr builderTy tpenv match args with | [] -> SynExpr.Const(SynConst.Unit, m) | [arg] -> SynExpr.Paren(SynExpr.Paren(arg, range0, None, m), range0, None, m) - | args -> SynExpr.Paren(SynExpr.Tuple(args, [], m), range0, None, m) + | args -> SynExpr.Paren(SynExpr.Tuple(false, args, [], m), range0, None, m) let builderVal = mkSynIdGet m builderValName mkSynApp1 (SynExpr.DotGet(builderVal, range0, LongIdentWithDots([mkSynId m nm], []), m)) args m @@ -7510,7 +7640,7 @@ and TcComputationExpression cenv env overallTy mWhole interpExpr builderTy tpenv match patvs with | [] -> SynExpr.Const(SynConst.Unit, m) | [v] -> SynExpr.Ident v.Id - | vs -> SynExpr.Tuple((vs |> List.map (fun v -> SynExpr.Ident v.Id)), [], m) + | vs -> SynExpr.Tuple(false, (vs |> List.map (fun v -> SynExpr.Ident v.Id)), [], m) let mkSimplePatForVarSpace m (patvs: Val list) = let spats = @@ -7524,7 +7654,7 @@ and TcComputationExpression cenv env overallTy mWhole interpExpr builderTy tpenv match patvs with | [] -> SynPat.Const (SynConst.Unit, m) | [v] -> mkSynPatVar None v.Id - | vs -> SynPat.Tuple((vs |> List.map (fun x -> mkSynPatVar None x.Id)), m) + | vs -> SynPat.Tuple(false, (vs |> List.map (fun x -> mkSynPatVar None x.Id)), m) let (|OptionalSequential|) e = match e with @@ -7541,7 +7671,7 @@ and TcComputationExpression cenv env overallTy mWhole interpExpr builderTy tpenv let estimatedRangeOfIntendedLeftAndRightArguments = unionRanges (List.last args).Range arg2.Range errorR(Error(FSComp.SR.tcUnrecognizedQueryBinaryOperator(), estimatedRangeOfIntendedLeftAndRightArguments)) true - | SynExpr.Tuple( (StripApps(SingleIdent nm2, args) :: _), _, m) when + | SynExpr.Tuple(false, (StripApps(SingleIdent nm2, args) :: _), _, m) when expectedArgCountForCustomOperator nm2 > 0 && not (List.isEmpty args) -> let estimatedRangeOfIntendedLeftAndRightArguments = unionRanges (List.last args).Range m.EndRange @@ -7928,7 +8058,7 @@ and TcComputationExpression cenv env overallTy mWhole interpExpr builderTy tpenv let m1 = match innerComp1 with | SynExpr.IfThenElse (_, _, _, _, _, mIfToThen, _m) -> mIfToThen - | SynExpr.Match (SequencePointAtBinding mMatch, _, _, _, _) -> mMatch + | SynExpr.Match (SequencePointAtBinding mMatch, _, _, _) -> mMatch | SynExpr.TryWith (_, _, _, _, _, SequencePointAtTry mTry, _) -> mTry | SynExpr.TryFinally (_, _, _, SequencePointAtTry mTry, _) -> mTry | SynExpr.For (SequencePointAtForLoop mBind, _, _, _, _, _, _) -> mBind @@ -8041,14 +8171,14 @@ and TcComputationExpression cenv env overallTy mWhole interpExpr builderTy tpenv | SynExpr.LetOrUseBang(_spBind, true, _isFromSource, pat, _rhsExpr, _innerComp, _) -> error(Error(FSComp.SR.tcInvalidUseBangBinding(), pat.Range)) - | SynExpr.Match (spMatch, expr, clauses, false, m) -> + | SynExpr.Match (spMatch, expr, clauses, m) -> let mMatch = match spMatch with SequencePointAtBinding mMatch -> mMatch | _ -> m if isQuery then error(Error(FSComp.SR.tcMatchMayNotBeUsedWithQuery(), mMatch)) let clauses = clauses |> List.map (fun (Clause(pat, cond, innerComp, patm, sp)) -> Clause(pat, cond, transNoQueryOps innerComp, patm, sp)) - Some(translatedCtxt (SynExpr.Match(spMatch, expr, clauses, false, m))) + Some(translatedCtxt (SynExpr.Match(spMatch, expr, clauses, m))) // 'match! expr with pats ...' --> build.Bind(e1, (function pats ...)) - | SynExpr.MatchBang (spMatch, expr, clauses, false, m) -> + | SynExpr.MatchBang (spMatch, expr, clauses, m) -> let mMatch = match spMatch with SequencePointAtBinding mMatch -> mMatch | _ -> m if isQuery then error(Error(FSComp.SR.tcMatchMayNotBeUsedWithQuery(), mMatch)) if isNil (TryFindIntrinsicOrExtensionMethInfo cenv env mMatch ad "Bind" builderTy) then error(Error(FSComp.SR.tcRequireBuilderMethod("Bind"), mMatch)) @@ -8164,180 +8294,180 @@ and TcComputationExpression cenv env overallTy mWhole interpExpr builderTy tpenv /// Also "ienumerable extraction" is performed on arguments to "for". and TcSequenceExpression cenv env tpenv comp overallTy m = - let genEnumElemTy = NewInferenceType () - UnifyTypes cenv env m overallTy (mkSeqTy cenv.g genEnumElemTy) + let genEnumElemTy = NewInferenceType () + UnifyTypes cenv env m overallTy (mkSeqTy cenv.g genEnumElemTy) - // Allow subsumption at 'yield' if the element type is nominal prior to the analysis of the body of the sequence expression - let flex = not (isTyparTy cenv.g genEnumElemTy) + // Allow subsumption at 'yield' if the element type is nominal prior to the analysis of the body of the sequence expression + let flex = not (isTyparTy cenv.g genEnumElemTy) - let mkDelayedExpr (coreExpr:Expr) = - let m = coreExpr.Range - let overallTy = tyOfExpr cenv.g coreExpr - mkSeqDelay cenv env m overallTy coreExpr + let mkDelayedExpr (coreExpr:Expr) = + let m = coreExpr.Range + let overallTy = tyOfExpr cenv.g coreExpr + mkSeqDelay cenv env m overallTy coreExpr - let rec tryTcSequenceExprBody env genOuterTy tpenv comp = - match comp with - | SynExpr.ForEach (_spBind, SeqExprOnly _seqExprOnly, _isFromSource, pat, pseudoEnumExpr, innerComp, m) -> - // This expression is not checked with the knowledge it is an IEnumerable, since we permit other enumerable types with GetEnumerator/MoveNext methods, as does C# - let pseudoEnumExpr, arb_ty, tpenv = TcExprOfUnknownType cenv env tpenv pseudoEnumExpr - let enumExpr, enumElemTy = ConvertArbitraryExprToEnumerable cenv arb_ty env pseudoEnumExpr - let pat', _, vspecs, envinner, tpenv = TcMatchPattern cenv enumElemTy env tpenv (pat, None) - let innerExpr, tpenv = tcSequenceExprBody envinner genOuterTy tpenv innerComp + let rec tryTcSequenceExprBody env genOuterTy tpenv comp = + match comp with + | SynExpr.ForEach (_spBind, SeqExprOnly _seqExprOnly, _isFromSource, pat, pseudoEnumExpr, innerComp, m) -> + // This expression is not checked with the knowledge it is an IEnumerable, since we permit other enumerable types with GetEnumerator/MoveNext methods, as does C# + let pseudoEnumExpr, arb_ty, tpenv = TcExprOfUnknownType cenv env tpenv pseudoEnumExpr + let enumExpr, enumElemTy = ConvertArbitraryExprToEnumerable cenv arb_ty env pseudoEnumExpr + let pat', _, vspecs, envinner, tpenv = TcMatchPattern cenv enumElemTy env tpenv (pat, None) + let innerExpr, tpenv = tcSequenceExprBody envinner genOuterTy tpenv innerComp - match pat', vspecs, innerExpr with - // peephole optimization: "for x in e1 -> e2" == "e1 |> List.map (fun x -> e2)" *) - | (TPat_as (TPat_wild _, PBind (v, _), _), - vs, - Expr.App(Expr.Val(vf, _, _), _, [genEnumElemTy], [yexpr], _)) - when vs.Length = 1 && valRefEq cenv.g vf cenv.g.seq_singleton_vref -> + match pat', vspecs, innerExpr with + // peephole optimization: "for x in e1 -> e2" == "e1 |> List.map (fun x -> e2)" *) + | (TPat_as (TPat_wild _, PBind (v, _), _), + vs, + Expr.App(Expr.Val(vf, _, _), _, [genEnumElemTy], [yexpr], _)) + when vs.Length = 1 && valRefEq cenv.g vf cenv.g.seq_singleton_vref -> - let enumExprMark = enumExpr.Range - let lam = mkLambda enumExprMark v (yexpr, genEnumElemTy) + let enumExprMark = enumExpr.Range + let lam = mkLambda enumExprMark v (yexpr, genEnumElemTy) - // SEQUENCE POINTS: need to build a let here consuming spBind - let enumExpr = mkCoerceIfNeeded cenv.g (mkSeqTy cenv.g enumElemTy) (tyOfExpr cenv.g enumExpr) enumExpr - Some(mkCallSeqMap cenv.g m enumElemTy genEnumElemTy lam enumExpr, tpenv) + // SEQUENCE POINTS: need to build a let here consuming spBind + let enumExpr = mkCoerceIfNeeded cenv.g (mkSeqTy cenv.g enumElemTy) (tyOfExpr cenv.g enumExpr) enumExpr + Some(mkCallSeqMap cenv.g m enumElemTy genEnumElemTy lam enumExpr, tpenv) - | _ -> - let enumExprMark = enumExpr.Range + | _ -> + let enumExprMark = enumExpr.Range - // SEQUENCE POINTS: need to build a let here consuming spBind + // SEQUENCE POINTS: need to build a let here consuming spBind - let matchv, matchExpr = compileSeqExprMatchClauses cenv env enumExprMark (pat', vspecs) innerExpr enumElemTy genOuterTy - let lam = mkLambda enumExprMark matchv (matchExpr, tyOfExpr cenv.g matchExpr) - Some(mkSeqCollect cenv env m enumElemTy genOuterTy lam enumExpr , tpenv) + let matchv, matchExpr = compileSeqExprMatchClauses cenv env enumExprMark (pat', vspecs) innerExpr None enumElemTy genOuterTy + let lam = mkLambda enumExprMark matchv (matchExpr, tyOfExpr cenv.g matchExpr) + Some(mkSeqCollect cenv env m enumElemTy genOuterTy lam enumExpr , tpenv) - | SynExpr.For (spBind, id, start, dir, finish, innerComp, m) -> - Some(tcSequenceExprBody env genOuterTy tpenv (elimFastIntegerForLoop (spBind, id, start, dir, finish, innerComp, m))) + | SynExpr.For (spBind, id, start, dir, finish, innerComp, m) -> + Some(tcSequenceExprBody env genOuterTy tpenv (elimFastIntegerForLoop (spBind, id, start, dir, finish, innerComp, m))) - | SynExpr.While (_spWhile, guardExpr, innerComp, _m) -> - let guardExpr, tpenv = TcExpr cenv cenv.g.bool_ty env tpenv guardExpr - let innerExpr, tpenv = tcSequenceExprBody env genOuterTy tpenv innerComp + | SynExpr.While (_spWhile, guardExpr, innerComp, _m) -> + let guardExpr, tpenv = TcExpr cenv cenv.g.bool_ty env tpenv guardExpr + let innerExpr, tpenv = tcSequenceExprBody env genOuterTy tpenv innerComp - let guardExprMark = guardExpr.Range - let guardExpr = mkUnitDelayLambda cenv.g guardExprMark guardExpr - let innerExpr = mkDelayedExpr innerExpr - Some(mkSeqFromFunctions cenv env guardExprMark genOuterTy guardExpr innerExpr, tpenv) - - | SynExpr.TryFinally (innerComp, unwindExpr, _mTryToLast, _spTry, _spFinally) -> - let innerExpr, tpenv = tcSequenceExprBody env genOuterTy tpenv innerComp - let unwindExpr, tpenv = TcExpr cenv cenv.g.unit_ty env tpenv unwindExpr + let guardExprMark = guardExpr.Range + let guardExpr = mkUnitDelayLambda cenv.g guardExprMark guardExpr + let innerExpr = mkDelayedExpr innerExpr + Some(mkSeqFromFunctions cenv env guardExprMark genOuterTy guardExpr innerExpr, tpenv) + + | SynExpr.TryFinally (innerComp, unwindExpr, _mTryToLast, _spTry, _spFinally) -> + let innerExpr, tpenv = tcSequenceExprBody env genOuterTy tpenv innerComp + let unwindExpr, tpenv = TcExpr cenv cenv.g.unit_ty env tpenv unwindExpr - let unwindExprMark = unwindExpr.Range - let unwindExpr = mkUnitDelayLambda cenv.g unwindExprMark unwindExpr - let innerExpr = mkDelayedExpr innerExpr - let innerExprMark = innerExpr.Range + let unwindExprMark = unwindExpr.Range + let unwindExpr = mkUnitDelayLambda cenv.g unwindExprMark unwindExpr + let innerExpr = mkDelayedExpr innerExpr + let innerExprMark = innerExpr.Range - Some(mkSeqFinally cenv env innerExprMark genOuterTy innerExpr unwindExpr, tpenv) - | SynExpr.Paren (_, _, _, m) -> - error(Error(FSComp.SR.tcConstructIsAmbiguousInSequenceExpression(), m)) + Some(mkSeqFinally cenv env innerExprMark genOuterTy innerExpr unwindExpr, tpenv) + | SynExpr.Paren (_, _, _, m) -> + error(Error(FSComp.SR.tcConstructIsAmbiguousInSequenceExpression(), m)) - | SynExpr.ImplicitZero m -> - Some(mkSeqEmpty cenv env m genOuterTy, tpenv ) + | SynExpr.ImplicitZero m -> + Some(mkSeqEmpty cenv env m genOuterTy, tpenv ) - | SynExpr.DoBang(_rhsExpr, m) -> - error(Error(FSComp.SR.tcDoBangIllegalInSequenceExpression(), m)) + | SynExpr.DoBang(_rhsExpr, m) -> + error(Error(FSComp.SR.tcDoBangIllegalInSequenceExpression(), m)) - | SynExpr.Sequential(sp, true, innerComp1, innerComp2, m) -> - // "expr; cexpr" is treated as sequential execution - // "cexpr; cexpr" is treated as append - match tryTcSequenceExprBody env genOuterTy tpenv innerComp1 with - | None -> - let innerExpr1, tpenv = TcStmtThatCantBeCtorBody cenv env tpenv innerComp1 - let innerExpr2, tpenv = tcSequenceExprBody env genOuterTy tpenv innerComp2 - - Some(Expr.Sequential(innerExpr1, innerExpr2, NormalSeq, sp, m), tpenv) - - | Some (innerExpr1, tpenv) -> - let innerExpr2, tpenv = tcSequenceExprBody env genOuterTy tpenv innerComp2 - let innerExpr2 = mkDelayedExpr innerExpr2 - Some(mkSeqAppend cenv env innerComp1.Range genOuterTy innerExpr1 innerExpr2, tpenv) - - | SynExpr.IfThenElse (guardExpr, thenComp, elseCompOpt, spIfToThen, _isRecovery, mIfToThen, mIfToEndOfElseBranch) -> - let guardExpr', tpenv = TcExpr cenv cenv.g.bool_ty env tpenv guardExpr - let thenExpr, tpenv = tcSequenceExprBody env genOuterTy tpenv thenComp - let elseComp = (match elseCompOpt with Some c -> c | None -> SynExpr.ImplicitZero mIfToThen) - let elseExpr, tpenv = tcSequenceExprBody env genOuterTy tpenv elseComp - Some(mkCond spIfToThen SequencePointAtTarget mIfToEndOfElseBranch genOuterTy guardExpr' thenExpr elseExpr, tpenv) - - // 'let x = expr in expr' - | SynExpr.LetOrUse (_, false (* not a 'use' binding *), _, _, _) -> - TcLinearExprs - (fun ty envinner tpenv e -> tcSequenceExprBody envinner ty tpenv e) - cenv env overallTy - tpenv - true - comp - (fun x -> x) |> Some - - // 'use x = expr in expr' - | SynExpr.LetOrUse (_isRec, true, [Binding (_vis, NormalBinding, _, _, _, _, _, pat, _, rhsExpr, _, _spBind)], innerComp, wholeExprMark) -> - - let bindPatTy = NewInferenceType () - let inputExprTy = NewInferenceType () - let pat', _, vspecs, envinner, tpenv = TcMatchPattern cenv bindPatTy env tpenv (pat, None) - UnifyTypes cenv env m inputExprTy bindPatTy - let inputExpr, tpenv = TcExpr cenv inputExprTy env tpenv rhsExpr - let innerExpr, tpenv = tcSequenceExprBody envinner genOuterTy tpenv innerComp - let inputExprMark = inputExpr.Range - let matchv, matchExpr = compileSeqExprMatchClauses cenv env inputExprMark (pat', vspecs) innerExpr bindPatTy genOuterTy - let consumeExpr = mkLambda wholeExprMark matchv (matchExpr, genOuterTy) - //SEQPOINT NEEDED - we must consume spBind on this path - Some(mkSeqUsing cenv env wholeExprMark bindPatTy genOuterTy inputExpr consumeExpr, tpenv) - - | SynExpr.LetOrUseBang(_, _, _, _, _, _, m) -> - error(Error(FSComp.SR.tcUseForInSequenceExpression(), m)) - - | SynExpr.Match (spMatch, expr, clauses, false, _) -> - let inputExpr, matchty, tpenv = TcExprOfUnknownType cenv env tpenv expr - let tclauses, tpenv = - List.mapFold - (fun tpenv (Clause(pat, cond, innerComp, _, sp)) -> - let pat', cond', vspecs, envinner, tpenv = TcMatchPattern cenv matchty env tpenv (pat, cond) - let innerExpr, tpenv = tcSequenceExprBody envinner genOuterTy tpenv innerComp - TClause(pat', cond', TTarget(vspecs, innerExpr, sp), pat'.Range), tpenv) - tpenv - clauses - let inputExprTy = tyOfExpr cenv.g inputExpr - let inputExprMark = inputExpr.Range - let matchv, matchExpr = CompilePatternForMatchClauses cenv env inputExprMark inputExprMark true ThrowIncompleteMatchException inputExprTy genOuterTy tclauses - Some(mkLet spMatch inputExprMark matchv inputExpr matchExpr, tpenv) - - | SynExpr.TryWith (_, mTryToWith, _, _, _, _, _) -> - error(Error(FSComp.SR.tcTryIllegalInSequenceExpression(), mTryToWith)) - - | SynExpr.YieldOrReturnFrom((isYield, _), yieldExpr, m) -> - let resultExpr, genExprTy, tpenv = TcExprOfUnknownType cenv env tpenv yieldExpr - - if not isYield then errorR(Error(FSComp.SR.tcUseYieldBangForMultipleResults(), m)) - - AddCxTypeMustSubsumeType ContextInfo.NoContext env.DisplayEnv cenv.css m NoTrace genOuterTy genExprTy - Some(mkCoerceExpr(resultExpr, genOuterTy, m, genExprTy), tpenv) - - | SynExpr.YieldOrReturn((isYield, _), yieldExpr, m) -> - let genResultTy = NewInferenceType () - if not isYield then errorR(Error(FSComp.SR.tcSeqResultsUseYield(), m)) - UnifyTypes cenv env m genOuterTy (mkSeqTy cenv.g genResultTy) - - let resultExpr, tpenv = TcExprFlex cenv flex true genResultTy env tpenv yieldExpr - Some(mkCallSeqSingleton cenv.g m genResultTy resultExpr, tpenv ) + | SynExpr.Sequential(sp, true, innerComp1, innerComp2, m) -> + // "expr; cexpr" is treated as sequential execution + // "cexpr; cexpr" is treated as append + match tryTcSequenceExprBody env genOuterTy tpenv innerComp1 with + | None -> + let innerExpr1, tpenv = TcStmtThatCantBeCtorBody cenv env tpenv innerComp1 + let innerExpr2, tpenv = tcSequenceExprBody env genOuterTy tpenv innerComp2 + + Some(Expr.Sequential(innerExpr1, innerExpr2, NormalSeq, sp, m), tpenv) + + | Some (innerExpr1, tpenv) -> + let innerExpr2, tpenv = tcSequenceExprBody env genOuterTy tpenv innerComp2 + let innerExpr2 = mkDelayedExpr innerExpr2 + Some(mkSeqAppend cenv env innerComp1.Range genOuterTy innerExpr1 innerExpr2, tpenv) + + | SynExpr.IfThenElse (guardExpr, thenComp, elseCompOpt, spIfToThen, _isRecovery, mIfToThen, mIfToEndOfElseBranch) -> + let guardExpr', tpenv = TcExpr cenv cenv.g.bool_ty env tpenv guardExpr + let thenExpr, tpenv = tcSequenceExprBody env genOuterTy tpenv thenComp + let elseComp = (match elseCompOpt with Some c -> c | None -> SynExpr.ImplicitZero mIfToThen) + let elseExpr, tpenv = tcSequenceExprBody env genOuterTy tpenv elseComp + Some(mkCond spIfToThen SequencePointAtTarget mIfToEndOfElseBranch genOuterTy guardExpr' thenExpr elseExpr, tpenv) + + // 'let x = expr in expr' + | SynExpr.LetOrUse (_, false (* not a 'use' binding *), _, _, _) -> + TcLinearExprs + (fun ty envinner tpenv e -> tcSequenceExprBody envinner ty tpenv e) + cenv env overallTy + tpenv + true + comp + (fun x -> x) |> Some - | _ -> None + // 'use x = expr in expr' + | SynExpr.LetOrUse (_isRec, true, [Binding (_vis, NormalBinding, _, _, _, _, _, pat, _, rhsExpr, _, _spBind)], innerComp, wholeExprMark) -> + + let bindPatTy = NewInferenceType () + let inputExprTy = NewInferenceType () + let pat', _, vspecs, envinner, tpenv = TcMatchPattern cenv bindPatTy env tpenv (pat, None) + UnifyTypes cenv env m inputExprTy bindPatTy + let inputExpr, tpenv = TcExpr cenv inputExprTy env tpenv rhsExpr + let innerExpr, tpenv = tcSequenceExprBody envinner genOuterTy tpenv innerComp + let inputExprMark = inputExpr.Range + let matchv, matchExpr = compileSeqExprMatchClauses cenv env inputExprMark (pat', vspecs) innerExpr (Some inputExpr) bindPatTy genOuterTy + let consumeExpr = mkLambda wholeExprMark matchv (matchExpr, genOuterTy) + //SEQPOINT NEEDED - we must consume spBind on this path + Some(mkSeqUsing cenv env wholeExprMark bindPatTy genOuterTy inputExpr consumeExpr, tpenv) + + | SynExpr.LetOrUseBang(_, _, _, _, _, _, m) -> + error(Error(FSComp.SR.tcUseForInSequenceExpression(), m)) + + | SynExpr.Match (spMatch, expr, clauses, _) -> + let inputExpr, matchty, tpenv = TcExprOfUnknownType cenv env tpenv expr + let tclauses, tpenv = + List.mapFold + (fun tpenv (Clause(pat, cond, innerComp, _, sp)) -> + let pat', cond', vspecs, envinner, tpenv = TcMatchPattern cenv matchty env tpenv (pat, cond) + let innerExpr, tpenv = tcSequenceExprBody envinner genOuterTy tpenv innerComp + TClause(pat', cond', TTarget(vspecs, innerExpr, sp), pat'.Range), tpenv) + tpenv + clauses + let inputExprTy = tyOfExpr cenv.g inputExpr + let inputExprMark = inputExpr.Range + let matchv, matchExpr = CompilePatternForMatchClauses cenv env inputExprMark inputExprMark true ThrowIncompleteMatchException (Some inputExpr) inputExprTy genOuterTy tclauses + Some(mkLet spMatch inputExprMark matchv inputExpr matchExpr, tpenv) + + | SynExpr.TryWith (_, mTryToWith, _, _, _, _, _) -> + error(Error(FSComp.SR.tcTryIllegalInSequenceExpression(), mTryToWith)) + + | SynExpr.YieldOrReturnFrom((isYield, _), yieldExpr, m) -> + let resultExpr, genExprTy, tpenv = TcExprOfUnknownType cenv env tpenv yieldExpr + + if not isYield then errorR(Error(FSComp.SR.tcUseYieldBangForMultipleResults(), m)) + + AddCxTypeMustSubsumeType ContextInfo.NoContext env.DisplayEnv cenv.css m NoTrace genOuterTy genExprTy + Some(mkCoerceExpr(resultExpr, genOuterTy, m, genExprTy), tpenv) + + | SynExpr.YieldOrReturn((isYield, _), yieldExpr, m) -> + let genResultTy = NewInferenceType () + if not isYield then errorR(Error(FSComp.SR.tcSeqResultsUseYield(), m)) + UnifyTypes cenv env m genOuterTy (mkSeqTy cenv.g genResultTy) + + let resultExpr, tpenv = TcExprFlex cenv flex true genResultTy env tpenv yieldExpr + Some(mkCallSeqSingleton cenv.g m genResultTy resultExpr, tpenv ) + + | _ -> None - and tcSequenceExprBody env genOuterTy tpenv comp = - match tryTcSequenceExprBody env genOuterTy tpenv comp with - | Some e -> e - | None -> - // seq { ...; expr } is treated as 'seq { ... ; expr; yield! Seq.empty }' - // Note this means seq { ...; () } is treated as 'seq { ... ; (); yield! Seq.empty }' - let m = comp.Range - let env = { env with eContextInfo = ContextInfo.SequenceExpression genOuterTy } - let expr, tpenv = TcStmtThatCantBeCtorBody cenv env tpenv comp - Expr.Sequential(expr, mkSeqEmpty cenv env m genOuterTy, NormalSeq, SuppressSequencePointOnStmtOfSequential, m), tpenv + and tcSequenceExprBody env genOuterTy tpenv comp = + match tryTcSequenceExprBody env genOuterTy tpenv comp with + | Some e -> e + | None -> + // seq { ...; expr } is treated as 'seq { ... ; expr; yield! Seq.empty }' + // Note this means seq { ...; () } is treated as 'seq { ... ; (); yield! Seq.empty }' + let m = comp.Range + let env = { env with eContextInfo = ContextInfo.SequenceExpression genOuterTy } + let expr, tpenv = TcStmtThatCantBeCtorBody cenv env tpenv comp + Expr.Sequential(expr, mkSeqEmpty cenv env m genOuterTy, NormalSeq, SuppressSequencePointOnStmtOfSequential, m), tpenv - let coreExpr, tpenv = tcSequenceExprBody env overallTy tpenv comp - let delayedExpr = mkDelayedExpr coreExpr - delayedExpr, tpenv + let coreExpr, tpenv = tcSequenceExprBody env overallTy tpenv comp + let delayedExpr = mkDelayedExpr coreExpr + delayedExpr, tpenv /// When checking sequence of function applications, /// type applications and dot-notation projections, first extract known @@ -8381,7 +8511,7 @@ and Propagate cenv overallTy env tpenv (expr: ApplicableExpr) exprty delayed = | DelayedApp (_, arg, mExprAndArg) :: delayedList' -> let denv = env.DisplayEnv match UnifyFunctionTypeUndoIfFailed cenv denv mExpr exprty with - | Some (_, resultTy) -> + | ValueSome (_, resultTy) -> // We add tag parameter to the return type for "&x" and 'NativePtr.toByRef' // See RFC FS-1053.md @@ -8394,7 +8524,7 @@ and Propagate cenv overallTy env tpenv (expr: ApplicableExpr) exprty delayed = propagate isAddrOf delayedList' mExprAndArg resultTy - | None -> + | _ -> let mArg = arg.Range match arg with | SynExpr.CompExpr _ -> () @@ -8433,7 +8563,7 @@ and TcDelayed cenv overallTy env tpenv mExpr expr exprty (atomicFlag:ExprAtomicF match delayed with | [] | DelayedDot :: _ -> - UnifyTypesAndRecover cenv env mExpr overallTy exprty + UnifyTypes cenv env mExpr overallTy exprty expr.Expr, tpenv // expr.M(args) where x.M is a .NET method or index property // expr.M(args) where x.M is a .NET method or index property @@ -8482,7 +8612,7 @@ and TcFunctionApplicationThen cenv overallTy env tpenv mExprAndArg expr exprty ( // If the type of 'synArg' unifies as a function type, then this is a function application, otherwise // it is an error or a computation expression match UnifyFunctionTypeUndoIfFailed cenv denv mFunExpr exprty with - | Some (domainTy, resultTy) -> + | ValueSome (domainTy, resultTy) -> // Notice the special case 'seq { ... }'. In this case 'seq' is actually a function in the F# library. // Set a flag in the syntax tree to say we noticed a leading 'seq' @@ -8499,7 +8629,7 @@ and TcFunctionApplicationThen cenv overallTy env tpenv mExprAndArg expr exprty ( let arg, tpenv = TcExpr cenv domainTy env tpenv synArg let exprAndArg, resultTy = buildApp cenv expr resultTy arg mExprAndArg TcDelayed cenv overallTy env tpenv mExprAndArg exprAndArg resultTy atomicFlag delayed - | None -> + | _ -> // OK, 'expr' doesn't have function type, but perhaps 'expr' is a computation expression builder, and 'arg' is '{ ... }' match synArg with | SynExpr.CompExpr (false, _isNotNakedRefCell, comp, _m) -> @@ -8546,7 +8676,7 @@ and TcItemThen cenv overallTy env tpenv (item, mItem, rest, afterResolution) del | (Item.UnionCase _ | Item.ExnCase _ | Item.ActivePatternResult _) as item -> // ucaseAppTy is the type of the union constructor applied to its (optional) argument let ucaseAppTy = NewInferenceType () - let mkConstrApp, argtys, argNames = + let mkConstrApp, argTys, argNames = match item with | Item.ActivePatternResult(apinfo, _, n, _) -> let aparity = apinfo.Names.Length @@ -8561,16 +8691,16 @@ and TcItemThen cenv overallTy env tpenv (item, mItem, rest, afterResolution) del ApplyUnionCaseOrExnTypes mItem cenv env ucaseAppTy (Item.UnionCase(ucinfo, false)) | _ -> ApplyUnionCaseOrExnTypes mItem cenv env ucaseAppTy item - let nargtys = List.length argtys + let numArgTys = List.length argTys // Subsumption at data constructions if argument type is nominal prior to equations for any arguments or return types - let flexes = argtys |> List.map (isTyparTy cenv.g >> not) + let flexes = argTys |> List.map (isTyparTy cenv.g >> not) let (|FittedArgs|_|) arg = match arg with - | SynExprParen(SynExpr.Tuple(args, _, _), _, _, _) - | SynExpr.Tuple(args, _, _) when nargtys > 1 -> Some args + | SynExprParen(SynExpr.Tuple(false, args, _, _), _, _, _) + | SynExpr.Tuple(false, args, _, _) when numArgTys > 1 -> Some args | SynExprParen(arg, _, _, _) - | arg when nargtys = 1 -> Some [arg] + | arg when numArgTys = 1 -> Some [arg] | _ -> None match delayed with @@ -8580,8 +8710,8 @@ and TcItemThen cenv overallTy env tpenv (item, mItem, rest, afterResolution) del if isNil otherDelayed then UnifyTypes cenv env mExprAndArg overallTy ucaseAppTy - let nargs = List.length args - UnionCaseOrExnCheck env nargtys nargs mExprAndArg + let numArgs = List.length args + UnionCaseOrExnCheck env numArgTys numArgs mExprAndArg // if we manage to get here - number of formal arguments = number of actual arguments // apply named parameters @@ -8592,7 +8722,7 @@ and TcItemThen cenv overallTy env tpenv (item, mItem, rest, afterResolution) del | [] -> args | _ -> - let fittedArgs = Array.zeroCreate nargtys + let fittedArgs = Array.zeroCreate numArgTys // first: put all positional arguments let mutable currentIndex = 0 @@ -8615,7 +8745,7 @@ and TcItemThen cenv overallTy env tpenv (item, mItem, rest, afterResolution) del | Item.UnionCase(uci, _) -> Some(ArgumentContainer.UnionCase(uci)) | Item.ExnCase tref -> Some(ArgumentContainer.Type(tref)) | _ -> None - let argItem = Item.ArgName (argNames.[i], argtys.[i], argContainerOpt) + let argItem = Item.ArgName (argNames.[i], argTys.[i], argContainerOpt) CallNameResolutionSink cenv.tcSink (id.idRange, env.NameEnv, argItem, argItem, emptyTyparInst, ItemOccurence.Use, env.DisplayEnv, ad) else error(Error(FSComp.SR.tcUnionCaseFieldCannotBeUsedMoreThanOnce(id.idText), id.idRange)) currentIndex <- SEEN_NAMED_ARGUMENT @@ -8628,8 +8758,8 @@ and TcItemThen cenv overallTy env tpenv (item, mItem, rest, afterResolution) del // then we'll favor old behavior and treat current argument as positional. let isSpecialCaseForBackwardCompatibility = (currentIndex <> SEEN_NAMED_ARGUMENT) && - (currentIndex < nargtys) && - match stripTyEqns cenv.g argtys.[currentIndex] with + (currentIndex < numArgTys) && + match stripTyEqns cenv.g argTys.[currentIndex] with | TType_app(tcref, _) -> tyconRefEq cenv.g cenv.g.bool_tcr tcref || tyconRefEq cenv.g cenv.g.system_Bool_tcref tcref | TType_var(_) -> true | _ -> false @@ -8638,18 +8768,21 @@ and TcItemThen cenv overallTy env tpenv (item, mItem, rest, afterResolution) del assert (isNull(box fittedArgs.[currentIndex])) fittedArgs.[currentIndex] <- List.item currentIndex args // grab original argument, not item from the list of named parameters currentIndex <- currentIndex + 1 - else - let caseName = - match item with - | Item.UnionCase(uci, _) -> uci.Name - | Item.ExnCase tcref -> tcref.DisplayName - | _ -> failwith "impossible" - error(Error(FSComp.SR.tcUnionCaseConstructorDoesNotHaveFieldWithGivenName(caseName, id.idText), id.idRange)) + else + match item with + | Item.UnionCase(uci, _) -> + error(Error(FSComp.SR.tcUnionCaseConstructorDoesNotHaveFieldWithGivenName(uci.Name, id.idText), id.idRange)) + | Item.ExnCase tcref -> + error(Error(FSComp.SR.tcExceptionConstructorDoesNotHaveFieldWithGivenName(tcref.DisplayName, id.idText), id.idRange)) + | Item.ActivePatternResult(_,_,_,_) -> + error(Error(FSComp.SR.tcActivePatternsDoNotHaveFields(), id.idRange)) + | _ -> + error(Error(FSComp.SR.tcConstructorDoesNotHaveFieldWithGivenName(id.idText), id.idRange)) assert (Seq.forall (box >> ((<>) null) ) fittedArgs) List.ofArray fittedArgs - let args', tpenv = TcExprs cenv env mExprAndArg tpenv flexes argtys args + let args', tpenv = TcExprs cenv env mExprAndArg tpenv flexes argTys args PropagateThenTcDelayed cenv overallTy env tpenv mExprAndArg (MakeApplicableExprNoFlex cenv (mkConstrApp mExprAndArg args')) ucaseAppTy atomicFlag otherDelayed | DelayedTypeApp (_x, mTypeArgs, _mExprAndTypeArgs) :: _delayed' -> @@ -8660,25 +8793,25 @@ and TcItemThen cenv overallTy env tpenv (item, mItem, rest, afterResolution) del // (or else we would be building an invalid expression) // Unit-taking active pattern result can be applied to no args - let nargs, mkExpr = + let numArgs, mkExpr = // This is where the constructor is an active pattern result applied to no argument // Unit-taking active pattern result can be applied to no args - if (nargtys = 1 && match item with Item.ActivePatternResult _ -> true | _ -> false) then - UnifyTypes cenv env mItem (List.head argtys) cenv.g.unit_ty + if (numArgTys = 1 && match item with Item.ActivePatternResult _ -> true | _ -> false) then + UnifyTypes cenv env mItem (List.head argTys) cenv.g.unit_ty 1, (fun () -> mkConstrApp mItem [mkUnit cenv.g mItem]) // This is where the constructor expects no arguments and is applied to no argument - elif nargtys = 0 then + elif numArgTys = 0 then 0, (fun () -> mkConstrApp mItem []) else // This is where the constructor expects arguments but is not applied to arguments, hence build a lambda - nargtys, + numArgTys, (fun () -> - let vs, args = argtys |> List.mapi (fun i ty -> mkCompGenLocal mItem ("arg" + string i) ty) |> List.unzip + let vs, args = argTys |> List.mapi (fun i ty -> mkCompGenLocal mItem ("arg" + string i) ty) |> List.unzip let constrApp = mkConstrApp mItem args let lam = mkMultiLambda mItem vs (constrApp, tyOfExpr cenv.g constrApp) lam) - UnionCaseOrExnCheck env nargtys nargs mItem + UnionCaseOrExnCheck env numArgTys numArgs mItem let expr = mkExpr() let exprTy = tyOfExpr cenv.g expr PropagateThenTcDelayed cenv overallTy env tpenv mItem (MakeApplicableExprNoFlex cenv expr) exprTy ExprAtomicFlag.Atomic delayed @@ -8859,14 +8992,14 @@ and TcItemThen cenv overallTy env tpenv (item, mItem, rest, afterResolution) del | SynExpr.Const _ | SynExpr.LongIdent _ -> true - | SynExpr.Tuple(synExprs, _, _) - | SynExpr.StructTuple(synExprs, _, _) + | SynExpr.Tuple(_, synExprs, _, _) | SynExpr.ArrayOrList(_, synExprs, _) -> synExprs |> List.forall isSimpleArgument | SynExpr.Record(_, copyOpt, fields, _) -> copyOpt |> Option.forall (fst >> isSimpleArgument) && fields |> List.forall (p23 >> Option.forall isSimpleArgument) | SynExpr.App (_, _, synExpr, synExpr2, _) -> isSimpleArgument synExpr && isSimpleArgument synExpr2 | SynExpr.IfThenElse(synExpr, synExpr2, synExprOpt, _, _, _, _) -> isSimpleArgument synExpr && isSimpleArgument synExpr2 && Option.forall isSimpleArgument synExprOpt | SynExpr.DotIndexedGet(synExpr, _, _, _) -> isSimpleArgument synExpr | SynExpr.ObjExpr _ + | SynExpr.AnonRecd _ | SynExpr.While _ | SynExpr.For _ | SynExpr.ForEach _ @@ -9212,10 +9345,10 @@ and TcLookupThen cenv overallTy env tpenv mObjExpr objExpr objExprTy longId dela | Item.RecdField rfinfo -> // Get or set instance F# field or literal RecdFieldInstanceChecks cenv.g cenv.amap ad mItem rfinfo - let tgty = rfinfo.DeclaringType - let valu = isStructTy cenv.g tgty - AddCxTypeMustSubsumeType ContextInfo.NoContext env.DisplayEnv cenv.css mItem NoTrace tgty objExprTy - let objExpr = if valu then objExpr else mkCoerceExpr(objExpr, tgty, mExprAndItem, objExprTy) + let tgtTy = rfinfo.DeclaringType + let valu = isStructTy cenv.g tgtTy + AddCxTypeMustSubsumeType ContextInfo.NoContext env.DisplayEnv cenv.css mItem NoTrace tgtTy objExprTy + let objExpr = if valu then objExpr else mkCoerceExpr(objExpr, tgtTy, mExprAndItem, objExprTy) let fieldTy = rfinfo.FieldType match delayed with | DelayedSet(e2, mStmt) :: otherDelayed -> @@ -9233,6 +9366,18 @@ and TcLookupThen cenv overallTy env tpenv mObjExpr objExpr objExprTy longId dela let objExpr' = mkRecdFieldGet cenv.g (objExpr, rfinfo.RecdFieldRef, rfinfo.TypeInst, mExprAndItem) PropagateThenTcDelayed cenv overallTy env tpenv mExprAndItem (MakeApplicableExprWithFlex cenv env objExpr') fieldTy ExprAtomicFlag.Atomic delayed + | Item.AnonRecdField (anonInfo, tinst, n, _) -> + let tgty = TType_anon (anonInfo, tinst) + AddCxTypeMustSubsumeType ContextInfo.NoContext env.DisplayEnv cenv.css mItem NoTrace tgty objExprTy + let fieldTy = List.item n tinst + match delayed with + | DelayedSet _ :: _otherDelayed -> + error(Error(FSComp.SR.tcInvalidAssignment(),mItem)) + | _ -> + // Instance F# Anonymous Record + let objExpr' = mkAnonRecdFieldGet cenv.g (anonInfo,objExpr,tinst,n,mExprAndItem) + PropagateThenTcDelayed cenv overallTy env tpenv mExprAndItem (MakeApplicableExprWithFlex cenv env objExpr') fieldTy ExprAtomicFlag.Atomic delayed + | Item.ILField finfo -> // Get or set instance IL field ILFieldInstanceChecks cenv.g cenv.amap ad mItem finfo @@ -9793,10 +9938,11 @@ and TcMethodApplication let objArgPreBinder, objArgs = match objArgs, lambdaVars with | [objArg], Some _ -> + if finalCalledMethInfo.IsExtensionMember && finalCalledMethInfo.ObjArgNeedsAddress(cenv.amap, mMethExpr) then + error(Error(FSComp.SR.tcCannotPartiallyApplyExtensionMethodForByref(finalCalledMethInfo.DisplayName), mMethExpr)) let objArgTy = tyOfExpr cenv.g objArg let v, ve = mkCompGenLocal mMethExpr "objectArg" objArgTy (fun body -> mkCompGenLet mMethExpr v objArg body), [ve] - | _ -> emptyPreBinder, objArgs @@ -9914,7 +10060,7 @@ and TcMethodApplication | CallerLineNumber, _ when typeEquiv cenv.g currCalledArgTy cenv.g.int_ty -> emptyPreBinder, Expr.Const(Const.Int32(mMethExpr.StartLine), mMethExpr, currCalledArgTy) | CallerFilePath, _ when typeEquiv cenv.g currCalledArgTy cenv.g.string_ty -> - emptyPreBinder, Expr.Const(Const.String(System.IO.Path.GetFullPath(mMethExpr.FileName)), mMethExpr, currCalledArgTy) + emptyPreBinder, Expr.Const(Const.String(FileSystem.GetFullPathShim(mMethExpr.FileName)), mMethExpr, currCalledArgTy) | CallerMemberName, Some(callerName) when (typeEquiv cenv.g currCalledArgTy cenv.g.string_ty) -> emptyPreBinder, Expr.Const(Const.String(callerName), mMethExpr, currCalledArgTy) | _ -> @@ -9953,7 +10099,7 @@ and TcMethodApplication let lineExpr = Expr.Const(Const.Int32(mMethExpr.StartLine), mMethExpr, calledNonOptTy) emptyPreBinder, mkUnionCaseExpr(mkSomeCase cenv.g, [calledNonOptTy], [lineExpr], mMethExpr) | CallerFilePath, _ when typeEquiv cenv.g calledNonOptTy cenv.g.string_ty -> - let filePathExpr = Expr.Const(Const.String(System.IO.Path.GetFullPath(mMethExpr.FileName)), mMethExpr, calledNonOptTy) + let filePathExpr = Expr.Const(Const.String(FileSystem.GetFullPathShim(mMethExpr.FileName)), mMethExpr, calledNonOptTy) emptyPreBinder, mkUnionCaseExpr(mkSomeCase cenv.g, [calledNonOptTy], [filePathExpr], mMethExpr) | CallerMemberName, Some(callerName) when typeEquiv cenv.g calledNonOptTy cenv.g.string_ty -> let memberNameExpr = Expr.Const(Const.String(callerName), mMethExpr, calledNonOptTy) @@ -10004,7 +10150,7 @@ and TcMethodApplication finalUnnamedCalledOutArgs |> List.map (fun calledArg -> let calledArgTy = calledArg.CalledArgumentType let outArgTy = destByrefTy cenv.g calledArgTy - let outv, outArgExpr = mkMutableCompGenLocal mMethExpr "outArg" outArgTy // mutable! + let outv, outArgExpr = mkMutableCompGenLocal mMethExpr PrettyNaming.outArgCompilerGeneratedName outArgTy // mutable! let expr = mkDefault(mMethExpr, outArgTy) let callerArg = CallerArg(calledArgTy, mMethExpr, false, mkValAddr mMethExpr false (mkLocalValRef outv)) let outArg = { NamedArgIdOpt=None;CalledArg=calledArg;CallerArg=callerArg } @@ -10206,10 +10352,10 @@ and TcMethodArg cenv env (lambdaPropagationInfo, tpenv) (lambdaPropagationInfo if allRowsGiveSameArgumentType then // Force the caller to be a function type. match UnifyFunctionTypeUndoIfFailed cenv env.DisplayEnv mArg callerLambdaTy with - | Some (callerLambdaDomainTy, callerLambdaRangeTy) -> + | ValueSome (callerLambdaDomainTy, callerLambdaRangeTy) -> if AddCxTypeEqualsTypeUndoIfFailed env.DisplayEnv cenv.css mArg calledLambdaArgTy callerLambdaDomainTy then loop callerLambdaRangeTy (lambdaVarNum + 1) - | None -> () + | _ -> () loop argTy 0 let e', tpenv = TcExpr cenv argTy env tpenv argExpr @@ -10298,10 +10444,10 @@ and TcLinearExprs bodyChecker cenv env overallTy tpenv isCompExpr expr cont = cont (bodyChecker overallTy env tpenv expr) /// Typecheck and compile pattern-matching constructs -and TcAndPatternCompileMatchClauses mExpr matchm actionOnFailure cenv inputTy resultTy env tpenv clauses = - let tclauses, tpenv = TcMatchClauses cenv inputTy resultTy env tpenv clauses - let v, expr = CompilePatternForMatchClauses cenv env mExpr matchm true actionOnFailure inputTy resultTy tclauses - v, expr, tpenv +and TcAndPatternCompileMatchClauses mExpr matchm actionOnFailure cenv inputExprOpt inputTy resultTy env tpenv synClauses = + let clauses, tpenv = TcMatchClauses cenv inputTy resultTy env tpenv synClauses + let matchVal, expr = CompilePatternForMatchClauses cenv env mExpr matchm true actionOnFailure inputExprOpt inputTy resultTy clauses + matchVal, expr, tpenv and TcMatchPattern cenv inputTy env tpenv (pat:SynPat, optWhenExpr) = let m = pat.Range @@ -10682,11 +10828,10 @@ and TcAttribute canFail cenv (env: TcEnv) attrTgt (synAttr: SynAttribute) = let conditionalCallDefineOpt = TryFindTyconRefStringAttribute cenv.g mAttr cenv.g.attrib_ConditionalAttribute tcref - match conditionalCallDefineOpt with - | Some d when not (List.contains d cenv.conditionalDefines) -> + match conditionalCallDefineOpt, cenv.conditionalDefines with + | Some d, Some defines when not (List.contains d defines) -> [], false | _ -> - // REVIEW: take notice of inherited? let validOn, _inherited = let validOnDefault = 0x7fff @@ -10747,6 +10892,7 @@ and TcAttribute canFail cenv (env: TcEnv) attrTgt (synAttr: SynAttribute) = | Exception _ when canFail -> [ ], true | res -> let item = ForceRaise res + if not (ExistsHeadTypeInEntireHierarchy cenv.g cenv.amap mAttr ty cenv.g.tcref_System_Attribute) then warning(Error(FSComp.SR.tcTypeDoesNotInheritAttribute(), mAttr)) let attrib = match item with | Item.CtorGroup(methodName, minfos) -> @@ -10845,16 +10991,16 @@ and TcAttributes cenv env attrTgt synAttribs = // TcLetBinding //------------------------------------------------------------------------ -and TcLetBinding cenv isUse env containerInfo declKind tpenv (binds, bindsm, scopem) = +and TcLetBinding cenv isUse env containerInfo declKind tpenv (synBinds, synBindsRange, scopem) = // Typecheck all the bindings... - let binds', tpenv = List.mapFold (fun tpenv b -> TcNonRecursiveBinding declKind cenv env tpenv (NewInferenceType ()) b) tpenv binds + let checkedBinds, tpenv = List.mapFold (fun tpenv b -> TcNonRecursiveBinding declKind cenv env tpenv (NewInferenceType ()) b) tpenv synBinds let (ContainerInfo(altActualParent, _)) = containerInfo // Canonicalize constraints prior to generalization let denv = env.DisplayEnv - GeneralizationHelpers.CanonicalizePartialInferenceProblem (cenv, denv, bindsm) - (binds' |> List.collect (fun tbinfo -> + GeneralizationHelpers.CanonicalizePartialInferenceProblem (cenv, denv, synBindsRange) + (checkedBinds |> List.collect (fun tbinfo -> let (CheckedBindingInfo(_, _, _, _, flex, _, _, _, tauTy, _, _, _, _, _)) = tbinfo let (ExplicitTyparInfo(_, declaredTypars, _)) = flex let maxInferredTypars = (freeInTypeLeftToRight cenv.g false tauTy) @@ -10863,7 +11009,7 @@ and TcLetBinding cenv isUse env containerInfo declKind tpenv (binds, bindsm, sco let lazyFreeInEnv = lazy (GeneralizationHelpers.ComputeUngeneralizableTypars env) // Generalize the bindings... - (((fun x -> x), env, tpenv), binds') ||> List.fold (fun (mkf_sofar, env, tpenv) tbinfo -> + (((fun x -> x), env, tpenv), checkedBinds) ||> List.fold (fun (buildExpr, env, tpenv) tbinfo -> let (CheckedBindingInfo(inlineFlag, attrs, doc, tcPatPhase2, flex, nameToPrelimValSchemeMap, rhsExpr, _, tauTy, m, spBind, _, konst, isFixed)) = tbinfo let enclosingDeclaredTypars = [] let (ExplicitTyparInfo(_, declaredTypars, canInferTypars)) = flex @@ -10889,54 +11035,62 @@ and TcLetBinding cenv isUse env containerInfo declKind tpenv (binds, bindsm, sco let tpenv = HideUnscopedTypars generalizedTypars tpenv let valSchemes = NameMap.map (UseCombinedArity cenv.g declKind rhsExpr) prelimValSchemes2 let values = MakeAndPublishVals cenv env (altActualParent, false, declKind, ValNotInRecScope, valSchemes, attrs, doc, konst) - let pat' = tcPatPhase2 (TcPatPhase2Input (values, true)) + let checkedPat = tcPatPhase2 (TcPatPhase2Input (values, true)) let prelimRecValues = NameMap.map fst values // Now bind the r.h.s. to the l.h.s. let rhsExpr = mkTypeLambda m generalizedTypars (rhsExpr, tauTy) - match pat' with + match checkedPat with // Don't introduce temporary or 'let' for 'match against wild' or 'match against unit' | (TPat_wild _ | TPat_const (Const.Unit, _)) when not isUse && not isFixed && isNil generalizedTypars -> - let mk_seq_bind (tm, tmty) = (mkSequential SequencePointsAtSeq m rhsExpr tm, tmty) - (mk_seq_bind << mkf_sofar, env, tpenv) + let mkSequentialBind (tm, tmty) = (mkSequential SequencePointsAtSeq m rhsExpr tm, tmty) + (buildExpr >> mkSequentialBind , env, tpenv) | _ -> // nice: don't introduce awful temporary for r.h.s. in the 99% case where we know what we're binding it to - let tmp, pat'' = - match pat' with - // nice: don't introduce awful temporary for r.h.s. in the 99% case where we know what we're binding it to - | TPat_as (pat1, PBind(v, TypeScheme(generalizedTypars', _)), _) - when List.lengthsEqAndForall2 typarRefEq generalizedTypars generalizedTypars' -> + let patternInputTmp, checkedPat2 = + match checkedPat with + // nice: don't introduce awful temporary for r.h.s. in the 99% case where we know what we're binding it to + | TPat_as (pat, PBind(v, TypeScheme(generalizedTypars', _)), _) + when List.lengthsEqAndForall2 typarRefEq generalizedTypars generalizedTypars' -> - v, pat1 + v, pat + //Op (LValueOp (LByrefGet,x),[],[],C:\GitHub\dsyme\visualfsharp\a.fs (15,42--15,43) IsSynthetic=false) - | _ when inlineFlag.MustInline -> error(Error(FSComp.SR.tcInvalidInlineSpecification(), m)) + | _ when inlineFlag.MustInline -> + error(Error(FSComp.SR.tcInvalidInlineSpecification(), m)) - | _ -> - let tmp, _ = mkCompGenLocal m "patternInput" (generalizedTypars +-> tauTy) - if isUse || isFixed then - errorR(Error(FSComp.SR.tcInvalidUseBinding(), m)) + | _ -> + + let tmp, _ = mkCompGenLocal m "patternInput" (generalizedTypars +-> tauTy) + + if isUse || isFixed then + errorR(Error(FSComp.SR.tcInvalidUseBinding(), m)) - // This assignment forces representation as module value, to maintain the invariant from the - // type checker that anything related to binding module-level values is marked with an - // val_repr_info, val_declaring_entity and is_topbind - if (DeclKind.MustHaveArity declKind) then - AdjustValToTopVal tmp altActualParent (InferArityOfExprBinding cenv.g AllowTypeDirectedDetupling.Yes tmp rhsExpr) - tmp, pat' + // If the overall declaration is declaring statics or a module value, then force the patternInputTmp to also + // have representation as module value. + if (DeclKind.MustHaveArity declKind) then + AdjustValToTopVal tmp altActualParent (InferArityOfExprBinding cenv.g AllowTypeDirectedDetupling.Yes tmp rhsExpr) + + tmp, checkedPat + // Add the bind "let patternInputTmp = rhsExpr" to the bodyExpr we get from mkPatBind let mkRhsBind (bodyExpr, bodyExprTy) = - let letExpr = mkLet spBind m tmp rhsExpr bodyExpr + let letExpr = mkLet spBind m patternInputTmp rhsExpr bodyExpr letExpr, bodyExprTy let allValsDefinedByPattern = NameMap.range prelimRecValues + + // Add the compilation of the pattern to the bodyExpr we get from mkCleanup let mkPatBind (bodyExpr, bodyExprTy) = - let valsDefinedByMatching = ListSet.remove valEq tmp allValsDefinedByPattern - let matchx = CompilePatternForMatch cenv env m m true ThrowIncompleteMatchException (tmp, generalizedTypars) [TClause(pat'', None, TTarget(valsDefinedByMatching, bodyExpr, SuppressSequencePointAtTarget), m)] tauTy bodyExprTy + let valsDefinedByMatching = ListSet.remove valEq patternInputTmp allValsDefinedByPattern + let matchx = CompilePatternForMatch cenv env m m true ThrowIncompleteMatchException (patternInputTmp, generalizedTypars, Some rhsExpr) [TClause(checkedPat2, None, TTarget(valsDefinedByMatching, bodyExpr, SuppressSequencePointAtTarget), m)] tauTy bodyExprTy let matchx = if (DeclKind.ConvertToLinearBindings declKind) then LinearizeTopMatch cenv.g altActualParent matchx else matchx matchx, bodyExprTy + // Add the dispose of any "use x = ..." to bodyExpr let mkCleanup (bodyExpr, bodyExprTy) = if isUse && not isFixed then (allValsDefinedByPattern, (bodyExpr, bodyExprTy)) ||> List.foldBack (fun v (bodyExpr, bodyExprTy) -> @@ -10945,10 +11099,10 @@ and TcLetBinding cenv isUse env containerInfo declKind tpenv (binds, bindsm, sco mkTryFinally cenv.g (bodyExpr, cleanupE, m, bodyExprTy, SequencePointInBodyOfTry, NoSequencePointAtFinally), bodyExprTy) else (bodyExpr, bodyExprTy) - - ((mkf_sofar >> mkCleanup >> mkPatBind >> mkRhsBind), - AddLocalValMap cenv.tcSink scopem prelimRecValues env, - tpenv)) + + let envInner = AddLocalValMap cenv.tcSink scopem prelimRecValues env + + ((buildExpr >> mkCleanup >> mkPatBind >> mkRhsBind), envInner, tpenv)) /// Return binds corresponding to the linearised let-bindings. /// This reveals the bound items, e.g. when the lets occur in incremental object defns. @@ -11584,10 +11738,10 @@ and TcIncrementalLetRecGeneralization cenv scopem // pathological situations let freeInUncheckedRecBinds = lazy ((emptyFreeTyvars, cenv.recUses.Contents) ||> Map.fold (fun acc vStamp _ -> - match Map.tryFind vStamp uncheckedRecBindsTable with - | Some fwdBind -> - accFreeInType CollectAllNoCaching fwdBind.RecBindingInfo.Val.Type acc - | None -> + match uncheckedRecBindsTable.TryGetValue vStamp with + | true, fwdBind -> + accFreeInType CollectAllNoCaching fwdBind.RecBindingInfo.Val.Type acc + | _ -> acc)) let rec loop (preGeneralizationRecBinds: PreGeneralizationRecursiveBinding list, @@ -12145,13 +12299,13 @@ module TcRecdUnionAndEnumDeclarations = begin rfields, thisTy | UnionCaseFullType (ty, arity) -> let ty', _ = TcTypeAndRecover cenv NoNewTypars CheckCxs ItemOccurence.UseInType env tpenv ty - let argtysl, recordTy = GetTopTauTypeInFSharpForm cenv.g (arity |> TranslateTopValSynInfo m (TcAttributes cenv env) |> TranslatePartialArity []).ArgInfos ty' m - if argtysl.Length > 1 then + let curriedArgTys, recordTy = GetTopTauTypeInFSharpForm cenv.g (arity |> TranslateTopValSynInfo m (TcAttributes cenv env) |> TranslatePartialArity []).ArgInfos ty' m + if curriedArgTys.Length > 1 then errorR(Error(FSComp.SR.tcIllegalFormForExplicitTypeDeclaration(), m)) - let argtys = argtysl |> List.concat - let nFields = argtys.Length + let argTys = curriedArgTys |> List.concat + let nFields = argTys.Length let rfields = - argtys |> List.mapi (fun i (argty, argInfo) -> + argTys |> List.mapi (fun i (argty, argInfo) -> let id = (match argInfo.Name with Some id -> id | None -> mkSynId m (mkName nFields i)) MakeRecdFieldSpec cenv env parent (false, None, argty, [], [], id, argInfo.Name.IsNone, false, false, XmlDoc.Empty, None, m)) if not (typeEquiv cenv.g recordTy thisTy) then @@ -14049,7 +14203,7 @@ module AddAugmentationDeclarations = let tcaugHasNominalInterface g (tcaug: TyconAugmentation) tcref = tcaug.tcaug_interfaces |> List.exists (fun (x, _, _) -> match tryDestAppTy g x with - | Some tcref2 when tyconRefEq g tcref2 tcref -> true + | ValueSome tcref2 when tyconRefEq g tcref2 tcref -> true | _ -> false) let AddGenericCompareDeclarations cenv (env: TcEnv) (scSet:Set) (tycon:Tycon) = @@ -14197,7 +14351,7 @@ module TyconConstraintInference = // Is the field type a type parameter? match tryDestTyparTy cenv.g ty with - | Some tp -> + | ValueSome tp -> // Look for an explicit 'comparison' constraint if tp.Constraints |> List.exists (function TyparConstraint.SupportsComparison _ -> true | _ -> false) then true @@ -14210,7 +14364,7 @@ module TyconConstraintInference = else false - | None -> + | _ -> match ty with // Look for array, UIntPtr and IntPtr types | SpecialComparableHeadType g tinst -> @@ -14322,7 +14476,7 @@ module TyconConstraintInference = // and type parameters. let rec checkIfFieldTypeSupportsEquality (tycon:Tycon) (ty: TType) = match tryDestTyparTy cenv.g ty with - | Some tp -> + | ValueSome tp -> // Look for an explicit 'equality' constraint if tp.Constraints |> List.exists (function TyparConstraint.SupportsEquality _ -> true | _ -> false) then true @@ -14334,7 +14488,7 @@ module TyconConstraintInference = true else false - | None -> + | _ -> match ty with | SpecialEquatableHeadType g tinst -> tinst |> List.forall (checkIfFieldTypeSupportsEquality tycon) @@ -14639,11 +14793,11 @@ module EstablishTypeDefinitionCores = yield (ty', m) | UnionCaseFullType (ty, arity) -> let ty', _ = TcTypeAndRecover cenv NoNewTypars NoCheckCxs ItemOccurence.UseInType env tpenv ty - let argtysl, _ = GetTopTauTypeInFSharpForm cenv.g (arity |> TranslateTopValSynInfo m (TcAttributes cenv env) |> TranslatePartialArity []).ArgInfos ty' m - if argtysl.Length > 1 then + let curriedArgTys, _ = GetTopTauTypeInFSharpForm cenv.g (arity |> TranslateTopValSynInfo m (TcAttributes cenv env) |> TranslatePartialArity []).ArgInfos ty' m + if curriedArgTys.Length > 1 then errorR(Error(FSComp.SR.tcIllegalFormForExplicitTypeDeclaration(), m)) - for argtys in argtysl do - for (argty, _) in argtys do + for argTys in curriedArgTys do + for (argty, _) in argTys do yield (argty , m) | SynTypeDefnSimpleRepr.General (_, _, _, fields, _, _, implicitCtorSynPats, _) when tycon.IsFSharpStructOrEnumTycon -> // for structs @@ -14679,11 +14833,11 @@ module EstablishTypeDefinitionCores = let AdjustModuleName modKind nm = (match modKind with FSharpModuleWithSuffix -> nm+FSharpModuleSuffix | _ -> nm) - let TypeNamesInMutRecDecls (compDecls: MutRecShapes) = + let TypeNamesInMutRecDecls cenv env (compDecls: MutRecShapes) = [ for d in compDecls do match d with - | MutRecShape.Tycon (MutRecDefnsPhase1DataForTycon(ComponentInfo(_, _, _, ids, _, _, _, _), _, _, _, _, isAtOriginalTyconDefn), _) -> - if isAtOriginalTyconDefn then + | MutRecShape.Tycon (MutRecDefnsPhase1DataForTycon(ComponentInfo(_, typars, _, ids, _, _, _, _), _, _, _, _, isAtOriginalTyconDefn), _) -> + if isAtOriginalTyconDefn && (TcTyparDecls cenv env typars |> List.forall (fun p -> p.Kind = TyparKind.Measure)) then yield (List.last ids).idText | _ -> () ] |> set @@ -14730,7 +14884,7 @@ module EstablishTypeDefinitionCores = let envForDecls, mtypeAcc = MakeInnerEnv envInitial id modKind let mspec = NewModuleOrNamespace (Some envInitial.eCompPath) vis id (xml.ToXmlDoc()) modAttrs (MaybeLazy.Strict (NewEmptyModuleOrNamespaceType modKind)) let innerParent = Parent (mkLocalModRef mspec) - let innerTypeNames = TypeNamesInMutRecDecls decls + let innerTypeNames = TypeNamesInMutRecDecls cenv envForDecls decls MutRecDefnsPhase2DataForModule (mtypeAcc, mspec), (innerParent, innerTypeNames, envForDecls) /// Establish 'type C < T1... TN > = ...' including @@ -15611,6 +15765,7 @@ module EstablishTypeDefinitionCores = let rec accInAbbrevType ty acc = match stripTyparEqns ty with + | TType_anon (_,l) | TType_tuple (_, l) -> accInAbbrevTypes l acc | TType_ucase (UCRef(tc, _), tinst) | TType_app (tc, tinst) -> @@ -15709,9 +15864,9 @@ module EstablishTypeDefinitionCores = else acc // note: all edges added are (tycon, _) let insertEdgeToType ty acc = match tryDestAppTy cenv.g ty with - | Some tcref -> + | ValueSome tcref -> insertEdgeToTycon tcref.Deref acc - | None -> + | _ -> acc // collect edges from an a struct field (which is struct-contained in tycon) @@ -15733,9 +15888,9 @@ module EstablishTypeDefinitionCores = (structTycon === tycon2) && (structTyInst, tinst2) ||> List.lengthsEqAndForall2 (fun ty1 ty2 -> match tryDestTyparTy cenv.g ty1 with - | Some destTypar1 -> + | ValueSome destTypar1 -> match tryDestTyparTy cenv.g ty2 with - | Some destTypar2 -> typarEq destTypar1 destTypar2 + | ValueSome destTypar2 -> typarEq destTypar1 destTypar2 | _ -> false | _ -> false) if specialCaseStaticField then @@ -15760,7 +15915,7 @@ module EstablishTypeDefinitionCores = let fspecs = if structTycon.IsUnionTycon then [ for uc in structTycon.UnionCasesArray do - for c in uc.FieldTable.AllFieldsAsList do + for c in uc.FieldTable.FieldsByIndex do yield c] else structTycon.AllFieldsAsList @@ -16010,12 +16165,12 @@ module TcDeclarations = else let isInSameModuleOrNamespace = - match envForDecls.eModuleOrNamespaceTypeAccumulator.Value.TypesByMangledName.TryFind(tcref.LogicalName) with - | Some tycon -> (tyconOrder.Compare(tcref.Deref, tycon) = 0) - | None -> + match envForDecls.eModuleOrNamespaceTypeAccumulator.Value.TypesByMangledName.TryGetValue tcref.LogicalName with + | true, tycon -> tyconOrder.Compare(tcref.Deref, tycon) = 0 + | _ -> //false // There is a special case we allow when compiling FSharp.Core.dll which permits interface implementations across namespace fragments - (cenv.g.compilingFslib && tcref.LogicalName.StartsWithOrdinal("Tuple`")) + cenv.g.compilingFslib && tcref.LogicalName.StartsWithOrdinal("Tuple`") let nReqTypars = reqTypars.Length @@ -16304,9 +16459,14 @@ module TcDeclarations = let tyDeclRange = synTyconInfo.Range let (ComponentInfo(_, typars, cs, longPath, _, _, _, _)) = synTyconInfo let declKind, tcref, declaredTyconTypars = ComputeTyconDeclKind tyconOpt isAtOriginalTyconDefn cenv envForDecls false tyDeclRange typars cs longPath - let newslotsOK = (if isAtOriginalTyconDefn && tcref.IsFSharpObjectModelTycon then NewSlotsOK else NoNewSlots) + let newslotsOK = (if isAtOriginalTyconDefn && tcref.IsFSharpObjectModelTycon then NewSlotsOK else NoNewSlots) + + if (declKind = ExtrinsicExtensionBinding) && isByrefTyconRef cenv.g tcref then + error(Error(FSComp.SR.tcByrefsMayNotHaveTypeExtensions(), tyDeclRange)) + if not (isNil members) && tcref.IsTypeAbbrev then errorR(Error(FSComp.SR.tcTypeAbbreviationsCannotHaveAugmentations(), tyDeclRange)) + MutRecDefnsPhase2DataForTycon(tyconOpt, innerParent, declKind, tcref, baseValOpt, safeInitInfo, declaredTyconTypars, members, tyDeclRange, newslotsOK, fixupFinalAttrs)) // By now we've established the full contents of type definitions apart from their @@ -16552,7 +16712,7 @@ let rec TcSignatureElementNonMutRec cenv parent typeNames endm (env: TcEnv) synS return env - | SynModuleSigDecl.NamespaceFragment (SynModuleOrNamespaceSig(longId, isRec, isModule, defs, xml, attribs, vis, m)) -> + | SynModuleSigDecl.NamespaceFragment (SynModuleOrNamespaceSig(longId, isRec, kind, defs, xml, attribs, vis, m)) -> do for id in longId do CheckNamespaceModuleOrTypeName cenv.g id @@ -16564,7 +16724,7 @@ let rec TcSignatureElementNonMutRec cenv parent typeNames endm (env: TcEnv) synS // namespace [rec] A.B // module M = ... let enclosingNamespacePath, defs = - if isModule then + if kind.IsModule then let nsp, modName = List.frontAndBack longId let modDecl = [SynModuleSigDecl.NestedModule(ComponentInfo(attribs, [], [], [modName], xml, false, vis, m), false, defs, m)] nsp, modDecl @@ -16861,7 +17021,7 @@ let rec TcModuleOrNamespaceElementNonMutRec (cenv:cenv) parent typeNames scopem return ((fun modDefs -> modDefn :: modDefs), topAttrsNew), env, envAtEnd - | SynModuleDecl.NamespaceFragment(SynModuleOrNamespace(longId, isRec, isModule, defs, xml, attribs, vis, m)) -> + | SynModuleDecl.NamespaceFragment(SynModuleOrNamespace(longId, isRec, kind, defs, xml, attribs, vis, m)) -> if !progress then dprintn ("Typecheck implementation " + textOfLid longId) let endm = m.EndRange @@ -16876,7 +17036,7 @@ let rec TcModuleOrNamespaceElementNonMutRec (cenv:cenv) parent typeNames scopem // namespace [rec] A.B // module M = ... let enclosingNamespacePath, defs = - if isModule then + if kind.IsModule then let nsp, modName = List.frontAndBack longId let modDecl = [SynModuleDecl.NestedModule(ComponentInfo(attribs, [], [], [modName], xml, false, vis, m), false, defs, true, m)] nsp, modDecl @@ -17227,7 +17387,7 @@ let CheckModuleSignature g cenv m denvAtEnd rootSigOpt implFileTypePriorToSig im // Compute the remapping from implementation to signature let remapInfo , _ = ComputeRemappingFromInferredSignatureToExplicitSignature cenv.g implFileTypePriorToSig sigFileType - let aenv = { TypeEquivEnv.Empty with EquivTycons = TyconRefMap.OfList remapInfo.mrpiEntities } + let aenv = { TypeEquivEnv.Empty with EquivTycons = TyconRefMap.OfList remapInfo.RepackagedEntities } if not (SignatureConformance.Checker(cenv.g, cenv.amap, denv, remapInfo, true).CheckSignature aenv (mkLocalModRef implFileSpecPriorToSig) sigFileType) then ( // We can just raise 'ReportedError' since CheckModuleOrNamespace raises its own error @@ -17309,14 +17469,14 @@ let TypeCheckOneImplFile // We ALWAYS run the PostTypeCheckSemanticChecks phase, though we if we have already encountered some // errors we turn off error reporting. This is because it performs various fixups over the TAST, e.g. // assigning nice names for inference variables. - let hasExplicitEntryPoint = + let hasExplicitEntryPoint, anonRecdTypes = conditionallySuppressErrorReporting (checkForErrors()) (fun () -> try let reportErrors = not (checkForErrors()) PostTypeCheckSemanticChecks.CheckTopImpl (g, cenv.amap, reportErrors, cenv.infoReader, env.eInternalsVisibleCompPaths, cenv.topCcu, envAtEnd.DisplayEnv, implFileExprAfterSig, extraAttribs, isLastCompiland, isInternalTestSpanStackReferring) with e -> errorRecovery e m - false) + false, StampMap.Empty) // Warn on version attributes. topAttrs.assemblyAttrs |> List.iter (function @@ -17332,7 +17492,7 @@ let TypeCheckOneImplFile | _ -> () | _ -> ()) - let implFile = TImplFile(qualNameOfFile, scopedPragmas, implFileExprAfterSig, hasExplicitEntryPoint, isScript) + let implFile = TImplFile(qualNameOfFile, scopedPragmas, implFileExprAfterSig, hasExplicitEntryPoint, isScript, anonRecdTypes) return (topAttrs, implFile, implFileTypePriorToSig, envAtEnd, cenv.createsGeneratedProvidedTypes) } diff --git a/src/fsharp/TypeChecker.fsi b/src/fsharp/TypeChecker.fsi index 3f84e1992f..aae0954499 100644 --- a/src/fsharp/TypeChecker.fsi +++ b/src/fsharp/TypeChecker.fsi @@ -39,14 +39,14 @@ val EmptyTopAttrs : TopAttribs val CombineTopAttrs : TopAttribs -> TopAttribs -> TopAttribs val TypeCheckOneImplFile : - TcGlobals * NiceNameGenerator * ImportMap * CcuThunk * (unit -> bool) * ConditionalDefines * NameResolution.TcResultsSink * bool + TcGlobals * NiceNameGenerator * ImportMap * CcuThunk * (unit -> bool) * ConditionalDefines option * NameResolution.TcResultsSink * bool -> TcEnv -> Tast.ModuleOrNamespaceType option -> ParsedImplFileInput -> Eventually val TypeCheckOneSigFile : - TcGlobals * NiceNameGenerator * ImportMap * CcuThunk * (unit -> bool) * ConditionalDefines * NameResolution.TcResultsSink * bool + TcGlobals * NiceNameGenerator * ImportMap * CcuThunk * (unit -> bool) * ConditionalDefines option * NameResolution.TcResultsSink * bool -> TcEnv -> ParsedSigFileInput -> Eventually diff --git a/src/fsharp/ast.fs b/src/fsharp/ast.fs index 1f0941eea4..22b960d18c 100644 --- a/src/fsharp/ast.fs +++ b/src/fsharp/ast.fs @@ -162,22 +162,26 @@ type LongIdentWithDots = /// more freedom about typechecking these expressions. /// LongIdent can be empty list - it is used to denote that name of some AST element is absent (i.e. empty type name in inherit) | LongIdentWithDots of id:LongIdent * dotms:range list - with member this.Range = - match this with - | LongIdentWithDots([],_) -> failwith "rangeOfLidwd" - | LongIdentWithDots([id],[]) -> id.idRange - | LongIdentWithDots([id],[m]) -> unionRanges id.idRange m - | LongIdentWithDots(h::t,[]) -> unionRanges h.idRange (List.last t).idRange - | LongIdentWithDots(h::t,dotms) -> unionRanges h.idRange (List.last t).idRange |> unionRanges (List.last dotms) - member this.Lid = match this with LongIdentWithDots(lid,_) -> lid - member this.ThereIsAnExtraDotAtTheEnd = match this with LongIdentWithDots(lid,dots) -> lid.Length = dots.Length - member this.RangeSansAnyExtraDot = - match this with - | LongIdentWithDots([],_) -> failwith "rangeOfLidwd" - | LongIdentWithDots([id],_) -> id.idRange - | LongIdentWithDots(h::t,dotms) -> - let nonExtraDots = if dotms.Length = t.Length then dotms else List.truncate t.Length dotms - unionRanges h.idRange (List.last t).idRange |> unionRanges (List.last nonExtraDots) + + member this.Range = + match this with + | LongIdentWithDots([],_) -> failwith "rangeOfLidwd" + | LongIdentWithDots([id],[]) -> id.idRange + | LongIdentWithDots([id],[m]) -> unionRanges id.idRange m + | LongIdentWithDots(h::t,[]) -> unionRanges h.idRange (List.last t).idRange + | LongIdentWithDots(h::t,dotms) -> unionRanges h.idRange (List.last t).idRange |> unionRanges (List.last dotms) + + member this.Lid = match this with LongIdentWithDots(lid,_) -> lid + + member this.ThereIsAnExtraDotAtTheEnd = match this with LongIdentWithDots(lid,dots) -> lid.Length = dots.Length + + member this.RangeSansAnyExtraDot = + match this with + | LongIdentWithDots([],_) -> failwith "rangeOfLidwd" + | LongIdentWithDots([id],_) -> id.idRange + | LongIdentWithDots(h::t,dotms) -> + let nonExtraDots = if dotms.Length = t.Length then dotms else List.truncate t.Length dotms + unionRanges h.idRange (List.last t).idRange |> unionRanges (List.last nonExtraDots) //------------------------------------------------------------------------ // AST: the grammar of implicitly scoped type parameters @@ -428,44 +432,56 @@ and | LongIdentApp of typeName:SynType * longDotId:LongIdentWithDots * LESSRange:range option * typeArgs:SynType list * commaRanges:range list * GREATERrange:range option * range:range /// F# syntax : type * ... * type - // the bool is true if / rather than * follows the type - | Tuple of typeNames:(bool*SynType) list * range:range - /// F# syntax : struct (type * ... * type) // the bool is true if / rather than * follows the type - | StructTuple of typeNames:(bool*SynType) list * range:range + | Tuple of isStruct:bool * typeNames:(bool*SynType) list * range:range + + /// F# syntax : {| id: type; ...; id: type |} + /// F# syntax : struct {| id: type; ...; id: type |} + | AnonRecd of isStruct:bool * typeNames:(Ident * SynType) list * range:range /// F# syntax : type[] | Array of int * elementType:SynType * range:range + /// F# syntax : type -> type | Fun of argType:SynType * returnType:SynType * range:range + /// F# syntax : 'Var | Var of genericName:SynTypar * range:range + /// F# syntax : _ | Anon of range:range + /// F# syntax : typ with constraints | WithGlobalConstraints of typeName:SynType * constraints:SynTypeConstraint list * range:range + /// F# syntax : #type | HashConstraint of SynType * range:range + /// F# syntax : for units of measure e.g. m / s | MeasureDivide of dividendType:SynType * divisorType:SynType * range:range + /// F# syntax : for units of measure e.g. m^3, kg^1/2 | MeasurePower of measureType:SynType * SynRationalConst * range:range + /// F# syntax : 1, "abc" etc, used in parameters to type providers /// For the dimensionless units i.e. 1 , and static parameters to provided types | StaticConstant of constant:SynConst * range:range + /// F# syntax : const expr, used in static parameters to type providers | StaticConstantExpr of expr:SynExpr * range:range + /// F# syntax : ident=1 etc., used in static parameters to type providers | StaticConstantNamed of expr:SynType * SynType * range:range + /// Get the syntactic range of source code covered by this construct. member x.Range = match x with | SynType.App (range=m) | SynType.LongIdentApp (range=m) | SynType.Tuple (range=m) - | SynType.StructTuple (range=m) | SynType.Array (range=m) + | SynType.AnonRecd (range=m) | SynType.Fun (range=m) | SynType.Var (range=m) | SynType.Anon (range=m) @@ -504,10 +520,11 @@ and | Typed of expr:SynExpr * typeName:SynType * range:range /// F# syntax: e1, ..., eN - | Tuple of exprs:SynExpr list * commaRanges:range list * range:range // "range list" is for interstitial commas, these only matter for parsing/design-time tooling, the typechecker may munge/discard them + | Tuple of isStruct: bool * exprs:SynExpr list * commaRanges:range list * range:range // "range list" is for interstitial commas, these only matter for parsing/design-time tooling, the typechecker may munge/discard them - /// F# syntax: struct (e1, ..., eN) - | StructTuple of exprs:SynExpr list * commaRanges:range list * range:range // "range list" is for interstitial commas, these only matter for parsing/design-time tooling, the typechecker may munge/discard them + /// F# syntax: {| id1=e1; ...; idN=eN |} + /// F# syntax: struct {| id1=e1; ...; idN=eN |} + | AnonRecd of isStruct: bool * copyInfo:(SynExpr * BlockSeparator) option * recordFields:(Ident * SynExpr) list * range:range /// F# syntax: [ e1; ...; en ], [| e1; ...; en |] | ArrayOrList of isList:bool * exprs:SynExpr list * range:range @@ -557,7 +574,7 @@ and | MatchLambda of isExnMatch:bool * range * SynMatchClause list * matchSeqPoint:SequencePointInfoForBinding * range:range /// F# syntax: match expr with pat1 -> expr | ... | patN -> exprN - | Match of matchSeqPoint:SequencePointInfoForBinding * expr:SynExpr * clauses:SynMatchClause list * isExnMatch:bool * range:range (* bool indicates if this is an exception match in a computation expression which throws unmatched exceptions *) + | Match of matchSeqPoint:SequencePointInfoForBinding * expr:SynExpr * clauses:SynMatchClause list * range:range (* bool indicates if this is an exception match in a computation expression which throws unmatched exceptions *) /// F# syntax: do expr | Do of expr:SynExpr * range:range @@ -696,7 +713,7 @@ and | LetOrUseBang of bindSeqPoint:SequencePointInfoForBinding * isUse:bool * isFromSource:bool * SynPat * SynExpr * SynExpr * range:range /// F# syntax: match! expr with pat1 -> expr | ... | patN -> exprN - | MatchBang of matchSeqPoint:SequencePointInfoForBinding * expr:SynExpr * clauses:SynMatchClause list * isExnMatch:bool * range:range (* bool indicates if this is an exception match in a computation expression which throws unmatched exceptions *) + | MatchBang of matchSeqPoint:SequencePointInfoForBinding * expr:SynExpr * clauses:SynMatchClause list * range:range (* bool indicates if this is an exception match in a computation expression which throws unmatched exceptions *) /// F# syntax: do! expr /// Computation expressions only @@ -734,7 +751,7 @@ and | SynExpr.Const (range=m) | SynExpr.Typed (range=m) | SynExpr.Tuple (range=m) - | SynExpr.StructTuple (range=m) + | SynExpr.AnonRecd (range=m) | SynExpr.ArrayOrList (range=m) | SynExpr.Record (range=m) | SynExpr.New (range=m) @@ -799,8 +816,8 @@ and | SynExpr.Const (range=m) | SynExpr.Typed (range=m) | SynExpr.Tuple (range=m) - | SynExpr.StructTuple (range=m) | SynExpr.ArrayOrList (range=m) + | SynExpr.AnonRecd (range=m) | SynExpr.Record (range=m) | SynExpr.New (range=m) | SynExpr.ObjExpr (range=m) @@ -855,6 +872,7 @@ and | SynExpr.DiscardAfterMissingQualificationAfterDot (expr,_) -> expr.Range | SynExpr.Fixed (_,m) -> m | SynExpr.Ident id -> id.idRange + /// Attempt to get the range of the first token or initial portion only - this is extremely ad-hoc, just a cheap way to improve a certain 'query custom operation' error range member e.RangeOfFirstPortion = match e with @@ -863,8 +881,8 @@ and | SynExpr.Const (range=m) | SynExpr.Typed (range=m) | SynExpr.Tuple (range=m) - | SynExpr.StructTuple (range=m) | SynExpr.ArrayOrList (range=m) + | SynExpr.AnonRecd (range=m) | SynExpr.Record (range=m) | SynExpr.New (range=m) | SynExpr.ObjExpr (range=m) @@ -993,8 +1011,7 @@ and | Or of SynPat * SynPat * range:range | Ands of SynPat list * range:range | LongIdent of longDotId:LongIdentWithDots * (* holds additional ident for tooling *) Ident option * SynValTyparDecls option (* usually None: temporary used to parse "f<'a> x = x"*) * SynConstructorArgs * accessibility:SynAccess option * range:range - | Tuple of SynPat list * range:range - | StructTuple of SynPat list * range:range + | Tuple of isStruct: bool * SynPat list * range:range | Paren of SynPat * range:range | ArrayOrList of bool * SynPat list * range:range | Record of ((LongIdent * Ident) * SynPat) list * range:range @@ -1025,7 +1042,6 @@ and | SynPat.LongIdent (range=m) | SynPat.ArrayOrList (range=m) | SynPat.Tuple (range=m) - | SynPat.StructTuple (range=m) | SynPat.Typed (range=m) | SynPat.Attrib (range=m) | SynPat.Record (range=m) @@ -1393,7 +1409,7 @@ and SynModuleDecl = | ModuleAbbrev of ident:Ident * longId:LongIdent * range:range | NestedModule of SynComponentInfo * isRecursive:bool * SynModuleDecls * bool * range:range - | Let of bool * SynBinding list * range:range + | Let of isRecursive:bool * SynBinding list * range:range | DoExpr of SequencePointInfoForBinding * SynExpr * range:range | Types of SynTypeDefn list * range:range | Exception of SynExceptionDefn * range:range @@ -1446,11 +1462,23 @@ and and SynModuleSigDecls = SynModuleSigDecl list -/// SynModuleOrNamespace(lid,isRec,isModule,decls,xmlDoc,attribs,SynAccess,m) +and + [] + SynModuleOrNamespaceKind = + | NamedModule + | AnonModule + | DeclaredNamespace + | GlobalNamespace + + member x.IsModule = + match x with + | NamedModule | AnonModule -> true + | _ -> false + and [] SynModuleOrNamespace = - | SynModuleOrNamespace of longId:LongIdent * isRecursive:bool * isModule:bool * decls:SynModuleDecls * xmlDoc:PreXmlDoc * attribs:SynAttributes * accessibility:SynAccess option * range:range + | SynModuleOrNamespace of longId:LongIdent * isRecursive:bool * kind:SynModuleOrNamespaceKind * decls:SynModuleDecls * xmlDoc:PreXmlDoc * attribs:SynAttributes * accessibility:SynAccess option * range:range member this.Range = match this with | SynModuleOrNamespace (range=m) -> m @@ -1458,7 +1486,7 @@ and and [] SynModuleOrNamespaceSig = - | SynModuleOrNamespaceSig of longId:LongIdent * isRecursive:bool * isModule:bool * SynModuleSigDecls * xmlDoc:PreXmlDoc * attribs:SynAttributes * accessibility:SynAccess option * range:range + | SynModuleOrNamespaceSig of longId:LongIdent * isRecursive:bool * kind:SynModuleOrNamespaceKind * SynModuleSigDecls * xmlDoc:PreXmlDoc * attribs:SynAttributes * accessibility:SynAccess option * range:range and [] ParsedHashDirective = @@ -1468,13 +1496,13 @@ and [] type ParsedImplFileFragment = | AnonModule of SynModuleDecls * range:range | NamedModule of SynModuleOrNamespace - | NamespaceFragment of longId:LongIdent * bool * bool * SynModuleDecls * xmlDoc:PreXmlDoc * SynAttributes * range:range + | NamespaceFragment of longId:LongIdent * bool * SynModuleOrNamespaceKind * SynModuleDecls * xmlDoc:PreXmlDoc * SynAttributes * range:range [] type ParsedSigFileFragment = | AnonModule of SynModuleSigDecls * range:range | NamedModule of SynModuleOrNamespaceSig - | NamespaceFragment of longId:LongIdent * bool * bool * SynModuleSigDecls * xmlDoc:PreXmlDoc * SynAttributes * range:range + | NamespaceFragment of longId:LongIdent * bool * SynModuleOrNamespaceKind * SynModuleSigDecls * xmlDoc:PreXmlDoc * SynAttributes * range:range [] type ParsedFsiInteraction = @@ -1702,7 +1730,7 @@ let rec SimplePatOfPat (synArgNameGenerator: SynArgNameGenerator) p = SynSimplePat.Id (id,altNameRefCell,isCompGen,false,false,id.idRange), Some (fun e -> let clause = Clause(p,None,e,m,SuppressSequencePointAtTarget) - SynExpr.Match(NoSequencePointAtInvisibleBinding,item,[clause],false,clause.Range)) + SynExpr.Match(NoSequencePointAtInvisibleBinding,item,[clause],clause.Range)) let appFunOpt funOpt x = match funOpt with None -> x | Some f -> f x let composeFunOpt funOpt1 funOpt2 = match funOpt2 with None -> funOpt1 | Some f -> Some (fun x -> appFunOpt funOpt1 (f x)) @@ -1714,8 +1742,8 @@ let rec SimplePatsOfPat synArgNameGenerator p = SynSimplePats.Typed(p2,ty,m), laterf // | SynPat.Paren (p,m) -> SimplePatsOfPat synArgNameGenerator p - | SynPat.Tuple (ps,m) - | SynPat.Paren(SynPat.Tuple (ps,m),_) -> + | SynPat.Tuple (false,ps,m) + | SynPat.Paren(SynPat.Tuple (false,ps,m),_) -> let ps2,laterf = List.foldBack (fun (p',rhsf) (ps',rhsf') -> @@ -1847,14 +1875,14 @@ let mkSynDotBrackSeqSliceGet m mDot arr (argslist:list) = | SynIndexerArg.One x -> yield x | _ -> () ] if notsliced.Length = argslist.Length then - SynExpr.DotIndexedGet(arr,[SynIndexerArg.One (SynExpr.Tuple(notsliced,[],unionRanges (List.head notsliced).Range (List.last notsliced).Range))],mDot,m) + SynExpr.DotIndexedGet(arr,[SynIndexerArg.One (SynExpr.Tuple(false,notsliced,[],unionRanges (List.head notsliced).Range (List.last notsliced).Range))],mDot,m) else SynExpr.DotIndexedGet(arr,argslist,mDot,m) let mkSynDotParenGet lhsm dotm a b = match b with - | SynExpr.Tuple ([_;_],_,_) -> errorR(Deprecated(FSComp.SR.astDeprecatedIndexerNotation(),lhsm)) ; SynExpr.Const(SynConst.Unit,lhsm) - | SynExpr.Tuple ([_;_;_],_,_) -> errorR(Deprecated(FSComp.SR.astDeprecatedIndexerNotation(),lhsm)) ; SynExpr.Const(SynConst.Unit,lhsm) + | SynExpr.Tuple (false,[_;_],_,_) -> errorR(Deprecated(FSComp.SR.astDeprecatedIndexerNotation(),lhsm)) ; SynExpr.Const(SynConst.Unit,lhsm) + | SynExpr.Tuple (false,[_;_;_],_,_) -> errorR(Deprecated(FSComp.SR.astDeprecatedIndexerNotation(),lhsm)) ; SynExpr.Const(SynConst.Unit,lhsm) | _ -> mkSynInfix dotm a parenGet b let mkSynUnit m = SynExpr.Const(SynConst.Unit,m) @@ -2382,11 +2410,15 @@ let rec synExprContainsError inpExpr = walkExpr e1 || walkExpr e2 | SynExpr.ArrayOrList (_,es,_) - | SynExpr.Tuple (es,_,_) - | SynExpr.StructTuple (es,_,_) -> + | SynExpr.Tuple (_,es,_,_) -> walkExprs es - | SynExpr.Record (_,_,fs,_) -> + | SynExpr.AnonRecd (_,origExpr,flds,_) -> + (match origExpr with Some (e,_) -> walkExpr e | None -> false) || + walkExprs (List.map snd flds) + + | SynExpr.Record (_,origExpr,fs,_) -> + (match origExpr with Some (e,_) -> walkExpr e | None -> false) || let flds = fs |> List.choose (fun (_, v, _) -> v) walkExprs (flds) @@ -2401,7 +2433,7 @@ let rec synExprContainsError inpExpr = walkMatchClauses cl | SynExpr.Lambda (_,_,_,e,_) -> walkExpr e - | SynExpr.Match (_,e,cl,_,_) -> + | SynExpr.Match (_,e,cl,_) -> walkExpr e || walkMatchClauses cl | SynExpr.LetOrUse (_,_,bs,e,_) -> walkBinds bs || walkExpr e @@ -2423,7 +2455,7 @@ let rec synExprContainsError inpExpr = | SynExpr.DotNamedIndexedPropertySet (e1,_,e2,e3,_) -> walkExpr e1 || walkExpr e2 || walkExpr e3 - | SynExpr.MatchBang (_,e,cl,_,_) -> + | SynExpr.MatchBang (_,e,cl,_) -> walkExpr e || walkMatchClauses cl | SynExpr.LetOrUseBang (_,_,_,_,e1,e2,_) -> walkExpr e1 || walkExpr e2 diff --git a/src/fsharp/fsc.fs b/src/fsharp/fsc.fs index e418b1bb9b..f3117e16e8 100755 --- a/src/fsharp/fsc.fs +++ b/src/fsharp/fsc.fs @@ -296,7 +296,7 @@ module InterfaceFileWriter = fprintfn os "#light" fprintfn os "" - for (TImplFile(_, _, mexpr, _, _)) in declaredImpls do + for (TImplFile(_, _, mexpr, _, _, _)) in declaredImpls do let denv = BuildInitialDisplayEnvForSigFileGeneration tcGlobals writeViaBufferWithEnvironmentNewLines os (fun os s -> Printf.bprintf os "%s\n\n" s) (NicePrint.layoutInferredSigOfModuleExpr true denv infoReader AccessibleFromSomewhere range0 mexpr |> Layout.squashTo 80 |> Layout.showL) @@ -329,9 +329,9 @@ module XmlDocWriter = if (hasDoc tc.XmlDoc) then tc.XmlDocSig <- XmlDocSigOfTycon [ptext; tc.CompiledName] for vref in tc.MembersOfFSharpTyconSorted do doValSig ptext vref.Deref - for uc in tc.UnionCasesAsList do + for uc in tc.UnionCasesArray do if (hasDoc uc.XmlDoc) then uc.XmlDocSig <- XmlDocSigOfUnionCase [ptext; tc.CompiledName; uc.Id.idText] - for rf in tc.AllFieldsAsList do + for rf in tc.AllFieldsArray do if (hasDoc rf.XmlDoc) then rf.XmlDocSig <- if tc.IsRecordTycon && (not rf.IsStatic) then @@ -380,9 +380,9 @@ module XmlDocWriter = addMember tc.XmlDocSig tc.XmlDoc for vref in tc.MembersOfFSharpTyconSorted do doVal vref.Deref - for uc in tc.UnionCasesAsList do + for uc in tc.UnionCasesArray do doUnionCase uc - for rf in tc.AllFieldsAsList do + for rf in tc.AllFieldsArray do doField rf let modulMember (m:ModuleOrNamespace) = addMember m.XmlDocSig m.XmlDoc @@ -1773,11 +1773,9 @@ let main0(ctok, argv, legacyReferenceResolver, bannerAlreadyPrinted, reduceMemor errorRecoveryNoRange e exiter.Exit 1 - let inputs = - // Deduplicate module names - let moduleNamesDict = ConcurrentDictionary>() - inputs - |> List.map (fun (input,x) -> DeduplicateParsedInputModuleName moduleNamesDict input,x) + let inputs, _ = + (Map.empty, inputs) + ||> List.mapFold (fun state (input,x) -> let inputT, stateT = DeduplicateParsedInputModuleName state input in (inputT,x), stateT) if tcConfig.parseOnly then exiter.Exit 0 if not tcConfig.continueAfterParseFailure then @@ -1831,7 +1829,7 @@ let main1(Args (ctok, tcGlobals, tcImports: TcImports, frameworkTcImports, gener // it as the updated global error logger and never remove it let oldLogger = errorLogger let errorLogger = - let scopedPragmas = [ for (TImplFile(_, pragmas, _, _, _)) in typedImplFiles do yield! pragmas ] + let scopedPragmas = [ for (TImplFile(_, pragmas, _, _, _, _)) in typedImplFiles do yield! pragmas ] GetErrorLoggerFilteringByScopedPragmas(true, scopedPragmas, oldLogger) let _unwindEL_3 = PushErrorLoggerPhaseUntilUnwind(fun _ -> errorLogger) @@ -1999,13 +1997,10 @@ let main2b (tcImportsCapture,dynamicAssemblyCreator) (Args (ctok, tcConfig: TcCo let ilxGenerator = CreateIlxAssemblyGenerator (tcConfig, tcImports, tcGlobals, (LightweightTcValForUsingInBuildMethodCall tcGlobals), generatedCcu) let codegenResults = GenerateIlxCode ((if Option.isSome dynamicAssemblyCreator then IlReflectBackend else IlWriteBackend), Option.isSome dynamicAssemblyCreator, false, tcConfig, topAttrs, optimizedImpls, generatedCcu.AssemblyName, ilxGenerator) - let casApplied = new Dictionary() - let securityAttrs, topAssemblyAttrs = topAttrs.assemblyAttrs |> List.partition (fun a -> IsSecurityAttribute tcGlobals (tcImports.GetImportMap()) casApplied a rangeStartup) - - // remove any security attributes from the top-level assembly attribute list + let topAssemblyAttrs = codegenResults.topAssemblyAttrs let topAttrs = {topAttrs with assemblyAttrs=topAssemblyAttrs} - let permissionSets = ilxGenerator.CreatePermissionSets securityAttrs - let secDecls = if List.isEmpty securityAttrs then emptyILSecurityDecls else mkILSecurityDecls permissionSets + let permissionSets = codegenResults.permissionSets + let secDecls = mkILSecurityDecls permissionSets let ilxMainModule = MainModuleBuilder.CreateMainModule (ctok, tcConfig, tcGlobals, tcImports, pdbfile, assemblyName, outfile, topAttrs, idata, optDataResources, codegenResults, assemVerFromAttrib, metadataVersion, secDecls) @@ -2039,7 +2034,7 @@ let main4 dynamicAssemblyCreator (Args (ctok, tcConfig, tcImports: TcImports, t DoesNotRequireCompilerThreadTokenAndCouldPossiblyBeMadeConcurrent ctok - let pdbfile = pdbfile |> Option.map (tcConfig.MakePathAbsolute >> Path.GetFullPath) + let pdbfile = pdbfile |> Option.map (tcConfig.MakePathAbsolute >> FileSystem.GetFullPathShim) let normalizeAssemblyRefs (aref:ILAssemblyRef) = match tcImports.TryFindDllInfo (ctok, Range.rangeStartup, aref.Name, lookupOnly=false) with @@ -2114,3 +2109,4 @@ let mainCompile (ctok, argv, legacyReferenceResolver, bannerAlreadyPrinted, redu //System.Runtime.GCSettings.LatencyMode <- System.Runtime.GCLatencyMode.Batch typecheckAndCompile(ctok, argv, legacyReferenceResolver, bannerAlreadyPrinted, reduceMemoryUsage, defaultCopyFSharpCore, exiter, errorLoggerProvider, tcImportsCapture, dynamicAssemblyCreator) + diff --git a/src/fsharp/fsc/fsc.fsproj b/src/fsharp/fsc/fsc.fsproj new file mode 100644 index 0000000000..40f56a0627 --- /dev/null +++ b/src/fsharp/fsc/fsc.fsproj @@ -0,0 +1,43 @@ + + + + + + Exe + net46;netcoreapp2.1 + .exe + fsc + $(NoWarn);45;55;62;75;1204 + true + $(OtherFlags) --maxerrors:20 --extraoptimizationloops:1 + true + true + true + + + + + fscmain.fs + + + + default.win32manifest + PreserveNewest + + + + + + + + + + + + + + + + + + diff --git a/src/fsharp/fsi/fsi.fs b/src/fsharp/fsi/fsi.fs index eb926991dc..8190be4078 100644 --- a/src/fsharp/fsi/fsi.fs +++ b/src/fsharp/fsi/fsi.fs @@ -1060,7 +1060,7 @@ type internal FsiDynamicCompiler #if DEBUG if fsiOptions.ShowILCode then fsiConsoleOutput.uprintnfn "--------------------"; - ILAsciiWriter.output_module outWriter mainmod3; + ILAsciiWriter.output_module outWriter ilGlobals mainmod3; fsiConsoleOutput.uprintnfn "--------------------" #else ignore(fsiOptions) @@ -1116,7 +1116,7 @@ type internal FsiDynamicCompiler // 'Open' the path for the fragment we just compiled for any future printing. let denv = denv.AddOpenPath (pathOfLid prefixPath) - for (TImplFile(_qname,_,mexpr,_,_)) in declaredImpls do + for (TImplFile(_qname,_,mexpr,_,_,_)) in declaredImpls do let responseL = NicePrint.layoutInferredSigOfModuleExpr false denv infoReader AccessibleFromSomewhere rangeStdin mexpr if not (Layout.isEmptyL responseL) then let opts = valuePrinter.GetFsiPrintOptions() @@ -1154,7 +1154,7 @@ type internal FsiDynamicCompiler let i = nextFragmentId() let prefix = mkFragmentPath i let prefixPath = pathOfLid prefix - let impl = SynModuleOrNamespace(prefix,(*isRec*)false, (* isModule: *) true,defs,PreXmlDoc.Empty,[],None,rangeStdin) + let impl = SynModuleOrNamespace(prefix,(*isRec*)false, NamedModule,defs,PreXmlDoc.Empty,[],None,rangeStdin) let input = ParsedInput.ImplFile(ParsedImplFileInput(filename,true, ComputeQualifiedNameOfFileFromUniquePath (rangeStdin,prefixPath),[],[],[impl],(true (* isLastCompiland *), false (* isExe *)) )) let istate,tcEnvAtEndOfLastInput,declaredImpls = ProcessInputs (ctok, errorLogger, istate, [input], showTypes, true, isInteractiveItExpr, prefix) let tcState = istate.tcState diff --git a/src/fsharp/fsi/fsi.fsproj b/src/fsharp/fsi/fsi.fsproj new file mode 100644 index 0000000000..5dbcac7557 --- /dev/null +++ b/src/fsharp/fsi/fsi.fsproj @@ -0,0 +1,60 @@ + + + + + + Exe + net46;netcoreapp2.1 + .exe + fsi + $(NoWarn);45;55;62;75;1204 + true + $(OtherFlags) --warnon:1182 --maxerrors:20 --extraoptimizationloops:1 + fsi.res + true + true + true + + + + $(DefineConstants);FSI_SHADOW_COPY_REFERENCES;FSI_SERVER + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/fsharp/fsi/xlf/FSIstrings.txt.cs.xlf b/src/fsharp/fsi/xlf/FSIstrings.txt.cs.xlf index d4667e04c0..9841900326 100644 --- a/src/fsharp/fsi/xlf/FSIstrings.txt.cs.xlf +++ b/src/fsharp/fsi/xlf/FSIstrings.txt.cs.xlf @@ -1,4 +1,4 @@ - + diff --git a/src/fsharp/fsi/xlf/FSIstrings.txt.de.xlf b/src/fsharp/fsi/xlf/FSIstrings.txt.de.xlf index f87d3361f2..93303b279f 100644 --- a/src/fsharp/fsi/xlf/FSIstrings.txt.de.xlf +++ b/src/fsharp/fsi/xlf/FSIstrings.txt.de.xlf @@ -1,4 +1,4 @@ - + diff --git a/src/fsharp/fsi/xlf/FSIstrings.txt.es.xlf b/src/fsharp/fsi/xlf/FSIstrings.txt.es.xlf index 6af67db255..6b25550fed 100644 --- a/src/fsharp/fsi/xlf/FSIstrings.txt.es.xlf +++ b/src/fsharp/fsi/xlf/FSIstrings.txt.es.xlf @@ -1,4 +1,4 @@ - + diff --git a/src/fsharp/fsi/xlf/FSIstrings.txt.fr.xlf b/src/fsharp/fsi/xlf/FSIstrings.txt.fr.xlf index 917a17f435..b69c71103d 100644 --- a/src/fsharp/fsi/xlf/FSIstrings.txt.fr.xlf +++ b/src/fsharp/fsi/xlf/FSIstrings.txt.fr.xlf @@ -1,4 +1,4 @@ - + @@ -134,7 +134,7 @@ \n\nException raised during pretty printing.\nPlease report this so it can be fixed.\nTrace: {0}\n - \n\nException déclenchée durant l'impression en mode Pretty.\nSignalez ce problème afin qu'il soit corrigé.\nTrace : {0}\n + \n\nException déclenchée durant l'impression automatique.\nSignalez ce problème afin qu'il soit corrigé.\nTrace : {0}\n @@ -184,7 +184,7 @@ Loading - Chargement en cours + Chargement diff --git a/src/fsharp/fsi/xlf/FSIstrings.txt.it.xlf b/src/fsharp/fsi/xlf/FSIstrings.txt.it.xlf index d7f05d6aa9..51a94aabb2 100644 --- a/src/fsharp/fsi/xlf/FSIstrings.txt.it.xlf +++ b/src/fsharp/fsi/xlf/FSIstrings.txt.it.xlf @@ -1,4 +1,4 @@ - + diff --git a/src/fsharp/fsi/xlf/FSIstrings.txt.ko.xlf b/src/fsharp/fsi/xlf/FSIstrings.txt.ko.xlf index 69a5d3b535..5d0b2017d6 100644 --- a/src/fsharp/fsi/xlf/FSIstrings.txt.ko.xlf +++ b/src/fsharp/fsi/xlf/FSIstrings.txt.ko.xlf @@ -1,4 +1,4 @@ - + diff --git a/src/fsharp/fsi/xlf/FSIstrings.txt.pl.xlf b/src/fsharp/fsi/xlf/FSIstrings.txt.pl.xlf index 82960cad8f..f6b3de9b34 100644 --- a/src/fsharp/fsi/xlf/FSIstrings.txt.pl.xlf +++ b/src/fsharp/fsi/xlf/FSIstrings.txt.pl.xlf @@ -1,4 +1,4 @@ - + diff --git a/src/fsharp/fsi/xlf/FSIstrings.txt.pt-BR.xlf b/src/fsharp/fsi/xlf/FSIstrings.txt.pt-BR.xlf index d35388b4cb..70a3636f04 100644 --- a/src/fsharp/fsi/xlf/FSIstrings.txt.pt-BR.xlf +++ b/src/fsharp/fsi/xlf/FSIstrings.txt.pt-BR.xlf @@ -1,4 +1,4 @@ - + diff --git a/src/fsharp/fsi/xlf/FSIstrings.txt.ru.xlf b/src/fsharp/fsi/xlf/FSIstrings.txt.ru.xlf index 6e40ee07dd..de3a08eed1 100644 --- a/src/fsharp/fsi/xlf/FSIstrings.txt.ru.xlf +++ b/src/fsharp/fsi/xlf/FSIstrings.txt.ru.xlf @@ -1,4 +1,4 @@ - + diff --git a/src/fsharp/fsi/xlf/FSIstrings.txt.tr.xlf b/src/fsharp/fsi/xlf/FSIstrings.txt.tr.xlf index 6497500a1f..35bd3478f9 100644 --- a/src/fsharp/fsi/xlf/FSIstrings.txt.tr.xlf +++ b/src/fsharp/fsi/xlf/FSIstrings.txt.tr.xlf @@ -1,4 +1,4 @@ - + diff --git a/src/fsharp/fsiAnyCpu/fsiAnyCpu.fsproj b/src/fsharp/fsiAnyCpu/fsiAnyCpu.fsproj new file mode 100644 index 0000000000..200bd6d40a --- /dev/null +++ b/src/fsharp/fsiAnyCpu/fsiAnyCpu.fsproj @@ -0,0 +1,44 @@ + + + + + + Exe + net46 + AnyCPU + .exe + fsiAnyCpu + $(NoWarn);45;55;62;75;1204 + true + $(OtherFlags) --warnon:1182 --maxerrors:20 --extraoptimizationloops:1 + ..\fsi\fsi.res + true + true + + + + $(DefineConstants);FSI_SHADOW_COPY_REFERENCES;FSI_SERVER + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/fsharp/import.fs b/src/fsharp/import.fs index 098720fb0a..e06ee756da 100755 --- a/src/fsharp/import.fs +++ b/src/fsharp/import.fs @@ -62,13 +62,13 @@ let CanImportILScopeRef (env:ImportMap) m scoref = match scoref with | ILScopeRef.Local -> true | ILScopeRef.Module _ -> true - | ILScopeRef.Assembly assref -> + | ILScopeRef.Assembly assemblyRef -> // Explanation: This represents an unchecked invariant in the hosted compiler: that any operations // which import types (and resolve assemblies from the tcImports tables) happen on the compilation thread. let ctok = AssumeCompilationThreadWithoutEvidence() - match env.assemblyLoader.FindCcuFromAssemblyRef (ctok, m, assref) with + match env.assemblyLoader.FindCcuFromAssemblyRef (ctok, m, assemblyRef) with | UnresolvedCcu _ -> false | ResolvedCcu _ -> true @@ -84,7 +84,7 @@ let ImportTypeRefData (env:ImportMap) m (scoref,path,typeName) = match scoref with | ILScopeRef.Local -> error(InternalError("ImportILTypeRef: unexpected local scope",m)) | ILScopeRef.Module _ -> error(InternalError("ImportILTypeRef: reference found to a type in an auxiliary module",m)) - | ILScopeRef.Assembly assref -> env.assemblyLoader.FindCcuFromAssemblyRef (ctok, m, assref) // NOTE: only assemblyLoader callsite + | ILScopeRef.Assembly assemblyRef -> env.assemblyLoader.FindCcuFromAssemblyRef (ctok, m, assemblyRef) // NOTE: only assemblyLoader callsite // Do a dereference of a fake tcref for the type just to check it exists in the target assembly and to find // the corresponding Tycon. @@ -109,8 +109,8 @@ let ImportTypeRefData (env:ImportMap) m (scoref,path,typeName) = () #endif match tryRescopeEntity ccu tycon with - | None -> error (Error(FSComp.SR.impImportedAssemblyUsesNotPublicType(String.concat "." (Array.toList path@[typeName])),m)) - | Some tcref -> tcref + | ValueNone -> error (Error(FSComp.SR.impImportedAssemblyUsesNotPublicType(String.concat "." (Array.toList path@[typeName])),m)) + | ValueSome tcref -> tcref /// Import a reference to a type definition, given an AbstractIL ILTypeRef, without caching @@ -168,7 +168,6 @@ let rec ImportILType (env:ImportMap) m tinst ty = let inst = tspec.GenericArgs |> List.map (ImportILType env m tinst) ImportTyconRefApp env tcref inst - | ILType.Modified(_,tref,ILType.Byref ty) when tref.Name = "System.Runtime.InteropServices.InAttribute" -> mkInByrefTy env.g (ImportILType env m tinst ty) | ILType.Byref ty -> mkByrefTy env.g (ImportILType env m tinst ty) | ILType.Ptr ILType.Void when env.g.voidptr_tcr.CanDeref -> mkVoidPtrTy env.g | ILType.Ptr ty -> mkNativePtrTy env.g (ImportILType env m tinst ty) diff --git a/src/fsharp/infos.fs b/src/fsharp/infos.fs index 7e23785723..6ee5a6b53c 100755 --- a/src/fsharp/infos.fs +++ b/src/fsharp/infos.fs @@ -67,15 +67,14 @@ let GetSuperTypeOfType g amap m ty = | Some super -> Some(Import.ImportProvidedType amap m super) #endif | ILTypeMetadata (TILObjectReprData(scoref,_,tdef)) -> - let _,tinst = destAppTy g ty + let tinst = argsOfAppTy g ty match tdef.Extends with | None -> None | Some ilty -> Some (ImportILType scoref amap m tinst ilty) | FSharpOrArrayOrByrefOrTupleOrExnTypeMetadata -> - - if isFSharpObjModelTy g ty || isExnDeclTy g ty then - let tcref,_tinst = destAppTy g ty + if isFSharpObjModelTy g ty || isExnDeclTy g ty then + let tcref = tcrefOfAppTy g ty Some (instType (mkInstForAppTy g ty) (superOfTycon g tcref.Deref)) elif isArrayTy g ty then Some g.system_Array_ty @@ -88,6 +87,8 @@ let GetSuperTypeOfType g amap m ty = Some(g.system_Enum_ty) else Some (g.system_Value_ty) + elif isAnonRecdTy g ty then + Some g.obj_ty elif isRecdTy g ty || isUnionTy g ty then Some g.obj_ty else @@ -105,8 +106,8 @@ type SkipUnrefInterfaces = Yes | No /// traverse the type hierarchy to collect further interfaces. let rec GetImmediateInterfacesOfType skipUnref g amap m ty = let itys = - if isAppTy g ty then - let tcref,tinst = destAppTy g ty + match tryAppTy g ty with + | ValueSome(tcref,tinst) -> if tcref.IsMeasureableReprTycon then [ match tcref.TypeReprInfo with | TMeasureableRepr reprTy -> @@ -142,8 +143,7 @@ let rec GetImmediateInterfacesOfType skipUnref g amap m ty = | FSharpOrArrayOrByrefOrTupleOrExnTypeMetadata -> tcref.ImmediateInterfaceTypesOfFSharpTycon |> List.map (instType (mkInstForAppTy g ty)) - else - [] + | _ -> [] // .NET array types are considered to implement IList let itys = @@ -187,7 +187,7 @@ let private FoldHierarchyOfTypeAux followInterfaces allowMultiIntfInst skipUnref (loop ndeep g.obj_ty state) else match tryDestTyparTy g ty with - | Some tp -> + | ValueSome tp -> let state = loop (ndeep+1) g.obj_ty state List.foldBack (fun x vacc -> @@ -208,7 +208,7 @@ let private FoldHierarchyOfTypeAux followInterfaces allowMultiIntfInst skipUnref loop (ndeep + 1) cty vacc) tp.Constraints state - | None -> + | _ -> let state = if followInterfaces then List.foldBack @@ -284,13 +284,26 @@ let ExistsHeadTypeInEntireHierarchy g amap m typeToSearchFrom tcrefToLookFor = let ImportILTypeFromMetadata amap m scoref tinst minst ilty = ImportILType scoref amap m (tinst@minst) ilty - -/// Get the return type of an IL method, taking into account instantiations for type and method generic parameters, and +/// Read an Abstract IL type from metadata, including any attributes that may affect the type itself, and convert to an F# type. +let ImportILTypeFromMetadataWithAttributes amap m scoref tinst minst ilty cattrs = + let ty = ImportILType scoref amap m (tinst@minst) ilty + // If the type is a byref and one of attributes from a return or parameter has IsReadOnly, then it's a inref. + if isByrefTy amap.g ty && TryFindILAttribute amap.g.attrib_IsReadOnlyAttribute cattrs then + mkInByrefTy amap.g (destByrefTy amap.g ty) + else + ty + +/// Get the parameter type of an IL method. +let ImportParameterTypeFromMetadata amap m ilty cattrs scoref tinst mist = + ImportILTypeFromMetadataWithAttributes amap m scoref tinst mist ilty cattrs + +/// Get the return type of an IL method, taking into account instantiations for type, return attributes and method generic parameters, and /// translating 'void' to 'None'. -let ImportReturnTypeFromMetaData amap m ty scoref tinst minst = - match ty with +let ImportReturnTypeFromMetadata amap m ilty cattrs scoref tinst minst = + match ilty with | ILType.Void -> None - | retTy -> Some (ImportILTypeFromMetadata amap m scoref tinst minst retTy) + | retTy -> Some(ImportILTypeFromMetadataWithAttributes amap m scoref tinst minst retTy cattrs) + /// Copy constraints. If the constraint comes from a type parameter associated /// with a type constructor then we are simply renaming type variables. If it comes @@ -806,19 +819,19 @@ type ILMethInfo = /// Get the argument types of the the IL method. If this is an C#-style extension method /// then drop the object argument. member x.GetParamTypes(amap,m,minst) = - x.ParamMetadata |> List.map (fun p -> ImportILTypeFromMetadata amap m x.MetadataScope x.DeclaringTypeInst minst p.Type) + x.ParamMetadata |> List.map (fun p -> ImportParameterTypeFromMetadata amap m p.Type p.CustomAttrs x.MetadataScope x.DeclaringTypeInst minst) /// Get all the argument types of the IL method. Include the object argument even if this is /// an C#-style extension method. member x.GetRawArgTypes(amap,m,minst) = - x.RawMetadata.Parameters |> List.map (fun p -> ImportILTypeFromMetadata amap m x.MetadataScope x.DeclaringTypeInst minst p.Type) + x.RawMetadata.Parameters |> List.map (fun p -> ImportParameterTypeFromMetadata amap m p.Type p.CustomAttrs x.MetadataScope x.DeclaringTypeInst minst) /// Get info about the arguments of the IL method. If this is an C#-style extension method then /// drop the object argument. /// /// Any type parameters of the enclosing type are instantiated in the type returned. member x.GetParamNamesAndTypes(amap,m,minst) = - x.ParamMetadata |> List.map (fun p -> ParamNameAndType(Option.map (mkSynId m) p.Name, ImportILTypeFromMetadata amap m x.MetadataScope x.DeclaringTypeInst minst p.Type) ) + x.ParamMetadata |> List.map (fun p -> ParamNameAndType(Option.map (mkSynId m) p.Name, ImportParameterTypeFromMetadata amap m p.Type p.CustomAttrs x.MetadataScope x.DeclaringTypeInst minst) ) /// Get a reference to the method (dropping all generic instantiations), as an Abstract IL ILMethodRef. member x.ILMethodRef = @@ -838,7 +851,8 @@ type ILMethInfo = // All C#-style extension methods are instance. We have to re-read the 'obj' type w.r.t. the // method instantiation. if x.IsILExtensionMethod then - [ImportILTypeFromMetadata amap m x.MetadataScope x.DeclaringTypeInst minst x.RawMetadata.Parameters.Head.Type] + let p = x.RawMetadata.Parameters.Head + [ ImportParameterTypeFromMetadata amap m p.Type p.CustomAttrs x.MetadataScope x.DeclaringTypeInst minst ] else if x.IsInstance then [ x.ApparentEnclosingType ] else @@ -846,7 +860,7 @@ type ILMethInfo = /// Get the compiled return type of the method, where 'void' is None. member x.GetCompiledReturnTy (amap, m, minst) = - ImportReturnTypeFromMetaData amap m x.RawMetadata.Return.Type x.MetadataScope x.DeclaringTypeInst minst + ImportReturnTypeFromMetadata amap m x.RawMetadata.Return.Type x.RawMetadata.Return.CustomAttrs x.MetadataScope x.DeclaringTypeInst minst /// Get the F# view of the return type of the method, where 'void' is 'unit'. member x.GetFSharpReturnTy (amap, m, minst) = @@ -1436,7 +1450,7 @@ type MethInfo = // if multiple caller info attributes are specified, pick the "wrong" one here // so that we get an error later match tryDestOptionTy g ty with - | Some optTy when typeEquiv g g.int32_ty optTy -> CallerFilePath + | ValueSome optTy when typeEquiv g g.int32_ty optTy -> CallerFilePath | _ -> CallerLineNumber (isParamArrayArg, isInArg, isOutArg, optArgInfo, callerInfo, reflArgInfo)) @@ -1503,7 +1517,7 @@ type MethInfo = match x with | ILMeth(_,ilminfo,_) -> let ftinfo = ILTypeInfo.FromType g (TType_app(tcref,formalEnclosingTyparTys)) - let formalRetTy = ImportReturnTypeFromMetaData amap m ilminfo.RawMetadata.Return.Type ftinfo.ILScopeRef ftinfo.TypeInstOfRawMetadata formalMethTyparTys + let formalRetTy = ImportReturnTypeFromMetadata amap m ilminfo.RawMetadata.Return.Type ilminfo.RawMetadata.Return.CustomAttrs ftinfo.ILScopeRef ftinfo.TypeInstOfRawMetadata formalMethTyparTys let formalParams = [ [ for p in ilminfo.RawMetadata.Parameters do let paramType = ImportILTypeFromMetadata amap m ftinfo.ILScopeRef ftinfo.TypeInstOfRawMetadata formalMethTyparTys p.Type @@ -1581,6 +1595,14 @@ type MethInfo = | _ -> x.DeclaringTyconRef.Typars(m) + /// Tries to get the object arg type if it's a byref type. + member x.TryObjArgByrefType(amap, m, minst) = + x.GetObjArgTypes(amap, m, minst) + |> List.tryHead + |> Option.bind (fun ty -> + if isByrefTy x.TcGlobals ty then Some(ty) + else None) + //------------------------------------------------------------------------- // ILFieldInfo @@ -2456,6 +2478,10 @@ type EventInfo = //------------------------------------------------------------------------- // Helpers associated with getting and comparing method signatures +/// Strips inref and outref to be a byref. +let stripByrefTy g ty = + if isByrefTy g ty then mkByrefTy g (destByrefTy g ty) + else ty /// Represents the information about the compiled form of a method signature. Used when analyzing implementation /// relations between members and abstract slots. @@ -2479,7 +2505,8 @@ let CompiledSigOfMeth g amap m (minfo:MethInfo) = CompiledSig(vargtys,vrty,formalMethTypars,fmtpinst) -/// Used to hide/filter members from super classes based on signature +/// Used to hide/filter members from super classes based on signature +/// Inref and outref parameter types will be treated as a byref type for equivalency. let MethInfosEquivByNameAndPartialSig erasureFlag ignoreFinal g amap m (minfo:MethInfo) (minfo2:MethInfo) = (minfo.LogicalName = minfo2.LogicalName) && (minfo.GenericArity = minfo2.GenericArity) && @@ -2490,7 +2517,8 @@ let MethInfosEquivByNameAndPartialSig erasureFlag ignoreFinal g amap m (minfo:Me let fminst2 = generalizeTypars formalMethTypars2 let argtys = minfo.GetParamTypes(amap, m, fminst) let argtys2 = minfo2.GetParamTypes(amap, m, fminst2) - (argtys,argtys2) ||> List.lengthsEqAndForall2 (List.lengthsEqAndForall2 (typeAEquivAux erasureFlag g (TypeEquivEnv.FromEquivTypars formalMethTypars formalMethTypars2))) + (argtys,argtys2) ||> List.lengthsEqAndForall2 (List.lengthsEqAndForall2 (fun ty1 ty2 -> + typeAEquivAux erasureFlag g (TypeEquivEnv.FromEquivTypars formalMethTypars formalMethTypars2) (stripByrefTy g ty1) (stripByrefTy g ty2))) /// Used to hide/filter members from super classes based on signature let PropInfosEquivByNameAndPartialSig erasureFlag g amap m (pinfo:PropInfo) (pinfo2:PropInfo) = diff --git a/src/fsharp/layout.fs b/src/fsharp/layout.fs index 0a59e85582..2ee543d9b1 100755 --- a/src/fsharp/layout.fs +++ b/src/fsharp/layout.fs @@ -109,6 +109,8 @@ module TaggedTextOps = let rightBracket = Internal.Utilities.StructuredFormat.TaggedTextOps.Literals.rightBracket let leftBrace = Internal.Utilities.StructuredFormat.TaggedTextOps.Literals.leftBrace let rightBrace = Internal.Utilities.StructuredFormat.TaggedTextOps.Literals.rightBrace + let leftBraceBar = Internal.Utilities.StructuredFormat.TaggedTextOps.Literals.leftBraceBar + let rightBraceBar = Internal.Utilities.StructuredFormat.TaggedTextOps.Literals.rightBraceBar let equals = Internal.Utilities.StructuredFormat.TaggedTextOps.Literals.equals let arrow = Internal.Utilities.StructuredFormat.TaggedTextOps.Literals.arrow let questionMark = Internal.Utilities.StructuredFormat.TaggedTextOps.Literals.questionMark diff --git a/src/fsharp/layout.fsi b/src/fsharp/layout.fsi index e2d1bcc7a3..a9ced6d9f2 100755 --- a/src/fsharp/layout.fsi +++ b/src/fsharp/layout.fsi @@ -104,6 +104,8 @@ module TaggedTextOps = val rightBracket : TaggedText val leftBrace: TaggedText val rightBrace : TaggedText + val leftBraceBar: TaggedText + val rightBraceBar : TaggedText val leftAngle: TaggedText val rightAngle: TaggedText val equals : TaggedText diff --git a/src/fsharp/lex.fsl b/src/fsharp/lex.fsl index f3842f908e..62fea65c29 100755 --- a/src/fsharp/lex.fsl +++ b/src/fsharp/lex.fsl @@ -562,11 +562,13 @@ rule token args skip = parse | "=" { EQUALS } | "[" { LBRACK } | "[|" { LBRACK_BAR } + | "{|" { LBRACE_BAR } | "<" { LESS false } | ">" { GREATER false } | "[<" { LBRACK_LESS } | "]" { RBRACK } | "|]" { BAR_RBRACK } + | "|}" { BAR_RBRACE } | ">]" { GREATER_RBRACK } | "{" { LBRACE } | "|" { BAR } diff --git a/src/fsharp/lib.fs b/src/fsharp/lib.fs index 3d5e854aff..18404ba377 100755 --- a/src/fsharp/lib.fs +++ b/src/fsharp/lib.fs @@ -226,9 +226,8 @@ module ListSet = | (h::t) -> if contains f h l1 then h::intersect f l1 t else intersect f l1 t | [] -> [] - (* NOTE: quadratic! *) // Note: if duplicates appear, keep the ones toward the _front_ of the list - let setify f l = List.foldBack (insert f) (List.rev l) [] |> List.rev + let setify f l = List.fold (fun acc x -> insert f x acc) [] l |> List.rev let hasDuplicates f l = match l with diff --git a/src/fsharp/pars.fsy b/src/fsharp/pars.fsy index 4d3cf24720..25c8ce10a8 100644 --- a/src/fsharp/pars.fsy +++ b/src/fsharp/pars.fsy @@ -197,8 +197,8 @@ let rangeOfLongIdent(lid:LongIdent) = %token OPEN OR REC THEN TO TRUE TRY TYPE VAL INLINE INTERFACE INSTANCE CONST %token WHEN WHILE WITH HASH AMP AMP_AMP QUOTE LPAREN RPAREN RPAREN_COMING_SOON RPAREN_IS_HERE STAR COMMA RARROW GREATER_BAR_RBRACK LPAREN_STAR_RPAREN %token QMARK QMARK_QMARK DOT COLON COLON_COLON COLON_GREATER COLON_QMARK_GREATER COLON_QMARK COLON_EQUALS SEMICOLON -%token SEMICOLON_SEMICOLON LARROW EQUALS LBRACK LBRACK_BAR LBRACK_LESS LBRACE -%token LBRACE_LESS BAR_RBRACK GREATER_RBRACE UNDERSCORE +%token SEMICOLON_SEMICOLON LARROW EQUALS LBRACK LBRACK_BAR LBRACE_BAR LBRACK_LESS LBRACE +%token BAR_RBRACK BAR_RBRACE UNDERSCORE %token BAR RBRACK RBRACE RBRACE_COMING_SOON RBRACE_IS_HERE MINUS DOLLAR %token GREATER_RBRACK STRUCT SIG %token STATIC MEMBER CLASS ABSTRACT OVERRIDE DEFAULT CONSTRUCTOR INHERIT @@ -675,14 +675,14 @@ fileModuleSpec: (fun (isRec2,path,_) -> if not (isNil path) then errorR(Error(FSComp.SR.parsNamespaceOrModuleNotBoth(),m2)) let lid = path@path2 - ParsedSigFileFragment.NamedModule(SynModuleOrNamespaceSig(lid, (isRec || isRec2), true, $4, xml,$1,vis,m))) } + ParsedSigFileFragment.NamedModule(SynModuleOrNamespaceSig(lid, (isRec || isRec2), NamedModule, $4, xml,$1,vis,m))) } | moduleSpfnsPossiblyEmptyBlock { let m = (rhs parseState 1) (fun (isRec, path, xml) -> match path with | [] -> ParsedSigFileFragment.AnonModule($1, m) - | _ -> ParsedSigFileFragment.NamespaceFragment(path, isRec, false, $1, xml,[],m)) } + | _ -> ParsedSigFileFragment.NamespaceFragment(path, isRec, DeclaredNamespace, $1, xml,[],m)) } moduleSpfnsPossiblyEmptyBlock: @@ -1097,14 +1097,14 @@ fileModuleImpl: (fun (isRec, path, _) -> if not (isNil path) then errorR(Error(FSComp.SR.parsNamespaceOrModuleNotBoth(),m2)) let lid = path@path2 - ParsedImplFileFragment.NamedModule(SynModuleOrNamespace(lid, (isRec || isRec2), true, $4, xml,$1,vis,m))) } + ParsedImplFileFragment.NamedModule(SynModuleOrNamespace(lid, (isRec || isRec2), NamedModule, $4, xml,$1,vis,m))) } | moduleDefnsOrExprPossiblyEmptyOrBlock { let m = (rhs parseState 1) (fun (isRec, path, xml) -> match path with | [] -> ParsedImplFileFragment.AnonModule($1,m) - | _ -> ParsedImplFileFragment.NamespaceFragment(path, isRec, false, $1, xml,[],m)) } + | _ -> ParsedImplFileFragment.NamespaceFragment(path, isRec, DeclaredNamespace, $1, xml,[],m)) } /* A collection/block of definitions or expressions making up a module or namespace, possibly empty */ @@ -1782,10 +1782,10 @@ memberCore: let args = if id.idText = "set" then match args with - | [SynPat.Paren(SynPat.Tuple (indexPats,_),indexPatRange);valuePat] when id.idText = "set" -> - [SynPat.Tuple(indexPats@[valuePat],unionRanges indexPatRange valuePat.Range)] + | [SynPat.Paren(SynPat.Tuple (false,indexPats,_),indexPatRange);valuePat] when id.idText = "set" -> + [SynPat.Tuple(false,indexPats@[valuePat],unionRanges indexPatRange valuePat.Range)] | [indexPat;valuePat] -> - [SynPat.Tuple(args,unionRanges indexPat.Range valuePat.Range)] + [SynPat.Tuple(false,args,unionRanges indexPat.Range valuePat.Range)] | [valuePat] -> [valuePat] | _ -> @@ -1945,11 +1945,11 @@ opt_classDefn: /* An 'inherits' definition in an object type definition */ inheritsDefn: - | INHERIT appTypeNonAtomicDeprecated optBaseSpec + | INHERIT atomTypeNonAtomicDeprecated optBaseSpec { let mDecl = unionRanges (rhs parseState 1) (($2): SynType).Range SynMemberDefn.Inherit($2,$3,mDecl) } - | INHERIT appTypeNonAtomicDeprecated opt_HIGH_PRECEDENCE_APP atomicExprAfterType optBaseSpec + | INHERIT atomTypeNonAtomicDeprecated opt_HIGH_PRECEDENCE_APP atomicExprAfterType optBaseSpec { let mDecl = unionRanges (rhs parseState 1) $4.Range SynMemberDefn.ImplicitInherit($2,$4,$5,mDecl) } @@ -2081,6 +2081,24 @@ braceFieldDeclList: | LBRACE error rbrace { [] } +anonRecdType: + | STRUCT braceBarFieldDeclListCore + { $2,true } + | braceBarFieldDeclListCore + { $1,false } + +/* The core of a record type definition */ +braceBarFieldDeclListCore: + | LBRACE_BAR recdFieldDeclList bar_rbrace + { $2 } + + | LBRACE_BAR recdFieldDeclList recover + { reportParseErrorAt (rhs parseState 1) (FSComp.SR.parsUnmatchedBraceBar()) + $2 } + + | LBRACE_BAR error bar_rbrace + { [] } + inlineAssemblyTyconRepr: | HASH stringOrKeywordString HASH { libraryOnlyError (lhs parseState) @@ -2210,8 +2228,8 @@ typeConstraint: | nm -> raiseParseErrorAt (rhs parseState 3) (FSComp.SR.parsUnexpectedIdentifier(nm)) } typarAlts: - | typarAlts OR appType { $3::$1 } - | appType { [$1] } + | typarAlts OR appType { $3::$1 } + | appType { [$1] } /* The core of a union type definition */ unionTypeRepr: @@ -2359,7 +2377,7 @@ openDecl: /*-------------------------------------------------------------------------*/ -/* F# Definitions and Expressions */ +/* F# Definitions, Types, Patterns and Expressions */ /* A 'let ...' or 'do ...' statement in the non-#light syntax */ defnBindings: @@ -2472,7 +2490,7 @@ cPrototype: SynExpr.Const(SynConst.String("extern was not given a DllImport attribute",rhs parseState 8),rhs parseState 8), mRhs) (fun attrs vis -> - let bindingId = SynPat.LongIdent (LongIdentWithDots([nm],[]), None, Some noInferredTypars, SynConstructorArgs.Pats [SynPat.Tuple(args,argsm)], vis, nmm) + let bindingId = SynPat.LongIdent (LongIdentWithDots([nm],[]), None, Some noInferredTypars, SynConstructorArgs.Pats [SynPat.Tuple(false,args,argsm)], vis, nmm) let binding = mkSynBinding (xmlDoc, bindingId) (vis, false, false, mBindLhs, NoSequencePointAtInvisibleBinding, Some rty ,rhsExpr, mRhs, [], attrs, None) @@ -2754,9 +2772,9 @@ headBindingPattern: | headBindingPattern BAR headBindingPattern { SynPat.Or($1,$3,rhs2 parseState 1 3) } | headBindingPattern COLON_COLON headBindingPattern - { SynPat.LongIdent (LongIdentWithDots(mkSynCaseName (rhs parseState 2) opNameCons,[]), None, None, SynConstructorArgs.Pats [SynPat.Tuple ([$1;$3],rhs2 parseState 1 3)],None,lhs parseState) } + { SynPat.LongIdent (LongIdentWithDots(mkSynCaseName (rhs parseState 2) opNameCons,[]), None, None, SynConstructorArgs.Pats [SynPat.Tuple (false,[$1;$3],rhs2 parseState 1 3)],None,lhs parseState) } | tuplePatternElements %prec pat_tuple - { SynPat.Tuple(List.rev $1, lhs parseState) } + { SynPat.Tuple(false,List.rev $1, lhs parseState) } | conjPatternElements %prec pat_conj { SynPat.Ands(List.rev $1, lhs parseState) } | constrPattern @@ -2790,7 +2808,7 @@ constrPattern: { let vis,lid = $1 in SynPat.LongIdent (lid,None,$2, $4,vis,lhs parseState) } | atomicPatternLongIdent opt_explicitValTyparDecls2 HIGH_PRECEDENCE_BRACK_APP atomicPatsOrNamePatPairs { let vis,lid = $1 in SynPat.LongIdent (lid,None,$2, $4,vis,lhs parseState) } - | COLON_QMARK atomType %prec pat_isinst + | COLON_QMARK atomTypeOrAnonRecdType %prec pat_isinst { SynPat.IsInst($2,lhs parseState) } | atomicPattern { $1 } @@ -2815,8 +2833,8 @@ atomicPattern: | quoteExpr { SynPat.QuoteExpr($1,lhs parseState) } | CHAR DOT_DOT CHAR { SynPat.DeprecatedCharRange ($1,$3,rhs2 parseState 1 3) } - | LBRACE recordPatternElements rbrace - { $2 } + | LBRACE recordPatternElementsAux rbrace + { let rs,m = $2 in SynPat.Record (rs,m) } | LBRACK listPatternElements RBRACK { SynPat.ArrayOrList(false,$2,lhs parseState) } | LBRACK_BAR listPatternElements BAR_RBRACK @@ -2850,10 +2868,10 @@ atomicPattern: { reportParseErrorAt (rhs parseState 1) (FSComp.SR.parsUnmatchedParen()) SynPat.Wild (lhs parseState)} | STRUCT LPAREN tupleParenPatternElements rparen - { SynPat.StructTuple(List.rev $3,lhs parseState) } + { SynPat.Tuple(true, List.rev $3,lhs parseState) } | STRUCT LPAREN tupleParenPatternElements recover { reportParseErrorAt (rhs parseState 2) (FSComp.SR.parsUnmatchedParen()); - SynPat.StructTuple(List.rev $3,lhs parseState) } + SynPat.Tuple(true, List.rev $3,lhs parseState) } | STRUCT LPAREN error rparen { (* silent recovery *) SynPat.Wild (lhs parseState) } | STRUCT LPAREN recover @@ -2899,7 +2917,7 @@ parenPattern: | parenPattern BAR parenPattern { SynPat.Or($1,$3,rhs2 parseState 1 3) } | tupleParenPatternElements - { SynPat.Tuple(List.rev $1,lhs parseState) } + { SynPat.Tuple(false,List.rev $1,lhs parseState) } | conjParenPatternElements { SynPat.Ands(List.rev $1,rhs2 parseState 1 3) } | parenPattern COLON typeWithTypeConstraints %prec paren_pat_colon @@ -2909,7 +2927,7 @@ parenPattern: { let lhsm = lhs parseState SynPat.Attrib($2,$1,lhsm) } | parenPattern COLON_COLON parenPattern - { SynPat.LongIdent (LongIdentWithDots(mkSynCaseName (rhs parseState 2) opNameCons,[]), None, None, SynConstructorArgs.Pats [ SynPat.Tuple ([$1;$3],rhs2 parseState 1 3) ],None,lhs parseState) } + { SynPat.LongIdent (LongIdentWithDots(mkSynCaseName (rhs parseState 2) opNameCons,[]), None, None, SynConstructorArgs.Pats [ SynPat.Tuple (false,[$1;$3],rhs2 parseState 1 3) ],None,lhs parseState) } | constrPattern { $1 } tupleParenPatternElements: @@ -2924,9 +2942,6 @@ conjParenPatternElements: | parenPattern AMP parenPattern { $3 :: $1 :: [] } -recordPatternElements: - | recordPatternElementsAux { let rs,m = $1 in SynPat.Record (rs,m) } - recordPatternElementsAux: /* Fix 1190 */ | recordPatternElement opt_seps { [$1],lhs parseState } @@ -3044,7 +3059,7 @@ declExpr: { let mMatch = (rhs parseState 1) let mWith,(clauses,mLast) = $3 let spBind = SequencePointAtBinding(unionRanges mMatch mWith) - SynExpr.Match(spBind, $2,clauses,false,unionRanges mMatch mLast) } + SynExpr.Match(spBind, $2,clauses,unionRanges mMatch mLast) } | MATCH typedSeqExpr recover %prec expr_match { if not $3 then reportParseErrorAt (rhs parseState 1) (FSComp.SR.parsUnexpectedEndOfFileMatch()) @@ -3055,7 +3070,7 @@ declExpr: { let mMatch = (rhs parseState 1) let mWith,(clauses,mLast) = $3 let spBind = SequencePointAtBinding(unionRanges mMatch mWith) - SynExpr.MatchBang(spBind, $2,clauses,false,unionRanges mMatch mLast) } + SynExpr.MatchBang(spBind, $2,clauses,unionRanges mMatch mLast) } | MATCH_BANG typedSeqExpr recover %prec expr_match { if not $3 then reportParseErrorAt (rhs parseState 1) (FSComp.SR.parsUnexpectedEndOfFileMatch()) @@ -3340,7 +3355,7 @@ declExpr: | declExpr COLON_EQUALS declExpr { mkSynInfix (rhs parseState 2) $1 ":=" $3 } | minusExpr LARROW declExprBlock { mkSynAssign $1 $3 } /* | minusExpr LARROW recover { mkSynAssign $1 (arbExpr("assignRhs",rhs parseState 2)) } */ - | tupleExpr %prec expr_tuple { let exprs,commas = $1 in SynExpr.Tuple(List.rev exprs, List.rev commas, (commas.Head, exprs) ||> unionRangeWithListBy (fun e -> e.Range) ) } + | tupleExpr %prec expr_tuple { let exprs,commas = $1 in SynExpr.Tuple(false, List.rev exprs, List.rev commas, (commas.Head, exprs) ||> unionRangeWithListBy (fun e -> e.Range) ) } | declExpr JOIN_IN declExpr { SynExpr.JoinIn($1,rhs parseState 2,$3,unionRanges $1.Range $3.Range) } | declExpr BAR_BAR declExpr { mkSynInfix (rhs parseState 2) $1 "||" $3 } | declExpr INFIX_BAR_OP declExpr { mkSynInfix (rhs parseState 2) $1 $2 $3 } @@ -3357,7 +3372,7 @@ declExpr: | declExpr GREATER declExpr { mkSynInfix (rhs parseState 2) $1 ">" $3 } | declExpr INFIX_AT_HAT_OP declExpr { mkSynInfix (rhs parseState 2) $1 $2 $3 } | declExpr PERCENT_OP declExpr { mkSynInfix (rhs parseState 2) $1 $2 $3 } - | declExpr COLON_COLON declExpr { SynExpr.App (ExprAtomicFlag.NonAtomic, true, mkSynIdGet (rhs parseState 2) opNameCons,SynExpr.Tuple ([$1;$3],[rhs parseState 2],unionRanges $1.Range $3.Range),unionRanges $1.Range $3.Range) } + | declExpr COLON_COLON declExpr { SynExpr.App (ExprAtomicFlag.NonAtomic, true, mkSynIdGet (rhs parseState 2) opNameCons,SynExpr.Tuple (false,[$1;$3],[rhs parseState 2],unionRanges $1.Range $3.Range),unionRanges $1.Range $3.Range) } | declExpr PLUS_MINUS_OP declExpr { mkSynInfix (rhs parseState 2) $1 $2 $3 } | declExpr MINUS declExpr { mkSynInfix (rhs parseState 2) $1 "-" $3 } | declExpr STAR declExpr { mkSynInfix (rhs parseState 2) $1 "*" $3 } @@ -3393,7 +3408,7 @@ declExpr: | declExpr PERCENT_OP OBLOCKEND_COMING_SOON { reportParseErrorAt (rhs parseState 2) (FSComp.SR.parsUnfinishedExpression($2)) exprFromParseError(mkSynInfix (rhs parseState 2) $1 $2 (arbExpr("declExprInfix",(rhs parseState 3).StartRange))) } | declExpr COLON_COLON OBLOCKEND_COMING_SOON { reportParseErrorAt (rhs parseState 2) (FSComp.SR.parsUnfinishedExpression("::")) - SynExpr.App (ExprAtomicFlag.NonAtomic, true, mkSynIdGet (rhs parseState 2) opNameCons,SynExpr.Tuple ([$1;(arbExpr("declExprInfix",(rhs parseState 3).StartRange))],[rhs parseState 2],unionRanges $1.Range (rhs parseState 3).StartRange),unionRanges $1.Range (rhs parseState 3).StartRange) } + SynExpr.App (ExprAtomicFlag.NonAtomic, true, mkSynIdGet (rhs parseState 2) opNameCons,SynExpr.Tuple (false,[$1;(arbExpr("declExprInfix",(rhs parseState 3).StartRange))],[rhs parseState 2],unionRanges $1.Range (rhs parseState 3).StartRange),unionRanges $1.Range (rhs parseState 3).StartRange) } | declExpr PLUS_MINUS_OP OBLOCKEND_COMING_SOON { reportParseErrorAt (rhs parseState 2) (FSComp.SR.parsUnfinishedExpression($2)) exprFromParseError(mkSynInfix (rhs parseState 2) $1 $2 (arbExpr("declExprInfix",(rhs parseState 3).StartRange))) } | declExpr MINUS OBLOCKEND_COMING_SOON { reportParseErrorAt (rhs parseState 2) (FSComp.SR.parsUnfinishedExpression("-")) @@ -3558,10 +3573,10 @@ minusExpr: | AMP_AMP minusExpr { SynExpr.AddressOf(false,$2,rhs parseState 1, unionRanges (rhs parseState 1) $2.Range) } - | NEW appTypeNonAtomicDeprecated opt_HIGH_PRECEDENCE_APP atomicExprAfterType + | NEW atomTypeNonAtomicDeprecated opt_HIGH_PRECEDENCE_APP atomicExprAfterType { SynExpr.New(false,$2,$4,unionRanges (rhs parseState 1) $4.Range) } - | NEW appTypeNonAtomicDeprecated opt_HIGH_PRECEDENCE_APP error + | NEW atomTypeNonAtomicDeprecated opt_HIGH_PRECEDENCE_APP error { SynExpr.New(false,$2,arbExpr("minusExpr",(rhs parseState 4)),unionRanges (rhs parseState 1) ($2).Range) } | NEW error @@ -3656,11 +3671,11 @@ atomicExpr: exprFromParseError (SynExpr.ArrayOrList(false,[ ], rhs parseState 1)),false } | STRUCT LPAREN tupleExpr rparen - { let exprs,commas = $3 in SynExpr.StructTuple(List.rev exprs, List.rev commas, (commas.Head, exprs) ||> unionRangeWithListBy (fun e -> e.Range) ), false } + { let exprs,commas = $3 in SynExpr.Tuple(true, List.rev exprs, List.rev commas, (commas.Head, exprs) ||> unionRangeWithListBy (fun e -> e.Range) ), false } | STRUCT LPAREN tupleExpr recover { reportParseErrorAt (rhs parseState 2) (FSComp.SR.parsUnmatchedBracket()); - let exprs,commas = $3 in SynExpr.StructTuple(List.rev exprs, List.rev commas, (commas.Head, exprs) ||> unionRangeWithListBy (fun e -> e.Range) ), false } + let exprs,commas = $3 in SynExpr.Tuple(true, List.rev exprs, List.rev commas, (commas.Head, exprs) ||> unionRangeWithListBy (fun e -> e.Range) ), false } | atomicExprAfterType { $1,false } @@ -3748,6 +3763,8 @@ atomicExprAfterType: { $1 } | braceExpr { $1 } + | braceBarExpr + { $1 } | NULL { SynExpr.Null(lhs parseState) } | FALSE @@ -3974,6 +3991,10 @@ forLoopRange: | parenPattern EQUALS rangeSequenceExpr { raiseParseErrorAt (rhs parseState 2) (FSComp.SR.parsUnexpectedSymbolEqualsInsteadOfIn()) } +forLoopDirection: + | TO { true } + | DOWNTO { false } + inlineAssemblyExpr: | HASH stringOrKeywordString opt_inlineAssemblyTypeArg opt_curriedArgExprs opt_inlineAssemblyReturnTypes HASH { libraryOnlyWarning (lhs parseState) @@ -4009,7 +4030,7 @@ opt_inlineAssemblyReturnTypes: { [] } recdExpr: - | INHERIT appTypeNonAtomicDeprecated opt_HIGH_PRECEDENCE_APP opt_atomicExprAfterType recdExprBindings opt_seps_recd + | INHERIT atomTypeNonAtomicDeprecated opt_HIGH_PRECEDENCE_APP opt_atomicExprAfterType recdExprBindings opt_seps_recd { let arg = match $4 with None -> mkSynUnit (lhs parseState) | Some e -> e let l = List.rev $5 let dummyField = mkRecdField (LongIdentWithDots([], [])) // dummy identifier, it will be discarded @@ -4017,14 +4038,17 @@ recdExpr: let (_, _, inheritsSep) = List.head l let bindings = List.tail l (Some ($2,arg,rhs2 parseState 2 4, inheritsSep, rhs parseState 1), None, bindings) } + | recdExprCore + { let a,b = $1 in (None, a, b) } +recdExprCore: | appExpr EQUALS declExprBlock recdExprBindings opt_seps_recd { match $1 with | LongOrSingleIdent(false, (LongIdentWithDots(_,_) as f),None,m) -> let f = mkRecdField f let l = List.rev $4 let l = rebindRanges (f, Some $3) l $5 - (None, None, l) + (None, l) | _ -> raiseParseErrorAt (rhs parseState 2) (FSComp.SR.parsFieldBinding()) } /* @@ -4036,7 +4060,7 @@ recdExpr: reportParseErrorAt m (FSComp.SR.parsUnderscoreInvalidFieldName()) reportParseErrorAt m (FSComp.SR.parsFieldBinding()) let f = mkUnderscoreRecdField m - (None, None, [ f, None, None ]) } + (None, [ (f, None, None) ]) } | UNDERSCORE EQUALS { let m = rhs parseState 1 @@ -4045,29 +4069,28 @@ recdExpr: reportParseErrorAt (rhs2 parseState 1 2) (FSComp.SR.parsFieldBinding()) - (None, None, [f, None, None]) } + (None, [ (f, None, None) ]) } | UNDERSCORE EQUALS declExprBlock recdExprBindings opt_seps_recd { reportParseErrorAt (rhs parseState 1) (FSComp.SR.parsUnderscoreInvalidFieldName()) let f = mkUnderscoreRecdField (rhs parseState 1) - let l = List.rev $4 let l = rebindRanges (f, Some $3) l $5 - (None, None, l) } + (None, l) } /* handles case like {x with} */ | appExpr WITH recdBinding recdExprBindings opt_seps_recd { let l = List.rev $4 let l = rebindRanges $3 l $5 - (None,Some ($1, (rhs parseState 2, None)), l) } + (Some ($1, (rhs parseState 2, None)), l) } | appExpr OWITH opt_seps_recd OEND - { (None,Some ($1, (rhs parseState 2, None)), []) } + { (Some ($1, (rhs parseState 2, None)), []) } | appExpr OWITH recdBinding recdExprBindings opt_seps_recd OEND { let l = List.rev $4 let l = rebindRanges $3 l $5 - (None,Some ($1, (rhs parseState 2, None)), l) } + (Some ($1, (rhs parseState 2, None)), l) } opt_seps_recd: | seps_recd { Some $1 } @@ -4079,6 +4102,7 @@ seps_recd: | SEMICOLON OBLOCKSEP { (rhs2 parseState 1 2), Some (rhs parseState 1).End } | OBLOCKSEP SEMICOLON { (rhs2 parseState 1 2), Some (rhs parseState 2).End } + /* identifier can start from the underscore */ @@ -4131,19 +4155,19 @@ objExpr: let fullRange = match $3 with [] -> (rhs parseState 1) | _ -> (rhs2 parseState 1 3) fullRange, (fun m -> let (a,b) = $1 in SynExpr.ObjExpr(a,b,[],$3, mNewExpr, m)) } - | NEW appTypeNonAtomicDeprecated + | NEW atomTypeNonAtomicDeprecated { let mNewExpr = rhs parseState 1 (rhs2 parseState 1 2), (fun m -> let (a,b) = $2,None in SynExpr.ObjExpr(a,b,[],[], mNewExpr, m)) } objExprBaseCall: - | NEW appTypeNonAtomicDeprecated opt_HIGH_PRECEDENCE_APP atomicExprAfterType baseSpec + | NEW atomTypeNonAtomicDeprecated opt_HIGH_PRECEDENCE_APP atomicExprAfterType baseSpec { ($2, Some($4,Some($5))) } - | NEW appTypeNonAtomicDeprecated opt_HIGH_PRECEDENCE_APP atomicExprAfterType + | NEW atomTypeNonAtomicDeprecated opt_HIGH_PRECEDENCE_APP atomicExprAfterType { ($2, Some($4,None)) } - | NEW appTypeNonAtomicDeprecated + | NEW atomTypeNonAtomicDeprecated { $2,None } @@ -4187,9 +4211,47 @@ objExprInterface: | interfaceMember appType opt_objExprBindings opt_declEnd opt_OBLOCKSEP { InterfaceImpl($2, $3, lhs parseState) } -forLoopDirection: - | TO { true } - | DOWNTO { false } +braceBarExpr: + | STRUCT braceBarExprCore + { $2 true } + | braceBarExprCore + { $1 false } + +braceBarExprCore: + | LBRACE_BAR recdExprCore bar_rbrace + { let orig, flds = $2 + let flds = + flds |> List.choose (function + | ((LongIdentWithDots([id],_),_),Some e,_) -> Some (id,e) + | ((LongIdentWithDots([id],_),_),None,_) -> Some (id, arbExpr("anonField",id.idRange)) + | _ -> reportParseErrorAt (rhs parseState 1) (FSComp.SR.parsInvalidAnonRecdType()); None) + let m = rhs2 parseState 1 3 + (fun isStruct -> SynExpr.AnonRecd(isStruct,orig,flds,m)) } + + | LBRACE_BAR recdExprCore recover + { reportParseErrorAt (rhs parseState 1) (FSComp.SR.parsUnmatchedBraceBar()) + let orig, flds = $2 + let flds = + flds |> List.choose (function + | ((LongIdentWithDots([id],_),_),Some e,_) -> Some (id,e) + | ((LongIdentWithDots([id],_),_),None,_) -> Some (id, arbExpr("anonField",id.idRange)) + | _ -> reportParseErrorAt (rhs parseState 1) (FSComp.SR.parsInvalidAnonRecdType()); None) + let m = rhs2 parseState 1 2 + (fun isStruct -> SynExpr.AnonRecd(isStruct,orig,flds,m)) } + + | LBRACE_BAR error bar_rbrace + { // silent recovery + let m = rhs2 parseState 1 3 + (fun _ -> arbExpr("braceBarExpr",m)) } + + | LBRACE_BAR recover + { reportParseErrorAt (rhs parseState 1) (FSComp.SR.parsUnmatchedBraceBar()) + let m = rhs2 parseState 1 1 + (fun isStruct -> SynExpr.AnonRecd(isStruct,None,[],m)) } + + | LBRACE_BAR bar_rbrace + { let m = rhs2 parseState 1 2 + (fun isStruct -> SynExpr.AnonRecd(isStruct,None,[],m)) } anonLambdaExpr: | FUN atomicPatterns RARROW typedSeqExprBlock @@ -4273,7 +4335,7 @@ topType: topTupleType: | topAppType STAR topTupleTypeElements - { let ty,mdata = $1 in let tys,mdatas = List.unzip $3 in (SynType.Tuple(List.map (fun ty -> (false,ty)) (ty ::tys), lhs parseState)),(mdata :: mdatas) } + { let ty,mdata = $1 in let tys,mdatas = List.unzip $3 in (SynType.Tuple(false,List.map (fun ty -> (false,ty)) (ty ::tys), lhs parseState)),(mdata :: mdatas) } | topAppType { let ty,mdata = $1 in ty,[mdata] } @@ -4323,15 +4385,15 @@ typEOF: tupleType: | appType STAR tupleOrQuotTypeElements - { SynType.Tuple((false,$1) :: $3,lhs parseState) } + { SynType.Tuple(false,(false,$1) :: $3,lhs parseState) } | INFIX_STAR_DIV_MOD_OP tupleOrQuotTypeElements { if $1 <> "/" then reportParseErrorAt (rhs parseState 1) (FSComp.SR.parsUnexpectedInfixOperator()); - SynType.Tuple((true, SynType.StaticConstant (SynConst.Int32 1, lhs parseState)):: $2, lhs parseState) } + SynType.Tuple(false,(true, SynType.StaticConstant (SynConst.Int32 1, lhs parseState)):: $2, lhs parseState) } | appType INFIX_STAR_DIV_MOD_OP tupleOrQuotTypeElements { if $2 <> "/" then reportParseErrorAt (rhs parseState 1) (FSComp.SR.parsUnexpectedInfixOperator()); - SynType.Tuple((true,$1) :: $3, lhs parseState) } + SynType.Tuple(false,(true,$1) :: $3, lhs parseState) } | appType %prec prec_tuptyp_prefix { $1 } @@ -4347,13 +4409,6 @@ tupleOrQuotTypeElements: | appType %prec prec_tuptyptail_prefix { [(false,$1)] } -tupleTypeElements: - | appType STAR tupleTypeElements - { $1 :: $3 } - - | appType %prec prec_tuptyptail_prefix - { [$1] } - appTypeCon: | path %prec prec_atomtyp_path { SynType.LongIdent($1) } @@ -4427,57 +4482,37 @@ typeArgListElements: { [], [] } powerType: - | atomType + | atomTypeOrAnonRecdType { $1 } - | atomType INFIX_AT_HAT_OP atomicRationalConstant + | atomTypeOrAnonRecdType INFIX_AT_HAT_OP atomicRationalConstant { if $2 <> "^" && $2 <> "^-" then reportParseErrorAt (rhs parseState 2) (FSComp.SR.parsUnexpectedInfixOperator()); if $2 = "^-" then SynType.MeasurePower($1, SynRationalConst.Negate($3), lhs parseState) else SynType.MeasurePower($1, $3, lhs parseState) } -/* Like appType but gives a deprecation error when a non-atomic type is used */ -appTypeNonAtomicDeprecated: - | appType arrayTypeSuffix - { deprecatedWithError (FSComp.SR.parsNonAtomicType()) (lhs parseState); - SynType.Array($2,$1,lhs parseState) } - - | appType HIGH_PRECEDENCE_BRACK_APP arrayTypeSuffix /* only HPA for "name[]" allowed here */ - { deprecatedWithError (FSComp.SR.parsNonAtomicType()) (lhs parseState); - SynType.Array($3,$1,lhs parseState) } - - | appType appTypeConPower - { let mWhole = unionRanges (rhs parseState 1) $2.Range // note: use "rhs parseState 1" to deal with parens in "(int) list" - deprecatedWithError (FSComp.SR.parsNonAtomicType()) mWhole; - SynType.App($2, None, [$1], [], None, true, mWhole) } +/* Like appType but gives a deprecation error when a non-atomic type is used */ +/* Also, doesn't start with '{|' */ +atomTypeNonAtomicDeprecated: | LPAREN appTypePrefixArguments rparen appTypeConPower { let args, commas = $2 mlCompatWarning (FSComp.SR.parsMultiArgumentGenericTypeFormDeprecated()) (unionRanges (rhs parseState 1) $4.Range); SynType.App($4, None, args, commas, None, true, unionRanges (rhs parseState 1) $4.Range) } - | powerTypeNonAtomicDeprecated + | atomType { $1 } - | typar COLON_GREATER typ - { deprecatedWithError (FSComp.SR.parsNonAtomicType()) (lhs parseState); - let tp,typ = $1,$3 - let m = lhs parseState - SynType.WithGlobalConstraints(SynType.Var (tp, rhs parseState 1), [WhereTyparSubtypeOfType(tp,typ,m)],m) } - - | UNDERSCORE COLON_GREATER typ %prec COLON_GREATER - { deprecatedWithError (FSComp.SR.parsNonAtomicType()) (lhs parseState); - SynType.HashConstraint($3, lhs parseState) } - -/* Like powerType but gives a deprecation warning if a non-atomic type is used */ -powerTypeNonAtomicDeprecated: +atomTypeOrAnonRecdType: | atomType - { $1 } + { $1 } + | anonRecdType + { let flds,isStruct = $1 + let flds2 = + flds |> List.choose (function + | (Field([],false,Some id,ty,false,_xmldoc,None,_m)) -> Some (id,ty) + | _ -> reportParseErrorAt (rhs parseState 1) (FSComp.SR.parsInvalidAnonRecdType()); None) + SynType.AnonRecd (isStruct,flds2, rhs parseState 1) } - | atomType INFIX_AT_HAT_OP atomicRationalConstant - { if $2 <> "^" && $2 <> "^-" then reportParseErrorAt (rhs parseState 2) (FSComp.SR.parsUnexpectedInfixOperator()); - deprecatedWithError (FSComp.SR.parsNonAtomicType()) (lhs parseState); - if $2 = "^-" then SynType.MeasurePower($1, SynRationalConst.Negate($3), lhs parseState) - else SynType.MeasurePower($1, $3, lhs parseState) } /* Any tokens in this grammar must be added to the lex filter rule 'peekAdjacentTypars' */ @@ -4500,11 +4535,11 @@ atomType: $2 } | STRUCT LPAREN appType STAR tupleOrQuotTypeElements rparen - { SynType.StructTuple((false,$3) :: $5,lhs parseState) } + { SynType.Tuple(true, (false,$3) :: $5,lhs parseState) } | STRUCT LPAREN appType STAR tupleOrQuotTypeElements recover { reportParseErrorAt (rhs parseState 2) (FSComp.SR.parsUnmatchedParen()) - SynType.StructTuple((false,$3) :: $5,lhs parseState) } + SynType.Tuple(true, (false,$3) :: $5,lhs parseState) } | STRUCT LPAREN appType STAR recover { reportParseErrorAt (rhs parseState 2) (FSComp.SR.parsUnmatchedParen()) @@ -4976,6 +5011,9 @@ rbrace: | RBRACE_IS_HERE { } | RBRACE { } +bar_rbrace: + | BAR_RBRACE { } + rparen: | RPAREN_COMING_SOON rparen { } | RPAREN_IS_HERE { } diff --git a/src/fsharp/range.fs b/src/fsharp/range.fs index 8649b70086..4e97edc2b3 100755 --- a/src/fsharp/range.fs +++ b/src/fsharp/range.fs @@ -5,99 +5,119 @@ module Microsoft.FSharp.Compiler.Range open System open System.IO -open System.Collections.Generic +open System.Collections.Concurrent open Microsoft.FSharp.Core.Printf -open Internal.Utilities -open Microsoft.FSharp.Compiler.AbstractIL -open Microsoft.FSharp.Compiler.AbstractIL.Internal open Microsoft.FSharp.Compiler.AbstractIL.Internal.Library -open Microsoft.FSharp.Compiler open Microsoft.FSharp.Compiler.Lib open Microsoft.FSharp.Compiler.Lib.Bits type FileIndex = int32 [] -let columnBitCount = 9 +let columnBitCount = 20 + [] -let lineBitCount = 16 +let lineBitCount = 31 let posBitCount = lineBitCount + columnBitCount -let _ = assert (posBitCount <= 32) -let posColumnMask = mask32 0 columnBitCount -let lineColumnMask = mask32 columnBitCount lineBitCount -let inline (lsr) (x:int) (y:int) = int32 (uint32 x >>> y) + +let posColumnMask = mask64 0 columnBitCount + +let lineColumnMask = mask64 columnBitCount lineBitCount [] [] -type pos(code:int32) = +type pos(code:int64) = + new (l, c) = let l = max 0 l let c = max 0 c - let p = ( c &&& posColumnMask) - ||| ((l <<< columnBitCount) &&& lineColumnMask) + let p = (int64 c &&& posColumnMask) + ||| ((int64 l <<< columnBitCount) &&& lineColumnMask) pos p - member p.Line = (code lsr columnBitCount) - member p.Column = (code &&& posColumnMask) + member p.Line = int32 (uint64 code >>> columnBitCount) + + member p.Column = int32 (code &&& posColumnMask) member r.Encoding = code + static member EncodingSize = posBitCount - static member Decode (code:int32) : pos = pos code + + static member Decode (code:int64) : pos = pos code + override p.Equals(obj) = match obj with :? pos as p2 -> code = p2.Encoding | _ -> false + override p.GetHashCode() = hash code + override p.ToString() = sprintf "(%d,%d)" p.Line p.Column [] -let fileIndexBitCount = 14 +let fileIndexBitCount = 24 + [] -let startLineBitCount = lineBitCount +let startColumnBitCount = columnBitCount // 20 + [] -let startColumnBitCount = columnBitCount +let endColumnBitCount = columnBitCount // 20 + [] -let heightBitCount = 15 // If necessary, could probably deduct one or two bits here without ill effect. +let startLineBitCount = lineBitCount // 31 + [] -let endColumnBitCount = columnBitCount +let heightBitCount = 27 + [] let isSyntheticBitCount = 1 -#if DEBUG -let _ = assert (fileIndexBitCount + startLineBitCount + startColumnBitCount + heightBitCount + endColumnBitCount + isSyntheticBitCount = 64) -#endif - + [] let fileIndexShift = 0 + [] -let startLineShift = 14 -[] -let startColumnShift = 30 +let startColumnShift = 24 + [] -let heightShift = 39 +let endColumnShift = 44 + [] -let endColumnShift = 54 +let startLineShift = 0 + [] -let isSyntheticShift = 63 +let heightShift = 31 +[] +let isSyntheticShift = 58 [] -let fileIndexMask = 0b0000000000000000000000000000000000000000000000000011111111111111L +let fileIndexMask = 0b0000000000000000000000000000000000000000111111111111111111111111L + [] -let startLineMask = 0b0000000000000000000000000000000000111111111111111100000000000000L +let startColumnMask = 0b0000000000000000000011111111111111111111000000000000000000000000L + [] -let startColumnMask = 0b0000000000000000000000000111111111000000000000000000000000000000L +let endColumnMask = 0b1111111111111111111100000000000000000000000000000000000000000000L + [] -let heightMask = 0b0000000000111111111111111000000000000000000000000000000000000000L +let startLineMask = 0b0000000000000000000000000000000001111111111111111111111111111111L + [] -let endColumnMask = 0b0111111111000000000000000000000000000000000000000000000000000000L +let heightMask = 0b0000001111111111111111111111111110000000000000000000000000000000L + [] -let isSyntheticMask = 0b1000000000000000000000000000000000000000000000000000000000000000L +let isSyntheticMask = 0b0000010000000000000000000000000000000000000000000000000000000000L #if DEBUG -let _ = assert (startLineShift = fileIndexShift + fileIndexBitCount) -let _ = assert (startColumnShift = startLineShift + startLineBitCount) -let _ = assert (heightShift = startColumnShift + startColumnBitCount) -let _ = assert (endColumnShift = heightShift + heightBitCount) -let _ = assert (isSyntheticShift = endColumnShift + endColumnBitCount) -let _ = assert (fileIndexMask = mask64 0 fileIndexBitCount) +let _ = assert (posBitCount <= 64) +let _ = assert (fileIndexBitCount + startColumnBitCount + endColumnBitCount <= 64) +let _ = assert (startLineBitCount + heightBitCount + isSyntheticBitCount <= 64) + +let _ = assert (startColumnShift = fileIndexShift + fileIndexBitCount) +let _ = assert (endColumnShift = startColumnShift + startColumnBitCount) + +let _ = assert (heightShift = startLineShift + startLineBitCount) +let _ = assert (isSyntheticShift = heightShift + heightBitCount) + +let _ = assert (fileIndexMask = mask64 fileIndexShift fileIndexBitCount) let _ = assert (startLineMask = mask64 startLineShift startLineBitCount) let _ = assert (startColumnMask = mask64 startColumnShift startColumnBitCount) let _ = assert (heightMask = mask64 heightShift heightBitCount) @@ -105,28 +125,64 @@ let _ = assert (endColumnMask = mask64 endColumnShift endColumnBitCount) let _ = assert (isSyntheticMask = mask64 isSyntheticShift isSyntheticBitCount) #endif -// This is just a standard unique-index table +/// Removes relative parts from any full paths +let normalizeFilePath (filePath: string) = + try + if FileSystem.IsPathRootedShim filePath then + FileSystem.GetFullPathShim filePath + else + filePath + with _ -> filePath + +/// A unique-index table for file names. type FileIndexTable() = let indexToFileTable = new ResizeArray<_>(11) - let fileToIndexTable = new Dictionary(11) - member t.FileToIndex f = - let mutable res = 0 - let ok = fileToIndexTable.TryGetValue(f, &res) - if ok then res - else + let fileToIndexTable = new ConcurrentDictionary() + + // Note: we should likely adjust this code to always normalize. However some testing (and possibly some + // product behaviour) appears to be sensitive to error messages reporting un-normalized file names. + // Currently all names going through 'mkRange' get normalized, while this going through just 'fileIndexOfFile' + // do not. Also any file names which are not put into ranges at all are non-normalized. + // + // TO move forward we should eventually introduce a new type NormalizedFileName that tracks this invariant. + member t.FileToIndex normalize filePath = + match fileToIndexTable.TryGetValue(filePath) with + | true, idx -> idx + | _ -> + + // Try again looking for a normalized entry. + let normalizedFilePath = if normalize then normalizeFilePath filePath else filePath + match fileToIndexTable.TryGetValue(normalizedFilePath) with + | true, idx -> + // Record the non-normalized entry if necessary + if filePath <> normalizedFilePath then + lock fileToIndexTable (fun () -> + fileToIndexTable.[filePath] <- idx) + + // Return the index + idx + + | _ -> lock fileToIndexTable (fun () -> - let mutable res = 0 in - let ok = fileToIndexTable.TryGetValue(f, &res) in - if ok then res - else - let n = indexToFileTable.Count in - indexToFileTable.Add(f) - fileToIndexTable.[f] <- n - n) + // Get the new index + let idx = indexToFileTable.Count + + // Record the normalized entry + indexToFileTable.Add normalizedFilePath + fileToIndexTable.[normalizedFilePath] <- idx + + // Record the non-normalized entry if necessary + if filePath <> normalizedFilePath then + fileToIndexTable.[filePath] <- idx + + // Return the index + idx) member t.IndexToFile n = - (if n < 0 then failwithf "fileOfFileIndex: negative argument: n = %d\n" n) - (if n >= indexToFileTable.Count then failwithf "fileOfFileIndex: invalid argument: n = %d\n" n) + if n < 0 then + failwithf "fileOfFileIndex: negative argument: n = %d\n" n + if n >= indexToFileTable.Count then + failwithf "fileOfFileIndex: invalid argument: n = %d\n" n indexToFileTable.[n] let maxFileIndex = pown32 fileIndexBitCount @@ -136,8 +192,11 @@ let maxFileIndex = pown32 fileIndexBitCount let fileIndexTable = new FileIndexTable() // If we exceed the maximum number of files we'll start to report incorrect file names -let fileIndexOfFile f = fileIndexTable.FileToIndex(f) % maxFileIndex -let fileOfFileIndex n = fileIndexTable.IndexToFile(n) +let fileIndexOfFileAux normalize f = fileIndexTable.FileToIndex normalize f % maxFileIndex + +let fileIndexOfFile filePath = fileIndexOfFileAux false filePath + +let fileOfFileIndex idx = fileIndexTable.IndexToFile idx let mkPos l c = pos (l, c) @@ -147,28 +206,47 @@ let mkPos l c = pos (l, c) #else [] #endif -type range(code:int64) = - static member Zero = range(0L) +type range(code1:int64, code2: int64) = + static member Zero = range(0L, 0L) new (fidx, bl, bc, el, ec) = - range( int64 fidx - ||| (int64 bl <<< startLineShift) - ||| (int64 bc <<< startColumnShift) - ||| (int64 (el-bl) <<< heightShift) - ||| (int64 ec <<< endColumnShift) ) + let code1 = ((int64 fidx) &&& fileIndexMask) + ||| ((int64 bc <<< startColumnShift) &&& startColumnMask) + ||| ((int64 ec <<< endColumnShift) &&& endColumnMask) + let code2 = + ((int64 bl <<< startLineShift) &&& startLineMask) + ||| ((int64 (el-bl) <<< heightShift) &&& heightMask) + range(code1, code2) new (fidx, b:pos, e:pos) = range(fidx, b.Line, b.Column, e.Line, e.Column) - member r.StartLine = int32((code &&& startLineMask) >>> startLineShift) - member r.StartColumn = int32((code &&& startColumnMask) >>> startColumnShift) - member r.EndLine = int32((code &&& heightMask) >>> heightShift) + r.StartLine - member r.EndColumn = int32((code &&& endColumnMask) >>> endColumnShift) - member r.IsSynthetic = int32((code &&& isSyntheticMask) >>> isSyntheticShift) <> 0 + member r.StartLine = int32((code2 &&& startLineMask) >>> startLineShift) + + member r.StartColumn = int32((code1 &&& startColumnMask) >>> startColumnShift) + + member r.EndLine = int32((code2 &&& heightMask) >>> heightShift) + r.StartLine + + member r.EndColumn = int32((code1 &&& endColumnMask) >>> endColumnShift) + + member r.IsSynthetic = int32((code2 &&& isSyntheticMask) >>> isSyntheticShift) <> 0 + member r.Start = pos (r.StartLine, r.StartColumn) + member r.End = pos (r.EndLine, r.EndColumn) - member r.FileIndex = int32(code &&& fileIndexMask) + + member r.FileIndex = int32(code1 &&& fileIndexMask) + member m.StartRange = range (m.FileIndex, m.Start, m.Start) + member m.EndRange = range (m.FileIndex, m.End, m.End) + member r.FileName = fileOfFileIndex r.FileIndex + + member r.MakeSynthetic() = range(code1, code2 ||| isSyntheticMask) + + member r.Code1 = code1 + + member r.Code2 = code2 + #if DEBUG member r.DebugCode = try @@ -182,37 +260,37 @@ type range(code:int64) = with e -> e.ToString() #endif - member r.MakeSynthetic() = range(code ||| isSyntheticMask) - override r.ToString() = sprintf "%s (%d,%d--%d,%d) IsSynthetic=%b" r.FileName r.StartLine r.StartColumn r.EndLine r.EndColumn r.IsSynthetic + member r.ToShortString() = sprintf "(%d,%d--%d,%d)" r.StartLine r.StartColumn r.EndLine r.EndColumn - member r.Code = code - override r.Equals(obj) = match obj with :? range as r2 -> code = r2.Code | _ -> false - override r.GetHashCode() = hash code -let mkRange f b e = - // remove relative parts from full path - let normalizedFilePath = if Path.IsPathRooted f then try Path.GetFullPath f with _ -> f else f - range (fileIndexOfFile normalizedFilePath, b, e) + override r.Equals(obj) = match obj with :? range as r2 -> code1 = r2.Code1 && code2 = r2.Code2 | _ -> false + + override r.GetHashCode() = hash code1 + hash code2 + + override r.ToString() = sprintf "%s (%d,%d--%d,%d) IsSynthetic=%b" r.FileName r.StartLine r.StartColumn r.EndLine r.EndColumn r.IsSynthetic -let mkFileIndexRange fi b e = range (fi, b, e) +let mkRange filePath startPos endPos = range (fileIndexOfFileAux true filePath, startPos, endPos) + +let mkFileIndexRange fileIndex startPos endPos = range (fileIndex, startPos, endPos) -(* end representation, start derived ops *) - let posOrder = Order.orderOn (fun (p:pos) -> p.Line, p.Column) (Pair.order (Int32.order, Int32.order)) -(* rangeOrder: not a total order, but enough to sort on ranges *) + +/// rangeOrder: not a total order, but enough to sort on ranges let rangeOrder = Order.orderOn (fun (r:range) -> r.FileName, r.Start) (Pair.order (String.order, posOrder)) let outputPos (os:TextWriter) (m:pos) = fprintf os "(%d,%d)" m.Line m.Column + let outputRange (os:TextWriter) (m:range) = fprintf os "%s%a-%a" m.FileName outputPos m.Start outputPos m.End -let boutputPos os (m:pos) = bprintf os "(%d,%d)" m.Line m.Column -let boutputRange os (m:range) = bprintf os "%s%a-%a" m.FileName boutputPos m.Start boutputPos m.End let posGt (p1:pos) (p2:pos) = (p1.Line > p2.Line || (p1.Line = p2.Line && p1.Column > p2.Column)) + let posEq (p1:pos) (p2:pos) = (p1.Line = p2.Line && p1.Column = p2.Column) + let posGeq p1 p2 = posEq p1 p2 || posGt p1 p2 + let posLt p1 p2 = posGt p2 p1 -// This is deliberately written in an allocation-free way, i.e. m1.Start, m1.End etc. are not called +/// This is deliberately written in an allocation-free way, i.e. m1.Start, m1.End etc. are not called let unionRanges (m1:range) (m2:range) = if m1.FileIndex <> m2.FileIndex then m2 else let b = @@ -236,9 +314,13 @@ let rangeBeforePos (m1:range) p = posGeq p m1.End let rangeN filename line = mkRange filename (mkPos line 0) (mkPos line 0) + let pos0 = mkPos 1 0 + let range0 = rangeN "unknown" 1 + let rangeStartup = rangeN "startup" 1 + let rangeCmdArgs = rangeN "commandLineArgs" 0 let trimRangeToLine (r:range) = @@ -252,6 +334,7 @@ let trimRangeToLine (r:range) = (* For Diagnostics *) let stringOfPos (pos:pos) = sprintf "(%d,%d)" pos.Line pos.Column + let stringOfRange (r:range) = sprintf "%s%s-%s" r.FileName (stringOfPos r.Start) (stringOfPos r.End) #if CHECK_LINE0_TYPES // turn on to check that we correctly transform zero-based line counts to one-based line counts @@ -266,17 +349,22 @@ type Pos01 = Line0 * int type Range01 = Pos01 * Pos01 module Line = + // Visual Studio uses line counts starting at 0, F# uses them starting at 1 let fromZ (line:Line0) = int line+1 + let toZ (line:int) : Line0 = LanguagePrimitives.Int32WithMeasure(line - 1) module Pos = + let fromZ (line:Line0) idx = mkPos (Line.fromZ line) idx - let toZ (p:pos) = (Line.toZ p.Line, p.Column) + let toZ (p:pos) = (Line.toZ p.Line, p.Column) module Range = + let toZ (m:range) = Pos.toZ m.Start, Pos.toZ m.End + let toFileZ (m:range) = m.FileName, toZ m diff --git a/src/fsharp/range.fsi b/src/fsharp/range.fsi index c3805f4659..d4ef8be800 100755 --- a/src/fsharp/range.fsi +++ b/src/fsharp/range.fsi @@ -10,44 +10,86 @@ open Microsoft.FSharp.Compiler.AbstractIL.Internal open Microsoft.FSharp.Compiler -(* we keep a global tables of filenames that we can reference by integers *) +/// An index into a global tables of filenames type FileIndex = int32 -val fileIndexOfFile : string -> FileIndex + +/// Convert a file path to an index +val fileIndexOfFile : filePath: string -> FileIndex + +/// Convert an index into a file path val fileOfFileIndex : FileIndex -> string +/// Represents a position in a file [] type pos = + + /// The line number for the position member Line : int + + /// The column number for the position member Column : int - member Encoding : int32 - static member Decode : int32 -> pos + /// The encoding of the position as a 64-bit integer + member Encoding : int64 + + /// Decode a position fro a 64-bit integer + static member Decode : int64 -> pos + /// The maximum number of bits needed to store an encoded position - static member EncodingSize : int32 + static member EncodingSize : int /// Create a position for the given line and column val mkPos : line:int -> column:int -> pos +/// Ordering on positions val posOrder : IComparer +/// Represents a range within a known file [] type range = + + /// The start line of the range member StartLine : int + + /// The start column of the range member StartColumn : int + + /// The line number for the end position of the range member EndLine : int + + /// The column number for the end position of the range member EndColumn : int + + /// The start position of the range member Start : pos + + /// The end position of the range member End : pos + + /// The empty range that is located at the start position of the range member StartRange: range + + /// The empty range that is located at the end position of the range member EndRange: range + + /// The file index for the range member FileIndex : int + + /// The file name for the file of the range member FileName : string + /// Synthetic marks ranges which are produced by intermediate compilation phases. This /// bit signifies that the range covers something that should not be visible to language /// service operations like dot-completion. member IsSynthetic : bool + + /// Convert a range to be synthetic member MakeSynthetic : unit -> range + + /// Convert a range to string member ToShortString : unit -> string + + /// The range where all values are zero static member Zero : range /// This view of range marks uses file indexes explicitly @@ -56,34 +98,61 @@ val mkFileIndexRange : FileIndex -> pos -> pos -> range /// This view hides the use of file indexes and just uses filenames val mkRange : string -> pos -> pos -> range +/// Reduce a range so it only covers a line val trimRangeToLine : range -> range /// not a total order, but enough to sort on ranges val rangeOrder : IComparer +/// Output a position val outputPos : System.IO.TextWriter -> pos -> unit + +/// Output a range val outputRange : System.IO.TextWriter -> range -> unit -val boutputPos : StringBuilder -> pos -> unit -val boutputRange : StringBuilder -> range -> unit +/// Compare positions for less-than val posLt : pos -> pos -> bool + +/// Compare positions for greater-than val posGt : pos -> pos -> bool + +/// Compare positions for equality val posEq : pos -> pos -> bool + +/// Compare positions for greater-than-or-equal-to val posGeq : pos -> pos -> bool +/// Union two ranges, taking their first occurring start position and last occurring end position val unionRanges : range -> range -> range + +/// Test to see if one range contains another range val rangeContainsRange : range -> range -> bool + +/// Test to see if a range contains a position val rangeContainsPos : range -> pos -> bool + +/// Test to see if a range occurs fully before a position val rangeBeforePos : range -> pos -> bool +/// Make a dummy range for a file val rangeN : string -> int -> range + +/// The zero position val pos0 : pos + +/// The zero range val range0 : range + +/// A range associated with a dummy file called "startup" val rangeStartup : range + +/// A range associated with a dummy file for the command line arguments val rangeCmdArgs : range -(* For diagnostics *) +/// Convert a position to a string val stringOfPos : pos -> string + +/// Convert a range to a string val stringOfRange : range -> string /// Represents a line number when using zero-based line counting (used by Visual Studio) @@ -98,22 +167,30 @@ type Line0 = int /// Represents a position using zero-based line counting (used by Visual Studio) type Pos01 = Line0 * int + /// Represents a range using zero-based line counting (used by Visual Studio) type Range01 = Pos01 * Pos01 module Line = + /// Convert a line number from zero-based line counting (used by Visual Studio) to one-based line counting (used internally in the F# compiler and in F# error messages) val fromZ : Line0 -> int + /// Convert a line number from one-based line counting (used internally in the F# compiler and in F# error messages) to zero-based line counting (used by Visual Studio) val toZ : int -> Line0 module Pos = + /// Convert a position from zero-based line counting (used by Visual Studio) to one-based line counting (used internally in the F# compiler and in F# error messages) val fromZ : line:Line0 -> column:int -> pos + /// Convert a position from one-based line counting (used internally in the F# compiler and in F# error messages) to zero-based line counting (used by Visual Studio) val toZ : pos -> Pos01 module Range = + /// Convert a range from one-based line counting (used internally in the F# compiler and in F# error messages) to zero-based line counting (used by Visual Studio) val toZ : range -> Range01 + + /// Convert a range from one-based line counting (used internally in the F# compiler and in F# error messages) to zero-based line counting (used by Visual Studio) val toFileZ : range -> string * Range01 diff --git a/src/fsharp/service/IncrementalBuild.fs b/src/fsharp/service/IncrementalBuild.fs index 7065d72a6f..f5d0141b32 100755 --- a/src/fsharp/service/IncrementalBuild.fs +++ b/src/fsharp/service/IncrementalBuild.fs @@ -55,15 +55,16 @@ module internal IncrementalBuild = /// Get the Id for the given ScalarBuildRule. member x.Id = match x with - | ScalarInput(id, _) ->id - | ScalarDemultiplex(id, _, _, _) ->id - | ScalarMap(id, _, _, _) ->id + | ScalarInput(id, _) -> id + | ScalarDemultiplex(id, _, _, _) -> id + | ScalarMap(id, _, _, _) -> id + /// Get the Name for the givenScalarExpr. member x.Name = match x with - | ScalarInput(_, n) ->n - | ScalarDemultiplex(_, n, _, _) ->n - | ScalarMap(_, n, _, _) ->n + | ScalarInput(_, n) -> n + | ScalarDemultiplex(_, n, _, _) -> n + | ScalarMap(_, n, _, _) -> n /// A build rule with a vector of outputs and VectorBuildRule = @@ -1034,6 +1035,7 @@ type TypeCheckAccumulator = /// Accumulated 'open' declarations, last file first tcOpenDeclarationsRev: OpenDeclaration[] list + topAttribs:TopAttribs option /// Result of checking most recent file, if any @@ -1043,6 +1045,9 @@ type TypeCheckAccumulator = tcDependencyFiles: string list + /// Disambiguation table for module names + tcModuleNamesDict: ModuleNamesDict + /// Accumulated errors, last file first tcErrorsRev:(PhasedDiagnostic * FSharpErrorSeverity)[] list } @@ -1125,10 +1130,17 @@ type PartialCheckResults = /// Kept in a stack so that each incremental update shares storage with previous files TcOpenDeclarationsRev: OpenDeclaration[] list + /// Disambiguation table for module names + ModuleNamesDict: ModuleNamesDict + TcDependencyFiles: string list + TopAttribs: TopAttribs option + TimeStamp: DateTime + LatestImplementationFile: TypedImplFile option + LastestCcuSigForFile: ModuleOrNamespaceType option } member x.TcErrors = Array.concat (List.rev x.TcErrorsRev) @@ -1146,6 +1158,7 @@ type PartialCheckResults = TcOpenDeclarationsRev = tcAcc.tcOpenDeclarationsRev TcDependencyFiles = tcAcc.tcDependencyFiles TopAttribs = tcAcc.topAttribs + ModuleNamesDict = tcAcc.tcModuleNamesDict TimeStamp = timestamp LatestImplementationFile = tcAcc.latestImplFile LastestCcuSigForFile = tcAcc.latestCcuSigForFile } @@ -1175,7 +1188,9 @@ type RawFSharpAssemblyDataBackedByLanguageService (tcConfig, tcGlobals, tcState: yield (ccuName, (fun () -> r.GetBytes())) ] let autoOpenAttrs = topAttrs.assemblyAttrs |> List.choose (List.singleton >> TryFindFSharpStringAttribute tcGlobals tcGlobals.attrib_AutoOpenAttribute) + let ivtAttrs = topAttrs.assemblyAttrs |> List.choose (List.singleton >> TryFindFSharpStringAttribute tcGlobals tcGlobals.attrib_InternalsVisibleToAttribute) + interface IRawFSharpAssemblyData with member __.GetAutoOpenAttributes(_ilg) = autoOpenAttrs member __.GetInternalsVisibleToAttributes(_ilg) = ivtAttrs @@ -1246,6 +1261,7 @@ type IncrementalBuilder(tcGlobals, frameworkTcImports, nonFrameworkAssemblyInput let assertNotDisposed() = if disposed then System.Diagnostics.Debug.Assert(false, "IncrementalBuild object has already been disposed!") + let mutable referenceCount = 0 //---------------------------------------------------- @@ -1258,14 +1274,9 @@ type IncrementalBuilder(tcGlobals, frameworkTcImports, nonFrameworkAssemblyInput assertNotDisposed() cache.GetFileTimeStamp filename - // Deduplicate module names - let moduleNamesDict = ConcurrentDictionary>() - /// This is a build task function that gets placed into the build rules as the computation for a VectorMap /// - /// Parse the given files and return the given inputs. This function is expected to be - /// able to be called with a subset of sourceFiles and return the corresponding subset of - /// parsed inputs. + /// Parse the given file and return the given input. let ParseTask ctok (sourceRange:range, filename:string, isLastCompiland) = assertNotDisposed() DoesNotRequireCompilerThreadTokenAndCouldPossiblyBeMadeConcurrent ctok @@ -1278,12 +1289,12 @@ type IncrementalBuilder(tcGlobals, frameworkTcImports, nonFrameworkAssemblyInput IncrementalBuilderEventTesting.MRU.Add(IncrementalBuilderEventTesting.IBEParsed filename) let input = ParseOneInputFile(tcConfig, lexResourceManager, [], filename , isLastCompiland, errorLogger, (*retryLocked*)true) fileParsed.Trigger (filename) - let result = Option.map (DeduplicateParsedInputModuleName moduleNamesDict) input - result, sourceRange, filename, errorLogger.GetErrors () + input, sourceRange, filename, errorLogger.GetErrors () with exn -> - System.Diagnostics.Debug.Assert(false, sprintf "unexpected failure in IncrementalFSharpBuild.Parse\nerror = %s" (exn.ToString())) - failwith "last chance failure" + let msg = sprintf "unexpected failure in IncrementalFSharpBuild.Parse\nerror = %s" (exn.ToString()) + System.Diagnostics.Debug.Assert(false, msg) + failwith msg /// This is a build task function that gets placed into the build rules as the computation for a Vector.Stamp @@ -1356,7 +1367,8 @@ type IncrementalBuilder(tcGlobals, frameworkTcImports, nonFrameworkAssemblyInput latestImplFile=None latestCcuSigForFile=None tcDependencyFiles=basicDependencies - tcErrorsRev = [ initialErrors ] } + tcErrorsRev = [ initialErrors ] + tcModuleNamesDict = Map.empty } return tcAcc } /// This is a build task function that gets placed into the build rules as the computation for a Vector.ScanLeft @@ -1377,6 +1389,8 @@ type IncrementalBuilder(tcGlobals, frameworkTcImports, nonFrameworkAssemblyInput let sink = TcResultsSinkImpl(tcAcc.tcGlobals) let hadParseErrors = not (Array.isEmpty parseErrors) + let input, moduleNamesDict = DeduplicateParsedInputModuleName tcAcc.tcModuleNamesDict input + let! (tcEnvAtEndOfFile, topAttribs, implFile, ccuSigForFile), tcState = TypeCheckOneInputEventually ((fun () -> hadParseErrors || errorLogger.ErrorCount > 0), @@ -1405,6 +1419,7 @@ type IncrementalBuilder(tcGlobals, frameworkTcImports, nonFrameworkAssemblyInput tcSymbolUsesRev=tcSymbolUses :: tcAcc.tcSymbolUsesRev tcOpenDeclarationsRev = sink.GetOpenDeclarations() :: tcAcc.tcOpenDeclarationsRev tcErrorsRev = newErrors :: tcAcc.tcErrorsRev + tcModuleNamesDict = moduleNamesDict tcDependencyFiles = filename :: tcAcc.tcDependencyFiles } } @@ -1447,55 +1462,55 @@ type IncrementalBuilder(tcGlobals, frameworkTcImports, nonFrameworkAssemblyInput TypeCheckMultipleInputsFinish (results, finalAcc.tcState) let ilAssemRef, tcAssemblyDataOpt, tcAssemblyExprOpt = - try - // TypeCheckClosedInputSetFinish fills in tcState.Ccu but in incremental scenarios we don't want this, - // so we make this temporary here - let oldContents = tcState.Ccu.Deref.Contents - try - let tcState, tcAssemblyExpr = TypeCheckClosedInputSetFinish (mimpls, tcState) - - // Compute the identity of the generated assembly based on attributes, options etc. - // Some of this is duplicated from fsc.fs - let ilAssemRef = - let publicKey = - try - let signingInfo = Driver.ValidateKeySigningAttributes (tcConfig, tcGlobals, topAttrs) - match Driver.GetStrongNameSigner signingInfo with - | None -> None - | Some s -> Some (PublicKey.KeyAsToken(s.PublicKey)) - with e -> - errorRecoveryNoRange e - None - let locale = TryFindFSharpStringAttribute tcGlobals (tcGlobals.FindSysAttrib "System.Reflection.AssemblyCultureAttribute") topAttrs.assemblyAttrs - let assemVerFromAttrib = - TryFindFSharpStringAttribute tcGlobals (tcGlobals.FindSysAttrib "System.Reflection.AssemblyVersionAttribute") topAttrs.assemblyAttrs - |> Option.bind (fun v -> try Some (parseILVersion v) with _ -> None) - let ver = - match assemVerFromAttrib with - | None -> tcConfig.version.GetVersionInfo(tcConfig.implicitIncludeDir) - | Some v -> v - ILAssemblyRef.Create(assemblyName, None, publicKey, false, Some ver, locale) - - let tcAssemblyDataOpt = + try + // TypeCheckClosedInputSetFinish fills in tcState.Ccu but in incremental scenarios we don't want this, + // so we make this temporary here + let oldContents = tcState.Ccu.Deref.Contents try - // Assemblies containing type provider components can not successfully be used via cross-assembly references. - // We return 'None' for the assembly portion of the cross-assembly reference - let hasTypeProviderAssemblyAttrib = - topAttrs.assemblyAttrs |> List.exists (fun (Attrib(tcref, _, _, _, _, _, _)) -> tcref.CompiledRepresentationForNamedType.BasicQualifiedName = typeof.FullName) - if tcState.CreatesGeneratedProvidedTypes || hasTypeProviderAssemblyAttrib then - None - else - Some (RawFSharpAssemblyDataBackedByLanguageService (tcConfig, tcGlobals, tcState, outfile, topAttrs, assemblyName, ilAssemRef) :> IRawFSharpAssemblyData) - - with e -> - errorRecoveryNoRange e - None - ilAssemRef, tcAssemblyDataOpt, Some tcAssemblyExpr - finally - tcState.Ccu.Deref.Contents <- oldContents - with e -> - errorRecoveryNoRange e - mkSimpleAssRef assemblyName, None, None + let tcState, tcAssemblyExpr = TypeCheckClosedInputSetFinish (mimpls, tcState) + + // Compute the identity of the generated assembly based on attributes, options etc. + // Some of this is duplicated from fsc.fs + let ilAssemRef = + let publicKey = + try + let signingInfo = Driver.ValidateKeySigningAttributes (tcConfig, tcGlobals, topAttrs) + match Driver.GetStrongNameSigner signingInfo with + | None -> None + | Some s -> Some (PublicKey.KeyAsToken(s.PublicKey)) + with e -> + errorRecoveryNoRange e + None + let locale = TryFindFSharpStringAttribute tcGlobals (tcGlobals.FindSysAttrib "System.Reflection.AssemblyCultureAttribute") topAttrs.assemblyAttrs + let assemVerFromAttrib = + TryFindFSharpStringAttribute tcGlobals (tcGlobals.FindSysAttrib "System.Reflection.AssemblyVersionAttribute") topAttrs.assemblyAttrs + |> Option.bind (fun v -> try Some (parseILVersion v) with _ -> None) + let ver = + match assemVerFromAttrib with + | None -> tcConfig.version.GetVersionInfo(tcConfig.implicitIncludeDir) + | Some v -> v + ILAssemblyRef.Create(assemblyName, None, publicKey, false, Some ver, locale) + + let tcAssemblyDataOpt = + try + // Assemblies containing type provider components can not successfully be used via cross-assembly references. + // We return 'None' for the assembly portion of the cross-assembly reference + let hasTypeProviderAssemblyAttrib = + topAttrs.assemblyAttrs |> List.exists (fun (Attrib(tcref, _, _, _, _, _, _)) -> tcref.CompiledRepresentationForNamedType.BasicQualifiedName = typeof.FullName) + if tcState.CreatesGeneratedProvidedTypes || hasTypeProviderAssemblyAttrib then + None + else + Some (RawFSharpAssemblyDataBackedByLanguageService (tcConfig, tcGlobals, tcState, outfile, topAttrs, assemblyName, ilAssemRef) :> IRawFSharpAssemblyData) + + with e -> + errorRecoveryNoRange e + None + ilAssemRef, tcAssemblyDataOpt, Some tcAssemblyExpr + finally + tcState.Ccu.Deref.Contents <- oldContents + with e -> + errorRecoveryNoRange e + mkSimpleAssemblyRef assemblyName, None, None let finalAccWithErrors = { finalAcc with @@ -1560,9 +1575,9 @@ type IncrementalBuilder(tcGlobals, frameworkTcImports, nonFrameworkAssemblyInput member this.IncrementUsageCount() = assertNotDisposed() System.Threading.Interlocked.Increment(&referenceCount) |> ignore - { new System.IDisposable with member x.Dispose() = this.DecrementUsageCount() } + { new System.IDisposable with member __.Dispose() = this.DecrementUsageCount() } - member this.DecrementUsageCount() = + member __.DecrementUsageCount() = assertNotDisposed() let currentValue = System.Threading.Interlocked.Decrement(&referenceCount) if currentValue = 0 then @@ -1572,11 +1587,17 @@ type IncrementalBuilder(tcGlobals, frameworkTcImports, nonFrameworkAssemblyInput member __.IsAlive = referenceCount > 0 member __.TcConfig = tcConfig + member __.FileParsed = fileParsed.Publish + member __.BeforeFileChecked = beforeFileChecked.Publish + member __.FileChecked = fileChecked.Publish + member __.ProjectChecked = projectChecked.Publish + member __.ImportedCcusInvalidated = importsInvalidated.Publish + member __.AllDependenciesDeprecated = allDependencies #if !NO_EXTENSIONTYPING @@ -1621,7 +1642,7 @@ type IncrementalBuilder(tcGlobals, frameworkTcImports, nonFrameworkAssemblyInput | (*first file*) 0 -> IncrementalBuild.IsReady cache (Target(initialTcAccNode, None)) partialBuild | _ -> IncrementalBuild.IsReady cache (Target(tcStatesNode, Some (slotOfFile-1))) partialBuild - member builder.GetCheckResultsBeforeSlotInProject (ctok: CompilationThreadToken, slotOfFile) = + member __.GetCheckResultsBeforeSlotInProject (ctok: CompilationThreadToken, slotOfFile) = cancellable { let cache = TimeStampCache(defaultTimeStamp) let! result = @@ -1651,9 +1672,6 @@ type IncrementalBuilder(tcGlobals, frameworkTcImports, nonFrameworkAssemblyInput member builder.GetCheckResultsAfterLastFileInProject (ctok: CompilationThreadToken) = builder.GetCheckResultsBeforeSlotInProject(ctok, builder.GetSlotsCount()) - member builder.DeduplicateParsedInputModuleNameInProject (input) = - DeduplicateParsedInputModuleName moduleNamesDict input - member __.GetCheckResultsAndImplementationsForProject(ctok: CompilationThreadToken) = cancellable { let cache = TimeStampCache(defaultTimeStamp) @@ -1860,10 +1878,11 @@ type IncrementalBuilder(tcGlobals, frameworkTcImports, nonFrameworkAssemblyInput return builderOpt, diagnostics } + static member KeepBuilderAlive (builderOpt: IncrementalBuilder option) = match builderOpt with | Some builder -> builder.IncrementUsageCount() | None -> { new System.IDisposable with member __.Dispose() = () } - member builder.IsBeingKeptAliveApartFromCacheEntry = (referenceCount >= 2) + member __.IsBeingKeptAliveApartFromCacheEntry = (referenceCount >= 2) diff --git a/src/fsharp/service/IncrementalBuild.fsi b/src/fsharp/service/IncrementalBuild.fsi index b6b64a7ffd..29c7a03a45 100755 --- a/src/fsharp/service/IncrementalBuild.fsi +++ b/src/fsharp/service/IncrementalBuild.fsi @@ -55,6 +55,9 @@ type internal PartialCheckResults = /// Represents open declarations TcOpenDeclarationsRev: OpenDeclaration[] list + /// Disambiguation table for module names + ModuleNamesDict: ModuleNamesDict + TcDependencyFiles: string list /// Represents the collected attributes to apply to the module of assuembly generates @@ -151,8 +154,6 @@ type internal IncrementalBuilder = // TODO: make this an Eventually (which can be scheduled) or an Async (which can be cancelled) member GetCheckResultsAndImplementationsForProject : CompilationThreadToken -> Cancellable - member DeduplicateParsedInputModuleNameInProject: Ast.ParsedInput -> Ast.ParsedInput - /// Get the logical time stamp that is associated with the output of the project if it were gully built immediately member GetLogicalTimeStampForProject: TimeStampCache * CompilationThreadToken -> DateTime diff --git a/src/fsharp/service/ServiceAssemblyContent.fs b/src/fsharp/service/ServiceAssemblyContent.fs index a61f8f2b2f..663ed82a94 100644 --- a/src/fsharp/service/ServiceAssemblyContent.fs +++ b/src/fsharp/service/ServiceAssemblyContent.fs @@ -555,7 +555,7 @@ module ParsedInput = | SynTypeConstraint.WhereTyparSupportsMember (ts, sign, _) -> List.iter walkType ts; walkMemberSig sign and walkPat = function - | SynPat.Tuple (pats, _) + | SynPat.Tuple (_,pats, _) | SynPat.ArrayOrList (_, pats, _) | SynPat.Ands (pats, _) -> List.iter walkPat pats | SynPat.Named (pat, ident, _, _, _) -> @@ -603,7 +603,7 @@ module ParsedInput = | SynType.LongIdent ident -> addLongIdentWithDots ident | SynType.App (ty, _, types, _, _, _, _) -> walkType ty; List.iter walkType types | SynType.LongIdentApp (_, _, _, types, _, _, _) -> List.iter walkType types - | SynType.Tuple (ts, _) -> ts |> List.iter (fun (_, t) -> walkType t) + | SynType.Tuple (_, ts, _) -> ts |> List.iter (fun (_, t) -> walkType t) | SynType.WithGlobalConstraints (t, typeConstraints, _) -> walkType t; List.iter walkTypeConstraint typeConstraints | _ -> () @@ -641,7 +641,7 @@ module ParsedInput = | SynExpr.TypeTest (e, t, _) | SynExpr.Upcast (e, t, _) | SynExpr.Downcast (e, t, _) -> walkExpr e; walkType t - | SynExpr.Tuple (es, _, _) + | SynExpr.Tuple (_, es, _, _) | Sequentials es | SynExpr.ArrayOrList (_, es, _) -> List.iter walkExpr es | SynExpr.App (_, _, e1, e2, _) @@ -668,7 +668,7 @@ module ParsedInput = List.iter walkExpr [e1; e2] | SynExpr.MatchLambda (_, _, synMatchClauseList, _, _) -> List.iter walkClause synMatchClauseList - | SynExpr.Match (_, e, synMatchClauseList, _, _) -> + | SynExpr.Match (_, e, synMatchClauseList, _) -> walkExpr e List.iter walkClause synMatchClauseList | SynExpr.TypeApp (e, _, tys, _, _, _, _) -> @@ -914,8 +914,9 @@ module ParsedInput = let rec walkImplFileInput (ParsedImplFileInput(modules = moduleOrNamespaceList)) = List.iter (walkSynModuleOrNamespace []) moduleOrNamespaceList - and walkSynModuleOrNamespace (parent: LongIdent) (SynModuleOrNamespace(ident, _, isModule, decls, _, _, _, range)) = + and walkSynModuleOrNamespace (parent: LongIdent) (SynModuleOrNamespace(ident, _, kind, decls, _, _, _, range)) = if range.EndLine >= currentLine then + let isModule = kind.IsModule match isModule, parent, ident with | false, _, _ -> ns := Some (longIdentToIdents ident) // top level module with "inlined" namespace like Ns1.Ns2.TopModule @@ -1035,4 +1036,4 @@ module ParsedInput = | _ -> // we failed to find insertion point because ast is empty for some reason, return top left point in this case { ScopeKind = ScopeKind.TopModule - Pos = mkPos 1 0 } \ No newline at end of file + Pos = mkPos 1 0 } diff --git a/src/fsharp/service/ServiceDeclarationLists.fs b/src/fsharp/service/ServiceDeclarationLists.fs index 85d7249f61..22b851a5b8 100644 --- a/src/fsharp/service/ServiceDeclarationLists.fs +++ b/src/fsharp/service/ServiceDeclarationLists.fs @@ -28,7 +28,7 @@ open Microsoft.FSharp.Compiler.InfoReader module EnvMisc3 = /// dataTipSpinWaitTime limits how long we block the UI thread while a tooltip pops up next to a selected item in an IntelliSense completion list. /// This time appears to be somewhat amortized by the time it takes the VS completion UI to actually bring up the tooltip after selecting an item in the first place. - let dataTipSpinWaitTime = GetEnvInteger "FCS_ToolTipSpinWaitTime" 300 + let dataTipSpinWaitTime = GetEnvInteger "FCS_ToolTipSpinWaitTime" 5000 [] @@ -109,7 +109,7 @@ module internal DescriptionListsImpl = | Some id, true, ptyOpt -> let nm = id.idText // detect parameter type, if ptyOpt is None - this is .NET style optional argument - let pty = defaultArg ptyOpt pty + let pty = match ptyOpt with ValueSome x -> x | _ -> pty (nm, isOptArg, SepL.questionMark ^^ (wordL (TaggedTextOps.tagParameter nm))), pty // Layout an unnamed argument | None, _,_ -> @@ -204,13 +204,13 @@ module internal DescriptionListsImpl = let getPrettyParamsOfTypes() = let tau = vref.TauType match tryDestFunTy denv.g tau with - | Some(arg,rtau) -> + | ValueSome(arg,rtau) -> let args = tryDestRefTupleTy denv.g arg let _prettyTyparInst, prettyParams, prettyRetTyL, _prettyConstraintsL = PrettyParamsOfTypes g denv item.TyparInst args rtau // FUTURE: prettyTyparInst is the pretty version of the known instantiations of type parameters in the output. It could be returned // for display as part of the method group prettyParams, prettyRetTyL - | None -> + | _ -> let _prettyTyparInst, prettyTyL = NicePrint.prettyLayoutOfUncurriedSig denv item.TyparInst [] tau [], prettyTyL @@ -241,8 +241,8 @@ module internal DescriptionListsImpl = // Adjust the return type so it only strips the first argument let curriedRetTy = match tryDestFunTy denv.g vref.TauType with - | Some(_,rtau) -> rtau - | None -> lastRetTy + | ValueSome(_,rtau) -> rtau + | _ -> lastRetTy let _prettyTyparInst, prettyFirstCurriedParams, prettyCurriedRetTyL, prettyConstraintsL = PrettyParamsOfParamDatas g denv item.TyparInst firstCurriedParamDatas curriedRetTy @@ -283,6 +283,10 @@ module internal DescriptionListsImpl = let _prettyTyparInst, prettyRetTyL = NicePrint.prettyLayoutOfUncurriedSig denv item.TyparInst [] rfinfo.FieldType [], prettyRetTyL + | Item.AnonRecdField(_anonInfo,tys,i, _) -> + let _prettyTyparInst, prettyRetTyL = NicePrint.prettyLayoutOfUncurriedSig denv item.TyparInst [] tys.[i] + [], prettyRetTyL + | Item.ILField finfo -> let _prettyTyparInst, prettyRetTyL = NicePrint.prettyLayoutOfUncurriedSig denv item.TyparInst [] (finfo.FieldType(amap,m)) [], prettyRetTyL @@ -381,14 +385,14 @@ module internal DescriptionListsImpl = /// Find the glyph for the given type representation. let typeToGlyph ty = - if isAppTy denv.g ty then - let tcref = tcrefOfAppTy denv.g ty - tcref.TypeReprInfo |> reprToGlyph - elif isStructTupleTy denv.g ty then FSharpGlyph.Struct - elif isRefTupleTy denv.g ty then FSharpGlyph.Class - elif isFunction denv.g ty then FSharpGlyph.Delegate - elif isTyparTy denv.g ty then FSharpGlyph.Struct - else FSharpGlyph.Typedef + match tryDestAppTy denv.g ty with + | ValueSome tcref -> tcref.TypeReprInfo |> reprToGlyph + | _ -> + if isStructTupleTy denv.g ty then FSharpGlyph.Struct + elif isRefTupleTy denv.g ty then FSharpGlyph.Class + elif isFunction denv.g ty then FSharpGlyph.Delegate + elif isTyparTy denv.g ty then FSharpGlyph.Struct + else FSharpGlyph.Typedef // This may explore assemblies that are not in the reference set, // e.g. for type abbreviations to types not in the reference set. @@ -403,6 +407,7 @@ module internal DescriptionListsImpl = | Item.UnionCase _ | Item.ActivePatternCase _ -> FSharpGlyph.EnumMember | Item.ExnCase _ -> FSharpGlyph.Exception + | Item.AnonRecdField _ -> FSharpGlyph.Field | Item.RecdField _ -> FSharpGlyph.Field | Item.ILField _ -> FSharpGlyph.Field | Item.Event _ -> FSharpGlyph.Event diff --git a/src/fsharp/service/ServiceInterfaceStubGenerator.fs b/src/fsharp/service/ServiceInterfaceStubGenerator.fs index 5d093079f9..90a8ae4d7b 100644 --- a/src/fsharp/service/ServiceInterfaceStubGenerator.fs +++ b/src/fsharp/service/ServiceInterfaceStubGenerator.fs @@ -151,8 +151,8 @@ type internal InterfaceData = None | SynType.Anon _ -> Some "_" - | SynType.Tuple(ts, _) -> - Some (ts |> Seq.choose (snd >> (|TypeIdent|_|)) |> String.concat " * ") + | SynType.AnonRecd (_, ts, _) -> + Some (ts |> Seq.choose (snd >> (|TypeIdent|_|)) |> String.concat "; ") | SynType.Array(dimension, TypeIdent typeName, _) -> Some (sprintf "%s [%s]" typeName (new String(',', dimension-1))) | SynType.MeasurePower(TypeIdent typeName, RationalConst power, _) -> @@ -761,7 +761,7 @@ module internal InterfaceStubGenerator = | SynExpr.Typed(synExpr, _synType, _range) -> walkExpr synExpr - | SynExpr.Tuple(synExprList, _, _range) + | SynExpr.Tuple(_, synExprList, _, _range) | SynExpr.ArrayOrList(_, synExprList, _range) -> List.tryPick walkExpr synExprList @@ -802,7 +802,7 @@ module internal InterfaceStubGenerator = | SynExpr.MatchLambda(_isExnMatch, _argm, synMatchClauseList, _spBind, _wholem) -> synMatchClauseList |> List.tryPick (fun (Clause(_, _, e, _, _)) -> walkExpr e) - | SynExpr.Match(_sequencePointInfoForBinding, synExpr, synMatchClauseList, _, _range) -> + | SynExpr.Match(_sequencePointInfoForBinding, synExpr, synMatchClauseList, _range) -> walkExpr synExpr |> Option.orElse (synMatchClauseList |> List.tryPick (fun (Clause(_, _, e, _, _)) -> walkExpr e)) diff --git a/src/fsharp/service/ServiceLexing.fs b/src/fsharp/service/ServiceLexing.fs index 343fc20317..5eda7cb31d 100755 --- a/src/fsharp/service/ServiceLexing.fs +++ b/src/fsharp/service/ServiceLexing.fs @@ -242,16 +242,16 @@ module internal TokenClassifications = | RPAREN | RPAREN_COMING_SOON | RPAREN_IS_HERE -> (FSharpTokenColorKind.Punctuation,FSharpTokenCharKind.Delimiter, FSharpTokenTriggerClass.ParamEnd ||| FSharpTokenTriggerClass.MatchBraces) - | LBRACK_LESS | LBRACE_LESS + | LBRACK_LESS -> (FSharpTokenColorKind.Punctuation,FSharpTokenCharKind.Delimiter,FSharpTokenTriggerClass.None ) - | LQUOTE _ | LBRACK | LBRACE | LBRACK_BAR + | LQUOTE _ | LBRACK | LBRACE | LBRACK_BAR | LBRACE_BAR -> (FSharpTokenColorKind.Punctuation,FSharpTokenCharKind.Delimiter,FSharpTokenTriggerClass.MatchBraces ) - | GREATER_RBRACE | GREATER_RBRACK | GREATER_BAR_RBRACK + | GREATER_RBRACK | GREATER_BAR_RBRACK -> (FSharpTokenColorKind.Punctuation,FSharpTokenCharKind.Delimiter,FSharpTokenTriggerClass.None ) - | RQUOTE _ | RBRACK | RBRACE | RBRACE_COMING_SOON | RBRACE_IS_HERE | BAR_RBRACK + | RQUOTE _ | RBRACK | RBRACE | RBRACE_COMING_SOON | RBRACE_IS_HERE | BAR_RBRACK | BAR_RBRACE -> (FSharpTokenColorKind.Punctuation,FSharpTokenCharKind.Delimiter,FSharpTokenTriggerClass.MatchBraces ) | PUBLIC | PRIVATE | INTERNAL | BASE | GLOBAL @@ -307,7 +307,14 @@ module internal TestExpose = //---------------------------------------------------------------------------- // Lexer states encoded to/from integers //-------------------------------------------------------------------------- -type FSharpTokenizerLexState = int64 +[] +type FSharpTokenizerLexState = + { PosBits: int64 + OtherBits: int64 } + static member Initial = { PosBits = 0L; OtherBits = 0L } + member this.Equals (other: FSharpTokenizerLexState) = (this.PosBits = other.PosBits) && (this.OtherBits = other.OtherBits) + override this.Equals (obj: obj) = match obj with :? FSharpTokenizerLexState as other -> this.Equals(other) | _ -> false + override this.GetHashCode () = hash this.PosBits + hash this.OtherBits type FSharpTokenizerColorState = | Token = 1 @@ -323,7 +330,6 @@ type FSharpTokenizerColorState = | EndLineThenToken = 12 | TripleQuoteString = 13 | TripleQuoteStringInComment = 14 - | InitialState = 0 @@ -348,38 +354,38 @@ module internal LexerStateEncoding = // Note that this will discard all lexcont state, including the ifdefStack. let revertToDefaultLexCont = LexCont.Token [] - let resize32 (i:int32) : FSharpTokenizerLexState = int64 i - let lexstateNumBits = 4 - let ncommentsNumBits = 2 - let startPosNumBits = pos.EncodingSize + let ncommentsNumBits = 4 let hardwhiteNumBits = 1 - let ifdefstackCountNumBits = 4 - let ifdefstackNumBits = 16 // 0 means if, 1 means else + let ifdefstackCountNumBits = 8 + let ifdefstackNumBits = 24 // 0 means if, 1 means else let _ = assert (lexstateNumBits + ncommentsNumBits - + startPosNumBits + hardwhiteNumBits + ifdefstackCountNumBits + ifdefstackNumBits <= 64) let lexstateStart = 0 let ncommentsStart = lexstateNumBits - let startPosStart = lexstateNumBits+ncommentsNumBits - let hardwhitePosStart = lexstateNumBits+ncommentsNumBits+startPosNumBits - let ifdefstackCountStart = lexstateNumBits+ncommentsNumBits+startPosNumBits+hardwhiteNumBits - let ifdefstackStart = lexstateNumBits+ncommentsNumBits+startPosNumBits+hardwhiteNumBits+ifdefstackCountNumBits + let hardwhitePosStart = lexstateNumBits+ncommentsNumBits + let ifdefstackCountStart = lexstateNumBits+ncommentsNumBits+hardwhiteNumBits + let ifdefstackStart = lexstateNumBits+ncommentsNumBits+hardwhiteNumBits+ifdefstackCountNumBits let lexstateMask = Bits.mask64 lexstateStart lexstateNumBits let ncommentsMask = Bits.mask64 ncommentsStart ncommentsNumBits - let startPosMask = Bits.mask64 startPosStart startPosNumBits let hardwhitePosMask = Bits.mask64 hardwhitePosStart hardwhiteNumBits let ifdefstackCountMask = Bits.mask64 ifdefstackCountStart ifdefstackCountNumBits let ifdefstackMask = Bits.mask64 ifdefstackStart ifdefstackNumBits let bitOfBool b = if b then 1 else 0 let boolOfBit n = (n = 1L) - + + let inline colorStateOfLexState (state: FSharpTokenizerLexState) = + enum (int32 ((state.OtherBits &&& lexstateMask) >>> lexstateStart)) + + let inline lexStateOfColorState (state: FSharpTokenizerColorState) = + (int64 state <<< lexstateStart) &&& lexstateMask + let encodeLexCont (colorState:FSharpTokenizerColorState) ncomments (b:pos) ifdefStack light = let mutable ifdefStackCount = 0 let mutable ifdefStackBits = 0 @@ -390,43 +396,46 @@ module internal LexerStateEncoding = ifdefStackBits <- (ifdefStackBits ||| (1 <<< ifdefStackCount)) ifdefStackCount <- ifdefStackCount + 1 - let lexstate = int64 colorState - ((lexstate <<< lexstateStart) &&& lexstateMask) - ||| ((ncomments <<< ncommentsStart) &&& ncommentsMask) - ||| ((resize32 b.Encoding <<< startPosStart) &&& startPosMask) - ||| ((resize32 (bitOfBool light) <<< hardwhitePosStart) &&& hardwhitePosMask) - ||| ((resize32 ifdefStackCount <<< ifdefstackCountStart) &&& ifdefstackCountMask) - ||| ((resize32 ifdefStackBits <<< ifdefstackStart) &&& ifdefstackMask) + let bits = + lexStateOfColorState colorState + ||| ((ncomments <<< ncommentsStart) &&& ncommentsMask) + ||| ((int64 (bitOfBool light) <<< hardwhitePosStart) &&& hardwhitePosMask) + ||| ((int64 ifdefStackCount <<< ifdefstackCountStart) &&& ifdefstackCountMask) + ||| ((int64 ifdefStackBits <<< ifdefstackStart) &&& ifdefstackMask) + { PosBits = b.Encoding + OtherBits = bits } + let decodeLexCont (state:FSharpTokenizerLexState) = let mutable ifDefs = [] - let ifdefStackCount = (int32) ((state &&& ifdefstackCountMask) >>> ifdefstackCountStart) + let bits = state.OtherBits + let ifdefStackCount = (int32) ((bits &&& ifdefstackCountMask) >>> ifdefstackCountStart) if ifdefStackCount>0 then - let ifdefStack = (int32) ((state &&& ifdefstackMask) >>> ifdefstackStart) + let ifdefStack = (int32) ((bits &&& ifdefstackMask) >>> ifdefstackStart) for i in 1..ifdefStackCount do let bit = ifdefStackCount-i let mask = 1 <<< bit let ifDef = (if ifdefStack &&& mask = 0 then IfDefIf else IfDefElse) ifDefs<-(ifDef,range0)::ifDefs - enum (int32 ((state &&& lexstateMask) >>> lexstateStart)), - (int32) ((state &&& ncommentsMask) >>> ncommentsStart), - pos.Decode (int32 ((state &&& startPosMask) >>> startPosStart)), + colorStateOfLexState state, + int32 ((bits &&& ncommentsMask) >>> ncommentsStart), + pos.Decode state.PosBits, ifDefs, - boolOfBit ((state &&& hardwhitePosMask) >>> hardwhitePosStart) + boolOfBit ((bits &&& hardwhitePosMask) >>> hardwhitePosStart) let encodeLexInt lightSyntaxStatus (lexcont:LexerWhitespaceContinuation) = let tag,n1,p1,ifd = match lexcont with | LexCont.Token ifd -> FSharpTokenizerColorState.Token, 0L, pos0, ifd - | LexCont.IfDefSkip (ifd,n,m) -> FSharpTokenizerColorState.IfDefSkip, resize32 n, m.Start, ifd - | LexCont.EndLine(LexerEndlineContinuation.Skip(ifd,n,m)) -> FSharpTokenizerColorState.EndLineThenSkip, resize32 n, m.Start, ifd + | LexCont.IfDefSkip (ifd,n,m) -> FSharpTokenizerColorState.IfDefSkip, int64 n, m.Start, ifd + | LexCont.EndLine(LexerEndlineContinuation.Skip(ifd,n,m)) -> FSharpTokenizerColorState.EndLineThenSkip, int64 n, m.Start, ifd | LexCont.EndLine(LexerEndlineContinuation.Token(ifd)) -> FSharpTokenizerColorState.EndLineThenToken, 0L, pos0, ifd | LexCont.String (ifd,m) -> FSharpTokenizerColorState.String, 0L, m.Start, ifd - | LexCont.Comment (ifd,n,m) -> FSharpTokenizerColorState.Comment, resize32 n, m.Start, ifd - | LexCont.SingleLineComment (ifd,n,m) -> FSharpTokenizerColorState.SingleLineComment, resize32 n, m.Start, ifd - | LexCont.StringInComment (ifd,n,m) -> FSharpTokenizerColorState.StringInComment, resize32 n, m.Start, ifd - | LexCont.VerbatimStringInComment (ifd,n,m) -> FSharpTokenizerColorState.VerbatimStringInComment, resize32 n, m.Start, ifd - | LexCont.TripleQuoteStringInComment (ifd,n,m) -> FSharpTokenizerColorState.TripleQuoteStringInComment,resize32 n, m.Start, ifd + | LexCont.Comment (ifd,n,m) -> FSharpTokenizerColorState.Comment, int64 n, m.Start, ifd + | LexCont.SingleLineComment (ifd,n,m) -> FSharpTokenizerColorState.SingleLineComment, int64 n, m.Start, ifd + | LexCont.StringInComment (ifd,n,m) -> FSharpTokenizerColorState.StringInComment, int64 n, m.Start, ifd + | LexCont.VerbatimStringInComment (ifd,n,m) -> FSharpTokenizerColorState.VerbatimStringInComment, int64 n, m.Start, ifd + | LexCont.TripleQuoteStringInComment (ifd,n,m) -> FSharpTokenizerColorState.TripleQuoteStringInComment,int64 n, m.Start, ifd | LexCont.MLOnly (ifd,m) -> FSharpTokenizerColorState.CamlOnly, 0L, m.Start, ifd | LexCont.VerbatimString (ifd,m) -> FSharpTokenizerColorState.VerbatimString, 0L, m.Start, ifd | LexCont.TripleQuoteString (ifd,m) -> FSharpTokenizerColorState.TripleQuoteString, 0L, m.Start, ifd @@ -571,7 +580,7 @@ type FSharpLineTokenizer(lexbuf: UnicodeLexing.Lexbuf, | None -> lexbuf.EndPos <- Internal.Utilities.Text.Lexing.Position.Empty | Some(value) -> resetLexbufPos value lexbuf - member x.ScanToken(lexintInitial) : Option * FSharpTokenizerLexState = + member x.ScanToken(lexintInitial) : FSharpTokenInfo option * FSharpTokenizerLexState = use unwindBP = PushThreadBuildPhaseUntilUnwind BuildPhase.Parse use unwindEL = PushErrorLoggerPhaseUntilUnwind (fun _ -> DiscardErrorsLogger) @@ -740,19 +749,14 @@ type FSharpLineTokenizer(lexbuf: UnicodeLexing.Lexbuf, tokenDataOption, lexintFinal - static member ColorStateOfLexState (lexState: FSharpTokenizerLexState) = - let tag,_ncomments,_position,_ifdefStack,_lightSyntaxStatusInital = LexerStateEncoding.decodeLexCont lexState - tag + static member ColorStateOfLexState(lexState: FSharpTokenizerLexState) = + LexerStateEncoding.colorStateOfLexState lexState - static member LexStateOfColorState (colorState: FSharpTokenizerColorState) = - let ncomments = 0L - let position = pos0 - let ifdefStack = [] - let light = true - LexerStateEncoding.encodeLexCont colorState ncomments position ifdefStack light + static member LexStateOfColorState(colorState: FSharpTokenizerColorState) = + { PosBits = 0L; OtherBits = LexerStateEncoding.lexStateOfColorState colorState } [] -type FSharpSourceTokenizer(defineConstants : string list, filename : Option) = +type FSharpSourceTokenizer(defineConstants : string list, filename : string option) = let lexResourceManager = new Lexhelp.LexResourceManager() let lexArgsLightOn = mkLexargs(filename,defineConstants,LightSyntaxStatus(true,false),lexResourceManager, ref [],DiscardErrorsLogger) diff --git a/src/fsharp/service/ServiceLexing.fsi b/src/fsharp/service/ServiceLexing.fsi index 1501f45415..d354e452e1 100755 --- a/src/fsharp/service/ServiceLexing.fsi +++ b/src/fsharp/service/ServiceLexing.fsi @@ -8,7 +8,12 @@ type Position = int * int type Range = Position * Position /// Represents encoded information for the end-of-line continuation of lexing -type FSharpTokenizerLexState = int64 +[] +type FSharpTokenizerLexState = + { PosBits: int64 + OtherBits: int64 } + static member Initial : FSharpTokenizerLexState + member Equals : FSharpTokenizerLexState -> bool /// Represents stable information for the state of the laxing engine at the end of a line type FSharpTokenizerColorState = @@ -27,7 +32,6 @@ type FSharpTokenizerColorState = | TripleQuoteStringInComment = 14 | InitialState = 0 - /// Gives an indicattion of the color class to assign to the token an IDE type FSharpTokenColorKind = | Default = 0 @@ -193,21 +197,28 @@ module FSharpTokenTag = type FSharpTokenInfo = { /// Left column of the token. LeftColumn:int + /// Right column of the token. RightColumn:int + ColorClass:FSharpTokenColorKind + /// Gives an indication of the class to assign to the token an IDE CharClass:FSharpTokenCharKind + /// Actions taken when the token is typed FSharpTokenTriggerClass:FSharpTokenTriggerClass + /// The tag is an integer identifier for the token Tag:int + /// Provides additional information about the token TokenName:string; + /// The full length consumed by this match, including delayed tokens (which can be ignored in naive lexers) FullMatchedLength: int } -/// Object to tokenize a line of F# source code, starting with the given lexState. The lexState should be 0 for +/// Object to tokenize a line of F# source code, starting with the given lexState. The lexState should be FSharpTokenizerLexState.Initial for /// the first line of text. Returns an array of ranges of the text and two enumerations categorizing the /// tokens and characters covered by that range, i.e. FSharpTokenColorKind and FSharpTokenCharKind. The enumerations /// are somewhat adhoc but useful enough to give good colorization options to the user in an IDE. @@ -221,7 +232,6 @@ type FSharpLineTokenizer = static member ColorStateOfLexState : FSharpTokenizerLexState -> FSharpTokenizerColorState static member LexStateOfColorState : FSharpTokenizerColorState -> FSharpTokenizerLexState - /// Tokenizer for a source file. Holds some expensive-to-compute resources at the scope of the file. [] type FSharpSourceTokenizer = @@ -229,7 +239,6 @@ type FSharpSourceTokenizer = member CreateLineTokenizer : lineText:string -> FSharpLineTokenizer member CreateBufferTokenizer : bufferFiller:(char[] * int * int -> int) -> FSharpLineTokenizer - module internal TestExpose = val TokenInfo : Parser.token -> (FSharpTokenColorKind * FSharpTokenCharKind * FSharpTokenTriggerClass) diff --git a/src/fsharp/service/ServiceNavigation.fs b/src/fsharp/service/ServiceNavigation.fs index 24d83f532b..e0e1feb1b3 100755 --- a/src/fsharp/service/ServiceNavigation.fs +++ b/src/fsharp/service/ServiceNavigation.fs @@ -270,7 +270,7 @@ module NavigationImpl = let items = // Show base name for this module only if it's not the root one let singleTopLevel = (modules.Length = 1) - modules |> List.collect (fun (SynModuleOrNamespace(id, _isRec, isModule, decls, _, _, access, m)) -> + modules |> List.collect (fun (SynModuleOrNamespace(id, _isRec, kind, decls, _, _, access, m)) -> let baseName = if (not singleTopLevel) then textOfLid id else "" // Find let bindings (for the right dropdown) let nested = processNestedDeclarations(decls) @@ -283,7 +283,7 @@ module NavigationImpl = | _ -> let decl = FSharpNavigationDeclarationItem.Create - (textOfLid id, (if isModule then ModuleFileDecl else NamespaceDecl), + (textOfLid id, (if kind.IsModule then ModuleFileDecl else NamespaceDecl), FSharpGlyph.Module, m, unionRangesChecked (rangeOfDecls nested) (moduleRange (rangeOfLid id) other), singleTopLevel, FSharpEnclosingEntityKind.Module, false, access), (addItemName(textOfLid id)), nested @@ -410,7 +410,7 @@ module NavigationImpl = let items = // Show base name for this module only if it's not the root one let singleTopLevel = (modules.Length = 1) - modules |> List.collect (fun (SynModuleOrNamespaceSig(id, _isRec, isModule, decls, _, _, access, m)) -> + modules |> List.collect (fun (SynModuleOrNamespaceSig(id, _isRec, kind, decls, _, _, access, m)) -> let baseName = if (not singleTopLevel) then textOfLid id else "" // Find let bindings (for the right dropdown) let nested = processNestedSigDeclarations(decls) @@ -420,7 +420,7 @@ module NavigationImpl = // Create explicitly - it can be 'single top level' thing that is hidden let decl = FSharpNavigationDeclarationItem.Create - (textOfLid id, (if isModule then ModuleFileDecl else NamespaceDecl), + (textOfLid id, (if kind.IsModule then ModuleFileDecl else NamespaceDecl), FSharpGlyph.Module, m, unionRangesChecked (rangeOfDecls nested) (moduleRange (rangeOfLid id) other), singleTopLevel, FSharpEnclosingEntityKind.Module, false, access), (addItemName(textOfLid id)), nested @@ -574,7 +574,8 @@ module NavigateTo = for item in moduleOrNamespaceList do walkSynModuleOrNamespaceSig item { Type = ContainerType.File; Name = fileName } - and walkSynModuleOrNamespaceSig (SynModuleOrNamespaceSig(lid, _, isModule, decls, _, _, _, _)) container = + and walkSynModuleOrNamespaceSig (SynModuleOrNamespaceSig(lid, _, kind, decls, _, _, _, _)) container = + let isModule = kind.IsModule if isModule then addModule lid true container let container = @@ -631,7 +632,8 @@ module NavigateTo = for item in moduleOrNamespaceList do walkSynModuleOrNamespace item container - and walkSynModuleOrNamespace(SynModuleOrNamespace(lid, _, isModule, decls, _, _, _, _)) container = + and walkSynModuleOrNamespace(SynModuleOrNamespace(lid, _, kind, decls, _, _, _, _)) container = + let isModule = kind.IsModule if isModule then addModule lid false container let container = diff --git a/src/fsharp/service/ServiceParamInfoLocations.fs b/src/fsharp/service/ServiceParamInfoLocations.fs index 23681498fb..e0e9affd2d 100755 --- a/src/fsharp/service/ServiceParamInfoLocations.fs +++ b/src/fsharp/service/ServiceParamInfoLocations.fs @@ -96,7 +96,7 @@ module internal NoteworthyParamInfoLocationsImpl = // see bug 345385. let rec searchSynArgExpr traverseSynExpr pos expr = match expr with - | SynExprParen((SynExpr.Tuple(synExprList, commaRanges, _tupleRange) as synExpr), _lpRange, rpRangeOpt, parenRange) -> // tuple argument + | SynExprParen((SynExpr.Tuple(false, synExprList, commaRanges, _tupleRange) as synExpr), _lpRange, rpRangeOpt, parenRange) -> // tuple argument let inner = traverseSynExpr synExpr match inner with | None -> @@ -108,7 +108,7 @@ module internal NoteworthyParamInfoLocationsImpl = NotFound, None | _ -> NotFound, None - | SynExprParen(SynExprParen(SynExpr.Tuple(_, _, _), _, _, _) as synExpr, _, rpRangeOpt, parenRange) -> // f((x, y)) is special, single tuple arg + | SynExprParen(SynExprParen(SynExpr.Tuple(false, _, _, _), _, _, _) as synExpr, _, rpRangeOpt, parenRange) -> // f((x, y)) is special, single tuple arg handleSingleArg traverseSynExpr (pos, synExpr, parenRange, rpRangeOpt) // dig into multiple parens diff --git a/src/fsharp/service/ServiceParseTreeWalk.fs b/src/fsharp/service/ServiceParseTreeWalk.fs index 7f94652a18..14e08c9b2d 100755 --- a/src/fsharp/service/ServiceParseTreeWalk.fs +++ b/src/fsharp/service/ServiceParseTreeWalk.fs @@ -49,48 +49,63 @@ module public AstTraversal = /// traverseSynExpr(subExpr) to recurse deeper on some particular sub-expression based on your own logic /// path helps to track AST nodes that were passed during traversal abstract VisitExpr : TraversePath * (SynExpr -> 'T option) * (SynExpr -> 'T option) * SynExpr -> 'T option + /// VisitTypeAbbrev(ty,m), defaults to ignoring this leaf of the AST abstract VisitTypeAbbrev : SynType * range -> 'T option default this.VisitTypeAbbrev(_ty,_m) = None + /// VisitImplicitInherit(defaultTraverse,ty,expr,m), defaults to just visiting expr abstract VisitImplicitInherit : (SynExpr -> 'T option) * SynType * SynExpr * range -> 'T option default this.VisitImplicitInherit(defaultTraverse, _ty, expr, _m) = defaultTraverse expr + /// VisitModuleDecl allows overriding module declaration behavior abstract VisitModuleDecl : (SynModuleDecl -> 'T option) * SynModuleDecl -> 'T option default this.VisitModuleDecl(defaultTraverse, decl) = defaultTraverse decl + /// VisitBinding allows overriding binding behavior (note: by default it would defaultTraverse expression) abstract VisitBinding : (SynBinding -> 'T option) * SynBinding -> 'T option default this.VisitBinding(defaultTraverse, binding) = defaultTraverse binding + /// VisitMatchClause allows overriding clause behavior (note: by default it would defaultTraverse expression) abstract VisitMatchClause : (SynMatchClause -> 'T option) * SynMatchClause -> 'T option default this.VisitMatchClause(defaultTraverse, mc) = defaultTraverse mc + /// VisitInheritSynMemberDefn allows overriding inherit behavior (by default do nothing) abstract VisitInheritSynMemberDefn : SynComponentInfo * SynTypeDefnKind * SynType * SynMemberDefns * range -> 'T option default this.VisitInheritSynMemberDefn(_componentInfo, _typeDefnKind, _synType, _members, _range) = None + /// VisitInterfaceSynMemberDefnType allows overriding behavior for visiting interface member in types (by default - do nothing) abstract VisitInterfaceSynMemberDefnType : SynType -> 'T option default this.VisitInterfaceSynMemberDefnType(_synType) = None + /// VisitRecordField allows overriding behavior when visiting l.h.s. of constructed record instances abstract VisitRecordField : TraversePath * SynExpr option * LongIdentWithDots option -> 'T option default this.VisitRecordField (_path, _copyOpt, _recordField) = None + /// VisitHashDirective allows overriding behavior when visiting hash directives in FSX scripts, like #r, #load and #I. abstract VisitHashDirective : range -> 'T option default this.VisitHashDirective (_) = None + /// VisitModuleOrNamespace allows overriding behavior when visiting module or namespaces abstract VisitModuleOrNamespace : SynModuleOrNamespace -> 'T option default this.VisitModuleOrNamespace (_) = None + /// VisitComponentInfo allows overriding behavior when visiting type component infos abstract VisitComponentInfo : SynComponentInfo -> 'T option default this.VisitComponentInfo (_) = None + /// VisitLetOrUse allows overriding behavior when visiting module or local let or use bindings abstract VisitLetOrUse : TraversePath * (SynBinding -> 'T option) * SynBinding list * range -> 'T option default this.VisitLetOrUse (_, _, _, _) = None + /// VisitType allows overriding behavior when visiting simple pats abstract VisitSimplePats : SynSimplePat list -> 'T option default this.VisitSimplePats (_) = None + /// VisitPat allows overriding behavior when visiting patterns abstract VisitPat : (SynPat -> 'T option) * SynPat -> 'T option default this.VisitPat (defaultTraverse, pat) = defaultTraverse pat + /// VisitType allows overriding behavior when visiting type hints (x: ..., etc.) abstract VisitType : (SynType -> 'T option) * SynType -> 'T option default this.VisitType (defaultTraverse, ty) = defaultTraverse ty @@ -191,9 +206,25 @@ module public AstTraversal = |> pick expr | SynExpr.Const(_synConst, _range) -> None | SynExpr.Typed(synExpr, synType, _range) -> [ traverseSynExpr synExpr; traverseSynType synType ] |> List.tryPick id - | SynExpr.Tuple(synExprList, _, _range) - | SynExpr.StructTuple(synExprList, _, _range) -> synExprList |> List.map (fun x -> dive x x.Range traverseSynExpr) |> pick expr + | SynExpr.Tuple(_, synExprList, _, _range) | SynExpr.ArrayOrList(_, synExprList, _range) -> synExprList |> List.map (fun x -> dive x x.Range traverseSynExpr) |> pick expr + + | SynExpr.AnonRecd(_isStruct, copyOpt, synExprList, _range) -> + [ match copyOpt with + | Some(expr, (withRange, _)) -> + yield dive expr expr.Range traverseSynExpr + yield dive () withRange (fun () -> + if posGeq pos withRange.End then + // special case: caret is after WITH + // { x with $ } + visitor.VisitRecordField (path, Some expr, None) + else + None + ) + | _ -> () + for (_,x) in synExprList do + yield dive x x.Range traverseSynExpr + ] |> pick expr | SynExpr.Record(inheritOpt,copyOpt,fields, _range) -> [ let diveIntoSeparator offsideColumn scPosOpt copyOpt = @@ -346,7 +377,7 @@ module public AstTraversal = synMatchClauseList |> List.map (fun x -> dive x x.Range (traverseSynMatchClause path)) |> pick expr - | SynExpr.Match(_sequencePointInfoForBinding, synExpr, synMatchClauseList, _, _range) -> + | SynExpr.Match(_sequencePointInfoForBinding, synExpr, synMatchClauseList, _range) -> [yield dive synExpr synExpr.Range traverseSynExpr yield! synMatchClauseList |> List.map (fun x -> dive x x.RangeOfGuardAndRhs (traverseSynMatchClause path))] |> pick expr @@ -425,9 +456,12 @@ module public AstTraversal = dive synExpr2 synExpr2.Range traverseSynExpr dive synExpr3 synExpr3.Range traverseSynExpr] |> pick expr - | SynExpr.TypeTest(synExpr, _synType, _range) -> traverseSynExpr synExpr - | SynExpr.Upcast(synExpr, _synType, _range) -> traverseSynExpr synExpr - | SynExpr.Downcast(synExpr, _synType, _range) -> traverseSynExpr synExpr + | SynExpr.TypeTest(synExpr, synType, _range) + | SynExpr.Upcast(synExpr, synType, _range) + | SynExpr.Downcast(synExpr, synType, _range) -> + [dive synExpr synExpr.Range traverseSynExpr + dive synType synType.Range traverseSynType] + |> pick expr | SynExpr.InferredUpcast(synExpr, _range) -> traverseSynExpr synExpr | SynExpr.InferredDowncast(synExpr, _range) -> traverseSynExpr synExpr | SynExpr.Null(_range) -> None @@ -441,7 +475,7 @@ module public AstTraversal = dive synExpr synExpr.Range traverseSynExpr dive synExpr2 synExpr2.Range traverseSynExpr] |> pick expr - | SynExpr.MatchBang(_sequencePointInfoForBinding, synExpr, synMatchClauseList, _, _range) -> + | SynExpr.MatchBang(_sequencePointInfoForBinding, synExpr, synMatchClauseList, _range) -> [yield dive synExpr synExpr.Range traverseSynExpr yield! synMatchClauseList |> List.map (fun x -> dive x x.RangeOfGuardAndRhs (traverseSynMatchClause path))] |> pick expr @@ -462,8 +496,7 @@ module public AstTraversal = | SynPat.Paren (p, _) -> traversePat p | SynPat.Or (p1, p2, _) -> [ p1; p2] |> List.tryPick traversePat | SynPat.Ands (ps, _) - | SynPat.Tuple (ps, _) - | SynPat.StructTuple (ps, _) + | SynPat.Tuple (_, ps, _) | SynPat.ArrayOrList (_, ps, _) -> ps |> List.tryPick traversePat | SynPat.Attrib (p, _, _) -> traversePat p | SynPat.LongIdent(_, _, _, args, _, _) -> @@ -492,8 +525,7 @@ module public AstTraversal = | SynType.Array (_, ty, _) -> traverseSynType ty | SynType.StaticConstantNamed (ty1, ty2, _) | SynType.MeasureDivide (ty1, ty2, _) -> [ty1; ty2] |> List.tryPick traverseSynType - | SynType.Tuple (tys, _) - | SynType.StructTuple (tys, _) -> tys |> List.map snd |> List.tryPick traverseSynType + | SynType.Tuple (_, tys, _) -> tys |> List.map snd |> List.tryPick traverseSynType | SynType.StaticConstantExpr (expr, _) -> traverseSynExpr [] expr | SynType.Anon _ -> None | _ -> None diff --git a/src/fsharp/service/ServiceStructure.fs b/src/fsharp/service/ServiceStructure.fs index c86358c8f5..a89afd44c5 100644 --- a/src/fsharp/service/ServiceStructure.fs +++ b/src/fsharp/service/ServiceStructure.fs @@ -2,7 +2,6 @@ namespace Microsoft.FSharp.Compiler.SourceCodeServices -open System.Collections.Generic open Microsoft.FSharp.Compiler.AbstractIL.Internal.Library open Microsoft.FSharp.Compiler.Ast open Microsoft.FSharp.Compiler @@ -103,6 +102,7 @@ module Structure = | For | While | Match + | MatchBang | MatchLambda | MatchClause | Lambda @@ -151,6 +151,7 @@ module Structure = | For -> "For" | While -> "While" | Match -> "Match" + | MatchBang -> "MatchBang" | MatchLambda -> "MatchLambda" | MatchClause -> "MatchClause" | Lambda -> "Lambda" @@ -259,7 +260,8 @@ module Structure = | SynExpr.LetOrUse (_,_,bindings, body, _) -> parseBindings bindings parseExpr body - | SynExpr.Match (seqPointAtBinding,_expr,clauses,_,r) -> + | SynExpr.Match (seqPointAtBinding,_expr,clauses,r) + | SynExpr.MatchBang (seqPointAtBinding, _expr, clauses, r) -> match seqPointAtBinding with | SequencePointAtBinding sr -> let collapse = Range.endToEnd sr r @@ -376,8 +378,7 @@ module Structure = // subtract columns so the @@> or @> is not collapsed rcheck Scope.Quote Collapse.Same r (Range.modBoth (if isRaw then 3 else 2) (if isRaw then 3 else 2) r) parseExpr e - | SynExpr.Tuple (es,_,r) - | SynExpr.StructTuple(es,_,r) -> + | SynExpr.Tuple (_, es, _, r) -> rcheck Scope.Tuple Collapse.Same r r List.iter parseExpr es | SynExpr.Paren (e,_,_,_) -> @@ -609,14 +610,14 @@ module Structure = parseAttributes attrs | _ -> () - let parseModuleOrNamespace isScript (SynModuleOrNamespace (longId,_,isModule,decls,_,attribs,_,r)) = + let parseModuleOrNamespace (SynModuleOrNamespace (longId,_,kind,decls,_,attribs,_,r)) = parseAttributes attribs let idRange = longIdentRange longId let fullrange = Range.startToEnd idRange r let collapse = Range.endToEnd idRange r // do not return range for top level implicit module in scripts - if isModule && not isScript then + if kind = NamedModule then rcheck Scope.Module Collapse.Below fullrange collapse collectHashDirectives decls @@ -832,14 +833,14 @@ module Structure = List.iter parseModuleSigDeclaration decls | _ -> () - let parseModuleOrNamespaceSigs (SynModuleOrNamespaceSig(longId,_,isModule,decls,_,attribs,_,r)) = + let parseModuleOrNamespaceSigs (SynModuleOrNamespaceSig(longId,_,kind,decls,_,attribs,_,r)) = parseAttributes attribs let rangeEnd = lastModuleSigDeclRangeElse r decls let idrange = longIdentRange longId let fullrange = Range.startToEnd idrange rangeEnd let collapse = Range.endToEnd idrange rangeEnd - if isModule then + if kind.IsModule then rcheck Scope.Module Collapse.Below fullrange collapse collectSigHashDirectives decls @@ -847,11 +848,11 @@ module Structure = List.iter parseModuleSigDeclaration decls match parsedInput with - | ParsedInput.ImplFile (ParsedImplFileInput (modules = modules; isScript = isScript)) -> - modules |> List.iter (parseModuleOrNamespace isScript) + | ParsedInput.ImplFile (ParsedImplFileInput (modules = modules)) -> + modules |> List.iter parseModuleOrNamespace getCommentRanges sourceLines | ParsedInput.SigFile (ParsedSigFileInput (modules = moduleSigs)) -> List.iter parseModuleOrNamespaceSigs moduleSigs getCommentRanges sourceLines - acc :> seq<_> \ No newline at end of file + acc :> seq<_> diff --git a/src/fsharp/service/ServiceStructure.fsi b/src/fsharp/service/ServiceStructure.fsi index 96d5796e9b..a7a054a411 100644 --- a/src/fsharp/service/ServiceStructure.fsi +++ b/src/fsharp/service/ServiceStructure.fsi @@ -3,8 +3,6 @@ namespace Microsoft.FSharp.Compiler.SourceCodeServices open Microsoft.FSharp.Compiler.Ast -open System.Collections.Generic -open Microsoft.FSharp.Compiler open Microsoft.FSharp.Compiler.Range module public Structure = @@ -42,6 +40,7 @@ module public Structure = | For | While | Match + | MatchBang | MatchLambda | MatchClause | Lambda diff --git a/src/fsharp/service/ServiceUntypedParse.fs b/src/fsharp/service/ServiceUntypedParse.fs index 18cb8023de..62c8892331 100755 --- a/src/fsharp/service/ServiceUntypedParse.fs +++ b/src/fsharp/service/ServiceUntypedParse.fs @@ -219,15 +219,20 @@ type FSharpParseFileResults(errors: FSharpErrorInfo[], input: Ast.ParsedInput op yield! walkExpr false e2 | SynExpr.ArrayOrList (_,es,_) - | SynExpr.Tuple (es,_,_) - | SynExpr.StructTuple (es,_,_) -> + | SynExpr.Tuple (_,es,_,_) -> yield! walkExprs es | SynExpr.Record (_,copyExprOpt,fs,_) -> match copyExprOpt with | Some (e,_) -> yield! walkExpr true e | None -> () - yield! walkExprs (List.map (fun (_, v, _) -> v) fs |> List.choose id) + yield! walkExprs (fs |> List.choose p23) + + | SynExpr.AnonRecd (_isStruct, copyExprOpt, fs, _) -> + match copyExprOpt with + | Some (e,_) -> yield! walkExpr true e + | None -> () + yield! walkExprs (fs |> List.map snd) | SynExpr.ObjExpr (_,args,bs,is,_,_) -> match args with @@ -265,7 +270,7 @@ type FSharpParseFileResults(errors: FSharpErrorInfo[], input: Ast.ParsedInput op | SynExpr.Lambda (_,_,_,e,_) -> yield! walkExpr true e - | SynExpr.Match (spBind,e,cl,_,_) -> + | SynExpr.Match (spBind,e,cl,_) -> yield! walkBindSeqPt spBind yield! walkExpr false e for (Clause(_,whenExpr,e,_,_)) in cl do @@ -317,7 +322,7 @@ type FSharpParseFileResults(errors: FSharpErrorInfo[], input: Ast.ParsedInput op yield! walkExpr true e1 yield! walkExpr true e2 - | SynExpr.MatchBang (spBind,e,cl,_,_) -> + | SynExpr.MatchBang (spBind,e,cl,_) -> yield! walkBindSeqPt spBind yield! walkExpr false e for (Clause(_,whenExpr,e,_,_)) in cl do @@ -758,7 +763,7 @@ module UntypedParseImpl = List.tryPick walkTyparDecl typars |> Option.orElse (List.tryPick walkTypeConstraint constraints))) |> Option.orElse (List.tryPick walkPat pats) - | SynPat.Tuple(pats, _) -> List.tryPick walkPat pats + | SynPat.Tuple(_,pats, _) -> List.tryPick walkPat pats | SynPat.Paren(pat, _) -> walkPat pat | SynPat.ArrayOrList(_, pats, _) -> List.tryPick walkPat pats | SynPat.IsInst(t, _) -> walkType t @@ -791,7 +796,7 @@ module UntypedParseImpl = | SynType.App(ty, _, types, _, _, _, _) -> walkType ty |> Option.orElse (List.tryPick walkType types) | SynType.LongIdentApp(_, _, _, types, _, _, _) -> List.tryPick walkType types - | SynType.Tuple(ts, _) -> ts |> List.tryPick (fun (_, t) -> walkType t) + | SynType.Tuple(_,ts, _) -> ts |> List.tryPick (fun (_, t) -> walkType t) | SynType.Array(_, t, _) -> walkType t | SynType.Fun(t1, t2, _) -> walkType t1 |> Option.orElse (walkType t2) | SynType.WithGlobalConstraints(t, _, _) -> walkType t @@ -819,7 +824,7 @@ module UntypedParseImpl = | SynExpr.Paren (e, _, _, _) -> walkExprWithKind parentKind e | SynExpr.Quote(_, _, e, _, _) -> walkExprWithKind parentKind e | SynExpr.Typed(e, _, _) -> walkExprWithKind parentKind e - | SynExpr.Tuple(es, _, _) -> List.tryPick (walkExprWithKind parentKind) es + | SynExpr.Tuple(_, es, _, _) -> List.tryPick (walkExprWithKind parentKind) es | SynExpr.ArrayOrList(_, es, _) -> List.tryPick (walkExprWithKind parentKind) es | SynExpr.Record(_, _, fields, r) -> ifPosInRange r (fun _ -> @@ -837,7 +842,7 @@ module UntypedParseImpl = | SynExpr.Lambda(_, _, _, e, _) -> walkExprWithKind parentKind e | SynExpr.MatchLambda(_, _, synMatchClauseList, _, _) -> List.tryPick walkClause synMatchClauseList - | SynExpr.Match(_, e, synMatchClauseList, _, _) -> + | SynExpr.Match(_, e, synMatchClauseList, _) -> walkExprWithKind parentKind e |> Option.orElse (List.tryPick walkClause synMatchClauseList) | SynExpr.Do(e, _) -> walkExprWithKind parentKind e | SynExpr.Assert(e, _) -> walkExprWithKind parentKind e @@ -869,7 +874,8 @@ module UntypedParseImpl = | SynExpr.JoinIn(e1, _, e2, _) -> List.tryPick (walkExprWithKind parentKind) [e1; e2] | SynExpr.YieldOrReturn(_, e, _) -> walkExprWithKind parentKind e | SynExpr.YieldOrReturnFrom(_, e, _) -> walkExprWithKind parentKind e - | (SynExpr.Match(_, e, synMatchClauseList, _, _) | SynExpr.MatchBang(_, e, synMatchClauseList, _, _)) -> + | SynExpr.Match(_, e, synMatchClauseList, _) + | SynExpr.MatchBang(_, e, synMatchClauseList, _) -> walkExprWithKind parentKind e |> Option.orElse (List.tryPick walkClause synMatchClauseList) | SynExpr.LetOrUseBang(_, _, _, _, e1, e2, _) -> List.tryPick (walkExprWithKind parentKind) [e1; e2] | SynExpr.DoBang(e, _) -> walkExprWithKind parentKind e @@ -1092,7 +1098,7 @@ module UntypedParseImpl = let findSetters argList = match argList with - | SynExpr.Paren(SynExpr.Tuple(parameters, _, _), _, _, _) -> + | SynExpr.Paren(SynExpr.Tuple(false, parameters, _, _), _, _, _) -> let setters = HashSet() for p in parameters do match p with @@ -1153,7 +1159,7 @@ module UntypedParseImpl = match path with | TS.Expr(SynExpr.Paren _)::TS.Expr(NewObjectOrMethodCall(args))::_ -> if Option.isSome precedingArgument then None else Some args - | TS.Expr(SynExpr.Tuple (elements, commas, _))::TS.Expr(SynExpr.Paren _)::TS.Expr(NewObjectOrMethodCall(args))::_ -> + | TS.Expr(SynExpr.Tuple (false, elements, commas, _))::TS.Expr(SynExpr.Paren _)::TS.Expr(NewObjectOrMethodCall(args))::_ -> match precedingArgument with | None -> Some args | Some e -> @@ -1258,7 +1264,7 @@ module UntypedParseImpl = match pat with | SynPat.Paren(pat, _) -> match pat with - | SynPat.Tuple(pats, _) -> + | SynPat.Tuple(_, pats, _) -> pats |> List.tryPick visitParam | _ -> visitParam pat | SynPat.Wild(range) when rangeContainsPos range pos -> diff --git a/src/fsharp/service/ServiceXmlDocParser.fs b/src/fsharp/service/ServiceXmlDocParser.fs index 92535f0cec..0cfd5ec6b7 100644 --- a/src/fsharp/service/ServiceXmlDocParser.fs +++ b/src/fsharp/service/ServiceXmlDocParser.fs @@ -22,8 +22,7 @@ module XmlDocParsing = | SynPat.Attrib(pat,_attrs,_range) -> digNamesFrom pat | SynPat.LongIdent(_lid,_idOpt,_typDeclsOpt,ConstructorPats pats,_access,_range) -> pats |> List.collect digNamesFrom - | SynPat.Tuple(pats,_range) - | SynPat.StructTuple(pats,_range) -> pats |> List.collect digNamesFrom + | SynPat.Tuple(_,pats,_range) -> pats |> List.collect digNamesFrom | SynPat.Paren(pat,_range) -> digNamesFrom pat | SynPat.OptionalVal (id, _) -> [id.idText] | SynPat.Or _ // no one uses ors in fun decls diff --git a/src/fsharp/service/service.fs b/src/fsharp/service/service.fs index 5ecc71684c..7fbc49c1f3 100755 --- a/src/fsharp/service/service.fs +++ b/src/fsharp/service/service.fs @@ -568,7 +568,7 @@ type TypeCheckInfo p <- p - 1 if p >= 0 then Some p else None - let CompletionItem (ty: TyconRef option) (assemblySymbol: AssemblySymbol option) (item: ItemWithInst) = + let CompletionItem (ty: ValueOption) (assemblySymbol: ValueOption) (item: ItemWithInst) = let kind = match item.Item with | Item.MethodGroup (_, minfo :: _, _) -> CompletionItemKind.Method minfo.IsExtensionMember @@ -584,10 +584,10 @@ type TypeCheckInfo MinorPriority = 0 Kind = kind IsOwnMember = false - Type = ty - Unresolved = assemblySymbol |> Option.map (fun x -> x.UnresolvedSymbol) } + Type = match ty with ValueSome x -> Some x | _ -> None + Unresolved = match assemblySymbol with ValueSome x -> Some x.UnresolvedSymbol | _ -> None } - let DefaultCompletionItem item = CompletionItem None None item + let DefaultCompletionItem item = CompletionItem ValueNone ValueNone item let getItem (x: ItemWithInst) = x.Item let GetDeclaredItems (parseResultsOpt: FSharpParseFileResults option, lineStr: string, origLongIdentOpt, colAtEndOfNamesAndResidue, residueOpt, lastDotPos, line, loc, @@ -635,29 +635,27 @@ type TypeCheckInfo let pos = mkPos line loc let (nenv, ad), m = GetBestEnvForPos pos - let getType() = - let tref = - match NameResolution.TryToResolveLongIdentAsType ncenv nenv m plid with - | Some x -> Some x - | None -> - match lastDotPos |> Option.orElseWith (fun _ -> FindFirstNonWhitespacePosition lineStr (colAtEndOfNamesAndResidue - 1)) with - | Some p when lineStr.[p] = '.' -> - match FindFirstNonWhitespacePosition lineStr (p - 1) with - | Some colAtEndOfNames -> - let colAtEndOfNames = colAtEndOfNames + 1 // convert 0-based to 1-based - let tyconRef = TryGetTypeFromNameResolution(line, colAtEndOfNames, residueOpt, resolveOverloads) - tyconRef - | None -> None - | _ -> None - - tref |> Option.bind (tryDestAppTy g) + let getType() = + match NameResolution.TryToResolveLongIdentAsType ncenv nenv m plid with + | Some x -> tryDestAppTy g x + | None -> + match lastDotPos |> Option.orElseWith (fun _ -> FindFirstNonWhitespacePosition lineStr (colAtEndOfNamesAndResidue - 1)) with + | Some p when lineStr.[p] = '.' -> + match FindFirstNonWhitespacePosition lineStr (p - 1) with + | Some colAtEndOfNames -> + let colAtEndOfNames = colAtEndOfNames + 1 // convert 0-based to 1-based + match TryGetTypeFromNameResolution(line, colAtEndOfNames, residueOpt, resolveOverloads) with + | Some x -> tryDestAppTy g x + | _ -> ValueNone + | None -> ValueNone + | _ -> ValueNone match nameResItems with | NameResResult.TypecheckStaleAndTextChanged -> None // second-chance intellisense will try again | NameResResult.Cancel(denv,m) -> Some([], denv, m) | NameResResult.Members(FilterRelevantItems getItem exactMatchResidueOpt (items, denv, m)) -> // lookup based on name resolution results successful - Some (items |> List.map (CompletionItem (getType()) None), denv, m) + Some (items |> List.map (CompletionItem (getType()) ValueNone), denv, m) | _ -> match origLongIdentOpt with | None -> None @@ -690,9 +688,9 @@ type TypeCheckInfo // These come through as an empty plid and residue "". Otherwise we try an environment lookup // and then return to the qualItems. This is because the expression typings are a little inaccurate, primarily because // it appears we're getting some typings recorded for non-atomic expressions like "f x" - when (match plid with [] -> true | _ -> false) -> + when isNil plid -> // lookup based on expression typings successful - Some (items |> List.map (CompletionItem (tryDestAppTy g ty) None), denv, m) + Some (items |> List.map (CompletionItem (tryDestAppTy g ty) ValueNone), denv, m) | GetPreciseCompletionListFromExprTypingsResult.NoneBecauseThereWereTypeErrors, _ -> // There was an error, e.g. we have "." and there is an error determining the type of // In this case, we don't want any of the fallback logic, rather, we want to produce zero results. @@ -700,7 +698,7 @@ type TypeCheckInfo | GetPreciseCompletionListFromExprTypingsResult.NoneBecauseTypecheckIsStaleAndTextChanged, _ -> // we want to report no result and let second-chance intellisense kick in None - | _, true when (match plid with [] -> true | _ -> false) -> + | _, true when isNil plid -> // If the user just pressed '.' after an _expression_ (not a plid), it is never right to show environment-lookup top-level completions. // The user might by typing quickly, and the LS didn't have an expression type right before the dot yet. // Second-chance intellisense will bring up the correct list in a moment. @@ -715,19 +713,19 @@ type TypeCheckInfo // First, use unfiltered name resolution items, if they're not empty | NameResResult.Members(items, denv, m), _, _ when not (isNil items) -> // lookup based on name resolution results successful - Some(items |> List.map (CompletionItem (getType()) None), denv, m) + ValueSome(items |> List.map (CompletionItem (getType()) ValueNone), denv, m) // If we have nonempty items from environment that were resolved from a type, then use them... // (that's better than the next case - here we'd return 'int' as a type) | _, FilterRelevantItems getItem exactMatchResidueOpt (items, denv, m), _ when not (isNil items) -> // lookup based on name and environment successful - Some(items |> List.map (CompletionItem (getType()) None), denv, m) + ValueSome(items |> List.map (CompletionItem (getType()) ValueNone), denv, m) // Try again with the qualItems | _, _, GetPreciseCompletionListFromExprTypingsResult.Some(FilterRelevantItems getItem exactMatchResidueOpt (items, denv, m), ty) -> - Some(items |> List.map (CompletionItem (tryDestAppTy g ty) None), denv, m) + ValueSome(items |> List.map (CompletionItem (tryDestAppTy g ty) ValueNone), denv, m) - | _ -> None + | _ -> ValueNone let globalResult = match origLongIdentOpt with @@ -745,16 +743,16 @@ type TypeCheckInfo match globalItems, denv, m with | FilterRelevantItems getItem exactMatchResidueOpt (globalItemsFiltered, denv, m) when not (isNil globalItemsFiltered) -> globalItemsFiltered - |> List.map(fun globalItem -> CompletionItem (getType()) (Some globalItem) (ItemWithNoInst globalItem.Symbol.Item)) - |> fun r -> Some(r, denv, m) - | _ -> None - | _ -> None // do not return unresolved items after dot + |> List.map(fun globalItem -> CompletionItem (getType()) (ValueSome globalItem) (ItemWithNoInst globalItem.Symbol.Item)) + |> fun r -> ValueSome(r, denv, m) + | _ -> ValueNone + | _ -> ValueNone // do not return unresolved items after dot match envResult, globalResult with - | Some (items, denv, m), Some (gItems,_,_) -> Some (items @ gItems, denv, m) - | Some x, None -> Some x - | None, Some y -> Some y - | None, None -> None + | ValueSome (items, denv, m), ValueSome (gItems,_,_) -> Some (items @ gItems, denv, m) + | ValueSome x, ValueNone -> Some x + | ValueNone, ValueSome y -> Some y + | ValueNone, ValueNone -> None let toCompletionItems (items: ItemWithInst list, denv: DisplayEnv, m: range ) = @@ -1161,22 +1159,22 @@ type TypeCheckInfo match item.Item with | Item.CtorGroup (_, (ILMeth (_,ilinfo,_)) :: _) -> match ilinfo.MetadataScope with - | ILScopeRef.Assembly assref -> + | ILScopeRef.Assembly assemblyRef -> let typeVarNames = getTypeVarNames ilinfo ParamTypeSymbol.tryOfILTypes typeVarNames ilinfo.ILMethodRef.ArgTypes |> Option.map (fun args -> let externalSym = ExternalSymbol.Constructor (ilinfo.ILMethodRef.DeclaringTypeRef.FullName, args) - FSharpFindDeclResult.ExternalDecl (assref.Name, externalSym)) + FSharpFindDeclResult.ExternalDecl (assemblyRef.Name, externalSym)) | _ -> None | Item.MethodGroup (name, (ILMeth (_,ilinfo,_)) :: _, _) -> match ilinfo.MetadataScope with - | ILScopeRef.Assembly assref -> + | ILScopeRef.Assembly assemblyRef -> let typeVarNames = getTypeVarNames ilinfo ParamTypeSymbol.tryOfILTypes typeVarNames ilinfo.ILMethodRef.ArgTypes |> Option.map (fun args -> let externalSym = ExternalSymbol.Method (ilinfo.ILMethodRef.DeclaringTypeRef.FullName, name, args, ilinfo.ILMethodRef.GenericArity) - FSharpFindDeclResult.ExternalDecl (assref.Name, externalSym)) + FSharpFindDeclResult.ExternalDecl (assemblyRef.Name, externalSym)) | _ -> None | Item.Property (name, ILProp propInfo :: _) -> @@ -1188,24 +1186,24 @@ type TypeCheckInfo match methInfo with | Some methInfo -> match methInfo.MetadataScope with - | ILScopeRef.Assembly assref -> + | ILScopeRef.Assembly assemblyRef -> let externalSym = ExternalSymbol.Property (methInfo.ILMethodRef.DeclaringTypeRef.FullName, name) - Some (FSharpFindDeclResult.ExternalDecl (assref.Name, externalSym)) + Some (FSharpFindDeclResult.ExternalDecl (assemblyRef.Name, externalSym)) | _ -> None | None -> None | Item.ILField (ILFieldInfo (typeInfo, fieldDef)) when not typeInfo.TyconRefOfRawMetadata.IsLocalRef -> match typeInfo.ILScopeRef with - | ILScopeRef.Assembly assref -> + | ILScopeRef.Assembly assemblyRef -> let externalSym = ExternalSymbol.Field (typeInfo.ILTypeRef.FullName, fieldDef.Name) - Some (FSharpFindDeclResult.ExternalDecl (assref.Name, externalSym)) + Some (FSharpFindDeclResult.ExternalDecl (assemblyRef.Name, externalSym)) | _ -> None | Item.Event (ILEvent (ILEventInfo (typeInfo, eventDef))) when not typeInfo.TyconRefOfRawMetadata.IsLocalRef -> match typeInfo.ILScopeRef with - | ILScopeRef.Assembly assref -> + | ILScopeRef.Assembly assemblyRef -> let externalSym = ExternalSymbol.Event (typeInfo.ILTypeRef.FullName, eventDef.Name) - Some (FSharpFindDeclResult.ExternalDecl (assref.Name, externalSym)) + Some (FSharpFindDeclResult.ExternalDecl (assemblyRef.Name, externalSym)) | _ -> None | Item.ImplicitOp(_, {contents = Some(TraitConstraintSln.FSMethSln(_, _vref, _))}) -> @@ -1216,9 +1214,9 @@ type TypeCheckInfo | Item.Types (_, [ AppTy g (tr, _) ]) when not tr.IsLocalRef -> match tr.TypeReprInfo, tr.PublicPath with - | TILObjectRepr(TILObjectReprData (ILScopeRef.Assembly assref, _, _)), Some (PubPath parts) -> + | TILObjectRepr(TILObjectReprData (ILScopeRef.Assembly assemblyRef, _, _)), Some (PubPath parts) -> let fullName = parts |> String.concat "." - Some (FSharpFindDeclResult.ExternalDecl (assref.Name, ExternalSymbol.Type fullName)) + Some (FSharpFindDeclResult.ExternalDecl (assemblyRef.Name, ExternalSymbol.Type fullName)) | _ -> None | _ -> None match result with @@ -1324,13 +1322,23 @@ type TypeCheckInfo let underlyingTy = stripTyEqnsAndMeasureEqns g ty isStructTy g underlyingTy + let isValRefMutable (vref: ValRef) = + // Mutable values, ref cells, and non-inref byrefs are mutable. + vref.IsMutable + || Tastops.isRefCellTy g vref.Type + || (Tastops.isByrefTy g vref.Type && not (Tastops.isInByrefTy g vref.Type)) + + let isRecdFieldMutable (rfinfo: RecdFieldInfo) = + (rfinfo.RecdField.IsMutable && rfinfo.LiteralValue.IsNone) + || Tastops.isRefCellTy g rfinfo.RecdField.FormalType + resolutions |> Seq.choose (fun cnr -> match cnr with // 'seq' in 'seq { ... }' gets colored as keywords | CNR(_, (Item.Value vref), ItemOccurence.Use, _, _, _, m) when valRefEq g g.seq_vref vref -> Some (m, SemanticClassificationType.ComputationExpression) - | CNR(_, (Item.Value vref), _, _, _, _, m) when vref.IsMutable || Tastops.isRefCellTy g vref.Type -> + | CNR(_, (Item.Value vref), _, _, _, _, m) when isValRefMutable vref -> Some (m, SemanticClassificationType.MutableVar) | CNR(_, Item.Value KeywordIntrinsicValue, ItemOccurence.Use, _, _, _, m) -> Some (m, SemanticClassificationType.IntrinsicFunction) @@ -1343,7 +1351,7 @@ type TypeCheckInfo Some (m, SemanticClassificationType.Operator) else Some (m, SemanticClassificationType.Function) - | CNR(_, Item.RecdField rfinfo, _, _, _, _, m) when rfinfo.RecdField.IsMutable && rfinfo.LiteralValue.IsNone -> + | CNR(_, Item.RecdField rfinfo, _, _, _, _, m) when isRecdFieldMutable rfinfo -> Some (m, SemanticClassificationType.MutableVar) | CNR(_, Item.RecdField rfinfo, _, _, _, _, m) when isFunction g rfinfo.FieldType -> Some (m, SemanticClassificationType.Function) @@ -1599,7 +1607,7 @@ module internal Parser = let isExe = options.IsExe try Some (ParseInput(lexfun, errHandler.ErrorLogger, lexbuf, None, fileName, (isLastCompiland, isExe))) with e -> - errHandler.ErrorLogger.ErrorR(e) + errHandler.ErrorLogger.StopProcessingRecovery e Range.range0 // don't re-raise any exceptions, we must return None. None) errHandler.CollectedDiagnostics, parseResult, errHandler.AnyErrors @@ -1616,6 +1624,7 @@ module internal Parser = tcGlobals: TcGlobals, tcImports: TcImports, tcState: TcState, + moduleNamesDict: ModuleNamesDict, loadClosure: LoadClosure option, // These are the errors and warnings seen by the background compiler for the entire antecedent backgroundDiagnostics: (PhasedDiagnostic * FSharpErrorSeverity)[], @@ -1719,6 +1728,9 @@ module internal Parser = async { try let checkForErrors() = (parseResults.ParseHadErrors || errHandler.ErrorCount > 0) + + let parsedMainInput, _moduleNamesDict = DeduplicateParsedInputModuleName moduleNamesDict parsedMainInput + // Typecheck is potentially a long running operation. We chop it up here with an Eventually continuation and, at each slice, give a chance // for the client to claim the result as obsolete and have the typecheck abort. @@ -1905,7 +1917,8 @@ type FSharpCheckProjectResults(projectFileName:string, tcConfigOption, keepAssem let cenv = SymbolEnv(tcGlobals, thisCcu, Some ccuSig, tcImports) [| for r in tcSymbolUses do - for symbolUse in r.AllUsesOfSymbols do + for symbolUseChunk in r.AllUsesOfSymbols do + for symbolUse in symbolUseChunk do if symbolUse.ItemOccurence <> ItemOccurence.RelatedText then let symbol = FSharpSymbol.Create(cenv, symbolUse.Item) yield FSharpSymbolUse(tcGlobals, symbolUse.DisplayEnv, symbol, symbolUse.ItemOccurence, symbolUse.Range) |] @@ -2099,7 +2112,8 @@ type FSharpCheckFileResults(filename: string, errors: FSharpErrorInfo[], scopeOp (fun () -> [| |]) (fun scope -> let cenv = scope.SymbolEnv - [| for symbolUse in scope.ScopeSymbolUses.AllUsesOfSymbols do + [| for symbolUseChunk in scope.ScopeSymbolUses.AllUsesOfSymbols do + for symbolUse in symbolUseChunk do if symbolUse.ItemOccurence <> ItemOccurence.RelatedText then let symbol = FSharpSymbol.Create(cenv, symbolUse.Item) yield FSharpSymbolUse(scope.TcGlobals, symbolUse.DisplayEnv, symbol, symbolUse.ItemOccurence, symbolUse.Range) |]) @@ -2597,7 +2611,7 @@ type BackgroundCompiler(legacyReferenceResolver, projectCacheSize, keepAssemblyC let loadClosure = scriptClosureCacheLock.AcquireLock (fun ltok -> scriptClosureCache.TryGet (ltok, options)) let! tcErrors, tcFileResult = Parser.CheckOneFile(parseResults, source, fileName, options.ProjectFileName, tcPrior.TcConfig, tcPrior.TcGlobals, tcPrior.TcImports, - tcPrior.TcState, loadClosure, tcPrior.TcErrors, reactorOps, (fun () -> builder.IsAlive), textSnapshotInfo, userOpName) + tcPrior.TcState, tcPrior.ModuleNamesDict, loadClosure, tcPrior.TcErrors, reactorOps, (fun () -> builder.IsAlive), textSnapshotInfo, userOpName) let parsingOptions = FSharpParsingOptions.FromTcConfig(tcPrior.TcConfig, Array.ofList builder.SourceFiles, options.UseScriptResolutionRules) let checkAnswer = MakeCheckFileAnswer(fileName, tcFileResult, options, builder, Array.ofList tcPrior.TcDependencyFiles, creationErrors, parseResults.Errors, tcErrors) bc.RecordTypeCheckFileInProjectResults(fileName, options, parsingOptions, parseResults, fileVersion, tcPrior.TimeStamp, Some checkAnswer, source) @@ -2678,9 +2692,7 @@ type BackgroundCompiler(legacyReferenceResolver, projectCacheSize, keepAssemblyC | _ -> Trace.TraceInformation("FCS: {0}.{1} ({2})", userOpName, "CheckFileInProject.CacheMiss", filename) let! tcPrior = execWithReactorAsync <| fun ctok -> builder.GetCheckResultsBeforeFileInProject (ctok, filename) - let parseTreeOpt = parseResults.ParseTree |> Option.map builder.DeduplicateParsedInputModuleNameInProject - let parseResultsAterDeDuplication = FSharpParseFileResults(parseResults.Errors, parseTreeOpt, parseResults.ParseHadErrors, parseResults.DependencyFiles) - let! checkAnswer = bc.CheckOneFileImpl(parseResultsAterDeDuplication, source, filename, options, textSnapshotInfo, fileVersion, builder, tcPrior, creationErrors, userOpName) + let! checkAnswer = bc.CheckOneFileImpl(parseResults, source, filename, options, textSnapshotInfo, fileVersion, builder, tcPrior, creationErrors, userOpName) return checkAnswer finally bc.ImplicitlyStartCheckProjectInBackground(options, userOpName) @@ -2723,7 +2735,6 @@ type BackgroundCompiler(legacyReferenceResolver, projectCacheSize, keepAssemblyC // Do the parsing. let parsingOptions = FSharpParsingOptions.FromTcConfig(builder.TcConfig, Array.ofList (builder.SourceFiles), options.UseScriptResolutionRules) let parseErrors, parseTreeOpt, anyErrors = Parser.parseFile (source, filename, parsingOptions, userOpName) - let parseTreeOpt = parseTreeOpt |> Option.map builder.DeduplicateParsedInputModuleNameInProject let parseResults = FSharpParseFileResults(parseErrors, parseTreeOpt, anyErrors, builder.AllDependenciesDeprecated) let! checkResults = bc.CheckOneFileImpl(parseResults, source, filename, options, textSnapshotInfo, fileVersion, builder, tcPrior, creationErrors, userOpName) @@ -3280,23 +3291,23 @@ type FSharpChecker(legacyReferenceResolver, projectCacheSize, keepAssemblyConten member internal __.FrameworkImportsCache = backgroundCompiler.FrameworkImportsCache /// Tokenize a single line, returning token information and a tokenization state represented by an integer - member x.TokenizeLine (line: string, state: int64) : FSharpTokenInfo[] * int64 = + member x.TokenizeLine (line: string, state: FSharpTokenizerLexState) = let tokenizer = FSharpSourceTokenizer([], None) let lineTokenizer = tokenizer.CreateLineTokenizer line - let state = ref (None, state) + let mutable state = (None, state) let tokens = - [| while (state := lineTokenizer.ScanToken (snd !state); (fst !state).IsSome) do - yield (fst !state).Value |] - tokens, snd !state + [| while (state <- lineTokenizer.ScanToken (snd state); (fst state).IsSome) do + yield (fst state).Value |] + tokens, snd state /// Tokenize an entire file, line by line member x.TokenizeFile (source: string) : FSharpTokenInfo[][] = let lines = source.Split('\n') let tokens = - [| let state = ref 0L + [| let mutable state = FSharpTokenizerLexState.Initial for line in lines do - let tokens, n = x.TokenizeLine(line, !state) - state := n + let tokens, n = x.TokenizeLine(line, state) + state <- n yield tokens |] tokens @@ -3323,7 +3334,7 @@ type FsiInteractiveChecker(legacyReferenceResolver, reactorOps: IReactorOperatio CompileOptions.ParseCompilerOptions (ignore, fsiCompilerOptions, [ ]) let loadClosure = LoadClosure.ComputeClosureOfScriptText(ctok, legacyReferenceResolver, defaultFSharpBinariesDir, filename, source, CodeContext.Editing, tcConfig.useSimpleResolution, tcConfig.useFsiAuxLib, new Lexhelp.LexResourceManager(), applyCompilerOptions, assumeDotNetFramework, tryGetMetadataSnapshot=(fun _ -> None), reduceMemoryUsage=reduceMemoryUsage) - let! tcErrors, tcFileResult = Parser.CheckOneFile(parseResults, source, filename, "project", tcConfig, tcGlobals, tcImports, tcState, Some loadClosure, backgroundDiagnostics, reactorOps, (fun () -> true), None, userOpName) + let! tcErrors, tcFileResult = Parser.CheckOneFile(parseResults, source, filename, "project", tcConfig, tcGlobals, tcImports, tcState, Map.empty, Some loadClosure, backgroundDiagnostics, reactorOps, (fun () -> true), None, userOpName) return match tcFileResult with @@ -3333,7 +3344,7 @@ type FsiInteractiveChecker(legacyReferenceResolver, reactorOps: IReactorOperatio let projectResults = FSharpCheckProjectResults (filename, Some tcConfig, keepAssemblyContents, errors, Some(tcGlobals, tcImports, tcFileInfo.ThisCcu, tcFileInfo.CcuSigForFile, - [tcFileInfo.ScopeSymbolUses], None, None, mkSimpleAssRef "stdin", + [tcFileInfo.ScopeSymbolUses], None, None, mkSimpleAssemblyRef "stdin", tcState.TcEnvFromImpls.AccessRights, None, dependencyFiles)) parseResults, typeCheckResults, projectResults | _ -> diff --git a/src/fsharp/service/service.fsi b/src/fsharp/service/service.fsi index 5ccb31e450..2d07c23561 100755 --- a/src/fsharp/service/service.fsi +++ b/src/fsharp/service/service.fsi @@ -711,7 +711,7 @@ type public FSharpChecker = member internal ReferenceResolver : ReferenceResolver.Resolver /// Tokenize a single line, returning token information and a tokenization state represented by an integer - member TokenizeLine: line:string * state:int64 -> FSharpTokenInfo [] * int64 + member TokenizeLine: line:string * state:FSharpTokenizerLexState-> FSharpTokenInfo [] * FSharpTokenizerLexState /// Tokenize an entire file, line by line member TokenizeFile: source:string -> FSharpTokenInfo [] [] diff --git a/src/fsharp/symbols/Exprs.fs b/src/fsharp/symbols/Exprs.fs index f6213ef2ff..4da520daed 100644 --- a/src/fsharp/symbols/Exprs.fs +++ b/src/fsharp/symbols/Exprs.fs @@ -1033,7 +1033,7 @@ module FSharpExprConvert = // is not sufficient to resolve to a symbol unambiguously in these cases. let argtys = [ ilMethRef.ArgTypes |> List.map (ImportILTypeFromMetadata cenv.amap m scoref tinst1 tinst2) ] let rty = - match ImportReturnTypeFromMetaData cenv.amap m ilMethRef.ReturnType scoref tinst1 tinst2 with + match ImportReturnTypeFromMetadata cenv.amap m ilMethRef.ReturnType emptyILCustomAttrs scoref tinst1 tinst2 with | None -> if isCtor then enclosingType else cenv.g.unit_ty | Some ty -> ty @@ -1223,7 +1223,7 @@ and FSharpImplementationFileDeclaration = | InitAction of FSharpExpr and FSharpImplementationFileContents(cenv, mimpl) = - let (TImplFile(qname, _pragmas, ModuleOrNamespaceExprWithSig(_, mdef, _), hasExplicitEntryPoint, isScript)) = mimpl + let (TImplFile(qname, _pragmas, ModuleOrNamespaceExprWithSig(_, mdef, _), hasExplicitEntryPoint, isScript, _anonRecdTypes)) = mimpl let rec getDecls2 (ModuleOrNamespaceExprWithSig(_mty, def, _m)) = getDecls def and getBind (bind: Binding) = let v = bind.Var diff --git a/src/fsharp/symbols/SymbolHelpers.fs b/src/fsharp/symbols/SymbolHelpers.fs index 2a3031e004..f4fb7c0238 100644 --- a/src/fsharp/symbols/SymbolHelpers.fs +++ b/src/fsharp/symbols/SymbolHelpers.fs @@ -361,11 +361,12 @@ module internal SymbolHelpers = | Item.UnionCase(ucinfo, _) -> Some (rangeOfUnionCaseInfo preferFlag ucinfo) | Item.ActivePatternCase apref -> Some (rangeOfValRef preferFlag apref.ActivePatternVal) | Item.ExnCase tcref -> Some tcref.Range + | Item.AnonRecdField (_,_,_,m) -> Some m | Item.RecdField rfinfo -> Some (rangeOfRecdFieldInfo preferFlag rfinfo) | Item.Event einfo -> rangeOfEventInfo preferFlag einfo | Item.ILField _ -> None | Item.Property(_, pinfos) -> rangeOfPropInfo preferFlag pinfos.Head - | Item.Types(_, tys) -> tys |> List.tryPick (tryNiceEntityRefOfTy >> Option.map (rangeOfEntityRef preferFlag)) + | Item.Types(_, tys) -> tys |> List.tryPick (tryNiceEntityRefOfTyOption >> Option.map (rangeOfEntityRef preferFlag)) | Item.CustomOperation (_, _, Some minfo) -> rangeOfMethInfo g preferFlag minfo | Item.TypeVar (_, tp) -> Some tp.Range | Item.ModuleOrNamespaces(modrefs) -> modrefs |> List.tryPick (rangeOfEntityRef preferFlag >> Some) @@ -379,7 +380,7 @@ module internal SymbolHelpers = | Item.ImplicitOp _ -> None | Item.UnqualifiedType tcrefs -> tcrefs |> List.tryPick (rangeOfEntityRef preferFlag >> Some) | Item.DelegateCtor ty - | Item.FakeInterfaceCtor ty -> ty |> tryNiceEntityRefOfTy |> Option.map (rangeOfEntityRef preferFlag) + | Item.FakeInterfaceCtor ty -> ty |> tryNiceEntityRefOfTyOption |> Option.map (rangeOfEntityRef preferFlag) | Item.NewDef _ -> None // Provided type definitions do not have a useful F# CCU for the purposes of goto-definition. @@ -419,7 +420,7 @@ module internal SymbolHelpers = | Item.CtorGroup(_, minfos) -> minfos |> List.tryPick (ccuOfMethInfo g) | Item.CustomOperation (_, _, Some minfo) -> ccuOfMethInfo g minfo - | Item.Types(_, tys) -> tys |> List.tryPick (tryNiceEntityRefOfTy >> Option.bind computeCcuOfTyconRef) + | Item.Types(_, tys) -> tys |> List.tryPick (tryNiceEntityRefOfTyOption >> Option.bind computeCcuOfTyconRef) | Item.ArgName (_, _, Some (ArgumentContainer.Type eref)) -> computeCcuOfTyconRef eref @@ -427,6 +428,7 @@ module internal SymbolHelpers = | Item.UnqualifiedType(erefs) -> erefs |> List.tryPick computeCcuOfTyconRef | Item.SetterArg (_, item) -> ccuOfItem g item + | Item.AnonRecdField (info, _, _, _) -> Some info.Assembly | Item.TypeVar _ -> None | _ -> None @@ -713,8 +715,12 @@ module internal SymbolHelpers = // In this case just bail out and assume items are not equal protectAssemblyExploration false (fun () -> let equalHeadTypes(ty1, ty2) = - if isAppTy g ty1 && isAppTy g ty2 then tyconRefEq g (tcrefOfAppTy g ty1) (tcrefOfAppTy g ty2) - else typeEquiv g ty1 ty2 + match tryDestAppTy g ty1 with + | ValueSome tcref1 -> + match tryDestAppTy g ty2 with + | ValueSome tcref2 -> tyconRefEq g tcref1 tcref2 + | _ -> typeEquiv g ty1 ty2 + | _ -> typeEquiv g ty1 ty2 ItemsAreEffectivelyEqual g item1 item2 || @@ -752,6 +758,8 @@ module internal SymbolHelpers = List.zip pi1s pi2s |> List.forall(fun (pi1, pi2) -> PropInfo.PropInfosUseIdenticalDefinitions pi1 pi2) | Item.Event(evt1), Item.Event(evt2) -> EventInfo.EventInfosUseIdenticalDefintions evt1 evt2 + | Item.AnonRecdField(anon1, _, i1, _), Item.AnonRecdField(anon2, _, i2, _) -> + Tastops.anonInfoEquiv anon1 anon2 && i1 = i2 | Item.CtorGroup(_, meths1), Item.CtorGroup(_, meths2) -> List.zip meths1 meths2 |> List.forall (fun (minfo1, minfo2) -> MethInfo.MethInfosUseIdenticalDefinitions minfo1 minfo2) @@ -768,8 +776,9 @@ module internal SymbolHelpers = protectAssemblyExploration 1027 (fun () -> match item with | ItemWhereTypIsPreferred ty -> - if isAppTy g ty then hash (tcrefOfAppTy g ty).LogicalName - else 1010 + match tryDestAppTy g ty with + | ValueSome tcref -> hash (tcref).LogicalName + | _ -> 1010 | Item.ILField(ILFieldInfo(_, fld)) -> System.Runtime.CompilerServices.RuntimeHelpers.GetHashCode fld // hash on the object identity of the AbstractIL metadata blob for the field | Item.TypeVar (nm, _tp) -> hash nm @@ -784,6 +793,7 @@ module internal SymbolHelpers = | Item.ExnCase(tcref) -> hash tcref.LogicalName | Item.UnionCase(UnionCaseInfo(_, UCRef(tcref, n)), _) -> hash(tcref.Stamp, n) | Item.RecdField(RecdFieldInfo(_, RFRef(tcref, n))) -> hash(tcref.Stamp, n) + | Item.AnonRecdField(anon, _, i, _) -> hash anon.SortedNames.[i] | Item.Event evt -> evt.ComputeHashCode() | Item.Property(_name, pis) -> hash (pis |> List.map (fun pi -> pi.ComputeHashCode())) | Item.UnqualifiedType(tcref :: _) -> hash tcref.LogicalName @@ -864,6 +874,7 @@ module internal SymbolHelpers = | Item.ActivePatternResult(apinfo, _ty, idx, _) -> apinfo.Names.[idx] | Item.ActivePatternCase apref -> FullNameOfItem g (Item.Value apref.ActivePatternVal) + "." + apref.Name | Item.ExnCase ecref -> fullDisplayTextOfExnRef ecref + | Item.AnonRecdField(anon, _argTys, i, _) -> anon.SortedNames.[i] | Item.RecdField rfinfo -> fullDisplayTextOfRecdFieldRef rfinfo.RecdFieldRef | Item.NewDef id -> id.idText | Item.ILField finfo -> bufs (fun os -> NicePrint.outputILTypeRef denv os finfo.ILTypeRef; bprintf os ".%s" finfo.FieldName) @@ -878,7 +889,7 @@ module internal SymbolHelpers = | Item.DelegateCtor ty | Item.Types(_, ty:: _) -> match tryDestAppTy g ty with - | Some tcref -> bufs (fun os -> NicePrint.outputTyconRef denv os tcref) + | ValueSome tcref -> bufs (fun os -> NicePrint.outputTyconRef denv os tcref) | _ -> "" | Item.ModuleOrNamespaces((modref :: _) as modrefs) -> let definiteNamespace = modrefs |> List.forall (fun modref -> modref.IsNamespace) @@ -1180,7 +1191,7 @@ module internal SymbolHelpers = ([], modrefs) ||> Seq.fold (fun st modref -> match fullDisplayTextOfParentOfModRef modref with - | Some(txt) -> txt::st + | ValueSome txt -> txt::st | _ -> st) |> Seq.mapi (fun i x -> i, x) |> Seq.toList @@ -1201,6 +1212,17 @@ module internal SymbolHelpers = else FSharpStructuredToolTipElement.Single (layout, xml) + | Item.AnonRecdField(anon, argTys, i, _) -> + let argTy = argTys.[i] + let nm = anon.SortedNames.[i] + let argTy, _ = PrettyTypes.PrettifyType g argTy + let layout = + wordL (tagText (FSComp.SR.typeInfoAnonRecdField())) ^^ + wordL (tagRecordField nm) ^^ + RightL.colon ^^ + NicePrint.layoutType denv argTy + FSharpStructuredToolTipElement.Single (layout, FSharpXmlDoc.None) + // Named parameters | Item.ArgName (id, argTy, _) -> let argTy, _ = PrettyTypes.PrettifyType g argTy @@ -1320,6 +1342,8 @@ module internal SymbolHelpers = | Item.RecdField rfi -> (rfi.TyconRef |> ticksAndArgCountTextOfTyconRef)+"."+rfi.Name |> Some + | Item.AnonRecdField _ -> None + | Item.ILField finfo -> match finfo with | ILFieldInfo(tinfo, fdef) -> diff --git a/src/fsharp/symbols/SymbolPatterns.fs b/src/fsharp/symbols/SymbolPatterns.fs index 74b9bcf60c..eb12229f7c 100644 --- a/src/fsharp/symbols/SymbolPatterns.fs +++ b/src/fsharp/symbols/SymbolPatterns.fs @@ -186,7 +186,9 @@ module Symbol = let (|RecordField|_|) (e: FSharpSymbol) = match e with | :? FSharpField as field -> - if field.DeclaringEntity.IsFSharpRecord then Some field else None + match field.DeclaringEntity with + | None -> None + | Some e -> if e.IsFSharpRecord then Some field else None | _ -> None let (|ActivePatternCase|_|) (symbol: FSharpSymbol) = diff --git a/src/fsharp/symbols/Symbols.fs b/src/fsharp/symbols/Symbols.fs index fc57dedae9..fa3fcccfc8 100755 --- a/src/fsharp/symbols/Symbols.fs +++ b/src/fsharp/symbols/Symbols.fs @@ -80,13 +80,13 @@ module Impl = | None -> mkLocalEntityRef entity | Some viewedCcu -> match tryRescopeEntity viewedCcu entity with - | None -> mkLocalEntityRef entity - | Some eref -> eref + | ValueNone -> mkLocalEntityRef entity + | ValueSome eref -> eref let entityIsUnresolved(entity:EntityRef) = match entity with | ERefNonLocal(NonLocalEntityRef(ccu, _)) -> - ccu.IsUnresolvedReference && entity.TryDeref.IsNone + ccu.IsUnresolvedReference && ValueOptionInternal.isNone entity.TryDeref | _ -> false let checkEntityIsResolved(entity:EntityRef) = @@ -245,6 +245,8 @@ type FSharpSymbol(cenv: SymbolEnv, item: (unit -> Item), access: (FSharpSymbol - | Item.RecdField rfinfo -> FSharpField(cenv, RecdOrClass rfinfo.RecdFieldRef) :> _ | Item.ILField finfo -> FSharpField(cenv, ILField finfo) :> _ + + | Item.AnonRecdField (anonInfo, tinst, n, m) -> FSharpField(cenv, AnonField (anonInfo, tinst, n, m)) :> _ | Item.Event einfo -> FSharpMemberOrFunctionOrValue(cenv, E einfo, item) :> _ @@ -475,7 +477,7 @@ and FSharpEntity(cenv: SymbolEnv, entity:EntityRef) = member __.IsByRef = isResolved() && - tyconRefEq cenv.g cenv.g.byref_tcr entity + isByrefTyconRef cenv.g entity member __.IsOpaque = isResolved() && @@ -753,11 +755,12 @@ and FSharpUnionCase(cenv, v: UnionCaseRef) = ) - let isUnresolved() = - entityIsUnresolved v.TyconRef || v.TryUnionCase.IsNone + let isUnresolved() = + entityIsUnresolved v.TyconRef || ValueOptionInternal.isNone v.TryUnionCase + let checkIsResolved() = checkEntityIsResolved v.TyconRef - if v.TryUnionCase.IsNone then + if ValueOptionInternal.isNone v.TryUnionCase then invalidOp (sprintf "The union case '%s' could not be found in the target type" v.CaseName) member __.IsUnresolved = @@ -815,26 +818,43 @@ and FSharpUnionCase(cenv, v: UnionCaseRef) = and FSharpFieldData = + | AnonField of AnonRecdTypeInfo * TTypes * int * range | ILField of ILFieldInfo | RecdOrClass of RecdFieldRef | Union of UnionCaseRef * int member x.TryRecdField = match x with - | RecdOrClass v -> v.RecdField |> Choice1Of2 - | Union (v, n) -> v.FieldByIndex(n) |> Choice1Of2 - | ILField f -> f |> Choice2Of2 + | AnonField (anonInfo, tinst, n, m) -> (anonInfo, tinst, n, m) |> Choice3Of3 + | RecdOrClass v -> v.RecdField |> Choice1Of3 + | Union (v, n) -> v.FieldByIndex(n) |> Choice1Of3 + | ILField f -> f |> Choice2Of3 - member x.DeclaringTyconRef = + member x.TryDeclaringTyconRef = match x with - | RecdOrClass v -> v.TyconRef - | Union (v, _) -> v.TyconRef - | ILField f -> f.DeclaringTyconRef + | AnonField _ -> None + | RecdOrClass v -> Some v.TyconRef + | Union (v, _) -> Some v.TyconRef + | ILField f -> Some f.DeclaringTyconRef + +and FSharpAnonRecordTypeDetails(cenv: SymbolEnv, anonInfo: AnonRecdTypeInfo) = + member __.Assembly = FSharpAssembly (cenv, anonInfo.Assembly) + + /// Names of any enclosing types of the compiled form of the anonymous type (if the anonymous type was defined as a nested type) + member __.EnclosingCompiledTypeNames = anonInfo.ILTypeRef.Enclosing + + /// The name of the compiled form of the anonymous type + member __.CompiledName = anonInfo.ILTypeRef.Name + + /// The sorted labels of the anonymous type + member __.SortedFieldNames = anonInfo.SortedNames and FSharpField(cenv: SymbolEnv, d: FSharpFieldData) = inherit FSharpSymbol (cenv, (fun () -> match d with + | AnonField (anonInfo, tinst, n, m) -> + Item.AnonRecdField(anonInfo, tinst, n, m) | RecdOrClass v -> checkEntityIsResolved v.TyconRef Item.RecdField(RecdFieldInfo(generalizeTypars v.TyconRef.TyparsNoRange, v)) @@ -852,20 +872,22 @@ and FSharpField(cenv: SymbolEnv, d: FSharpFieldData) = ) let isUnresolved() = - entityIsUnresolved d.DeclaringTyconRef || - match d with - | RecdOrClass v -> v.TryRecdField.IsNone - | Union (v, _) -> v.TryUnionCase.IsNone + d.TryDeclaringTyconRef |> Option.exists entityIsUnresolved || + match d with + | AnonField _ -> false + | RecdOrClass v -> ValueOptionInternal.isNone v.TryRecdField + | Union (v, _) -> ValueOptionInternal.isNone v.TryUnionCase | ILField _ -> false let checkIsResolved() = - checkEntityIsResolved d.DeclaringTyconRef + d.TryDeclaringTyconRef |> Option.iter checkEntityIsResolved match d with + | AnonField _ -> () | RecdOrClass v -> - if v.TryRecdField.IsNone then + if ValueOptionInternal.isNone v.TryRecdField then invalidOp (sprintf "The record field '%s' could not be found in the target type" v.FieldName) | Union (v, _) -> - if v.TryUnionCase.IsNone then + if ValueOptionInternal.isNone v.TryUnionCase then invalidOp (sprintf "The union case '%s' could not be found in the target type" v.CaseName) | ILField _ -> () @@ -874,7 +896,7 @@ and FSharpField(cenv: SymbolEnv, d: FSharpFieldData) = new (cenv, rfref) = FSharpField(cenv, FSharpFieldData.RecdOrClass(rfref)) member __.DeclaringEntity = - FSharpEntity(cenv, d.DeclaringTyconRef) + d.TryDeclaringTyconRef |> Option.map (fun tcref -> FSharpEntity(cenv, tcref)) member __.IsUnresolved = isUnresolved() @@ -882,32 +904,47 @@ and FSharpField(cenv: SymbolEnv, d: FSharpFieldData) = member __.IsMutable = if isUnresolved() then false else match d.TryRecdField with - | Choice1Of2 r -> r.IsMutable - | Choice2Of2 f -> not f.IsInitOnly && f.LiteralValue.IsNone + | Choice1Of3 r -> r.IsMutable + | Choice2Of3 f -> not f.IsInitOnly && f.LiteralValue.IsNone + | Choice3Of3 _ -> false member __.IsLiteral = if isUnresolved() then false else match d.TryRecdField with - | Choice1Of2 r -> r.LiteralValue.IsSome - | Choice2Of2 f -> f.LiteralValue.IsSome + | Choice1Of3 r -> r.LiteralValue.IsSome + | Choice2Of3 f -> f.LiteralValue.IsSome + | Choice3Of3 _ -> false member __.LiteralValue = if isUnresolved() then None else match d.TryRecdField with - | Choice1Of2 r -> getLiteralValue r.LiteralValue - | Choice2Of2 f -> f.LiteralValue |> Option.map AbstractIL.ILRuntimeWriter.convFieldInit + | Choice1Of3 r -> getLiteralValue r.LiteralValue + | Choice2Of3 f -> f.LiteralValue |> Option.map AbstractIL.ILRuntimeWriter.convFieldInit + | Choice3Of3 _ -> None member __.IsVolatile = if isUnresolved() then false else match d.TryRecdField with - | Choice1Of2 r -> r.IsVolatile - | Choice2Of2 _ -> false // F# doesn't actually respect "volatile" from other assemblies in any case + | Choice1Of3 r -> r.IsVolatile + | Choice2Of3 _ -> false // F# doesn't actually respect "volatile" from other assemblies in any case + | Choice3Of3 _ -> false member __.IsDefaultValue = if isUnresolved() then false else match d.TryRecdField with - | Choice1Of2 r -> r.IsZeroInit - | Choice2Of2 _ -> false + | Choice1Of3 r -> r.IsZeroInit + | Choice2Of3 _ -> false + | Choice3Of3 _ -> false + + member __.IsAnonRecordField = + match d with + | AnonField _ -> true + | _ -> false + + member __.AnonRecordFieldDetails = + match d with + | AnonField (anonInfo, types, n, _) -> FSharpAnonRecordTypeDetails(cenv, anonInfo), [| for ty in types -> FSharpType(cenv, ty) |], n + | _ -> invalidOp "not an anonymous record field" member __.XmlDocSig = checkIsResolved() @@ -921,6 +958,7 @@ and FSharpField(cenv: SymbolEnv, d: FSharpFieldData) = SymbolHelpers.GetXmlDocSigOfUnionCaseInfo unionCase | ILField f -> SymbolHelpers.GetXmlDocSigOfILFieldInfo cenv.infoReader range0 f + | AnonField _ -> None match xmlsig with | Some (_, docsig) -> docsig | _ -> "" @@ -928,68 +966,77 @@ and FSharpField(cenv: SymbolEnv, d: FSharpFieldData) = member __.XmlDoc = if isUnresolved() then XmlDoc.Empty |> makeXmlDoc else match d.TryRecdField with - | Choice1Of2 r -> r.XmlDoc - | Choice2Of2 _ -> XmlDoc.Empty + | Choice1Of3 r -> r.XmlDoc + | Choice2Of3 _ -> XmlDoc.Empty + | Choice3Of3 _ -> XmlDoc.Empty |> makeXmlDoc member __.FieldType = checkIsResolved() let fty = match d.TryRecdField with - | Choice1Of2 r -> r.FormalType - | Choice2Of2 f -> f.FieldType(cenv.amap, range0) + | Choice1Of3 r -> r.FormalType + | Choice2Of3 f -> f.FieldType(cenv.amap, range0) + | Choice3Of3 (_,tinst,n,_) -> tinst.[n] FSharpType(cenv, fty) member __.IsStatic = if isUnresolved() then false else match d.TryRecdField with - | Choice1Of2 r -> r.IsStatic - | Choice2Of2 f -> f.IsStatic + | Choice1Of3 r -> r.IsStatic + | Choice2Of3 f -> f.IsStatic + | Choice3Of3 _ -> false member __.Name = checkIsResolved() match d.TryRecdField with - | Choice1Of2 r -> r.Name - | Choice2Of2 f -> f.FieldName + | Choice1Of3 r -> r.Name + | Choice2Of3 f -> f.FieldName + | Choice3Of3 (anonInfo, _tinst, n, _) -> anonInfo.SortedNames.[n] member __.IsCompilerGenerated = if isUnresolved() then false else match d.TryRecdField with - | Choice1Of2 r -> r.IsCompilerGenerated - | Choice2Of2 _ -> false + | Choice1Of3 r -> r.IsCompilerGenerated + | Choice2Of3 _ -> false + | Choice3Of3 _ -> false member __.IsNameGenerated = if isUnresolved() then false else match d.TryRecdField with - | Choice1Of2 r -> r.rfield_name_generated + | Choice1Of3 r -> r.rfield_name_generated | _ -> false member __.DeclarationLocation = checkIsResolved() match d.TryRecdField with - | Choice1Of2 r -> r.Range - | Choice2Of2 _ -> range0 + | Choice1Of3 r -> r.Range + | Choice2Of3 _ -> range0 + | Choice3Of3 (_anonInfo, _tinst, _n, m) -> m member __.FieldAttributes = if isUnresolved() then makeReadOnlyCollection [] else match d.TryRecdField with - | Choice1Of2 r -> r.FieldAttribs |> List.map (fun a -> FSharpAttribute(cenv, AttribInfo.FSAttribInfo(cenv.g, a))) - | Choice2Of2 _ -> [] + | Choice1Of3 r -> r.FieldAttribs |> List.map (fun a -> FSharpAttribute(cenv, AttribInfo.FSAttribInfo(cenv.g, a))) + | Choice2Of3 _ -> [] + | Choice3Of3 _ -> [] |> makeReadOnlyCollection member __.PropertyAttributes = if isUnresolved() then makeReadOnlyCollection [] else match d.TryRecdField with - | Choice1Of2 r -> r.PropertyAttribs |> List.map (fun a -> FSharpAttribute(cenv, AttribInfo.FSAttribInfo(cenv.g, a))) - | Choice2Of2 _ -> [] + | Choice1Of3 r -> r.PropertyAttribs |> List.map (fun a -> FSharpAttribute(cenv, AttribInfo.FSAttribInfo(cenv.g, a))) + | Choice2Of3 _ -> [] + | Choice3Of3 _ -> [] |> makeReadOnlyCollection member __.Accessibility: FSharpAccessibility = if isUnresolved() then FSharpAccessibility(taccessPublic) else let access = match d.TryRecdField with - | Choice1Of2 r -> r.Accessibility - | Choice2Of2 _ -> taccessPublic + | Choice1Of3 r -> r.Accessibility + | Choice2Of3 _ -> taccessPublic + | Choice3Of3 _ -> taccessPublic FSharpAccessibility(access) member private x.V = d @@ -1001,6 +1048,7 @@ and FSharpField(cenv: SymbolEnv, d: FSharpFieldData) = match d, uc.V with | RecdOrClass r1, RecdOrClass r2 -> recdFieldRefOrder.Compare(r1, r2) = 0 | Union (u1, n1), Union (u2, n2) -> cenv.g.unionCaseRefEq u1 u2 && n1 = n2 + | AnonField (anonInfo1, _, _, _) , AnonField (anonInfo2, _, _, _) -> x.Name = uc.Name && anonInfoEquiv anonInfo1 anonInfo2 | _ -> false | _ -> false @@ -1331,7 +1379,7 @@ and FSharpMemberOrFunctionOrValue(cenv, d:FSharpMemberOrValData, item) = let isUnresolved() = match fsharpInfo() with | None -> false - | Some v -> v.TryDeref.IsNone + | Some v -> ValueOptionInternal.isNone v.TryDeref let checkIsResolved() = if isUnresolved() then @@ -2032,6 +2080,7 @@ and FSharpType(cenv, ty:TType) = member __.GenericArguments = protect <| fun () -> match stripTyparEqns ty with + | TType_anon (_, tyargs) | TType_app (_, tyargs) | TType_tuple (_, tyargs) -> (tyargs |> List.map (fun ty -> FSharpType(cenv, ty)) |> makeReadOnlyCollection) | TType_fun(d, r) -> [| FSharpType(cenv, d); FSharpType(cenv, r) |] |> makeReadOnlyCollection @@ -2063,6 +2112,19 @@ and FSharpType(cenv, ty:TType) = | TType_fun _ -> true | _ -> false + member __.IsAnonRecordType = + isResolved() && + protect <| fun () -> + match stripTyparEqns ty with + | TType_anon _ -> true + | _ -> false + + member __.AnonRecordTypeDetails = + protect <| fun () -> + match stripTyparEqns ty with + | TType_anon (anonInfo, _) -> FSharpAnonRecordTypeDetails(cenv, anonInfo) + | _ -> invalidOp "not an anonymous record type" + member __.IsGenericParameter = protect <| fun () -> match stripTyparEqns ty with @@ -2117,6 +2179,7 @@ and FSharpType(cenv, ty:TType) = | TType_tuple (_, l1) -> 10400 + List.sumBy hashType l1 | TType_fun (dty, rty) -> 10500 + hashType dty + hashType rty | TType_measure _ -> 10600 + | TType_anon (_,l1) -> 10800 + List.sumBy hashType l1 hashType ty member x.Format(denv: FSharpDisplayContext) = diff --git a/src/fsharp/symbols/Symbols.fsi b/src/fsharp/symbols/Symbols.fsi index 7b7f565fdc..3f3a3f0e0e 100644 --- a/src/fsharp/symbols/Symbols.fsi +++ b/src/fsharp/symbols/Symbols.fsi @@ -401,7 +401,20 @@ and [] public FSharpUnionCase = /// Indicates if the union case is for a type in an unresolved assembly member IsUnresolved : bool +/// A subtype of FSharpSymbol that represents a record or union case field as seen by the F# language +and [] public FSharpAnonRecordTypeDetails = + + /// The assembly where the compiled form of the anonymous type is defined + member Assembly : FSharpAssembly + + /// Names of any enclosing types of the compiled form of the anonymous type (if the anonymous type was defined as a nested type) + member EnclosingCompiledTypeNames : string list + + /// The name of the compiled form of the anonymous type + member CompiledName : string + /// The sorted labels of the anonymous type + member SortedFieldNames : string[] /// A subtype of FSharpSymbol that represents a record or union case field as seen by the F# language and [] public FSharpField = @@ -410,8 +423,14 @@ and [] public FSharpField = internal new : SymbolEnv * RecdFieldRef -> FSharpField internal new : SymbolEnv * UnionCaseRef * int -> FSharpField - /// Get the declaring entity of this field - member DeclaringEntity: FSharpEntity + /// Get the declaring entity of this field, if any. Fields from anonymous types do not have a declaring entity + member DeclaringEntity: FSharpEntity option + + /// Is this a field from an anonymous record type? + member IsAnonRecordField: bool + + /// If the field is from an anonymous record type then get the details of the field including the index in the sorted array of fields + member AnonRecordFieldDetails: FSharpAnonRecordTypeDetails * FSharpType[] * int /// Indicates if the field is declared 'static' member IsMutable: bool @@ -934,6 +953,12 @@ and [] public FSharpType = /// Indicates if the type is a function type. The GenericArguments property returns the domain and range of the function type. member IsFunctionType : bool + /// Indicates if the type is an anonymous record type. The GenericArguments property returns the type instantiation of the anonymous record type + member IsAnonRecordType: bool + + /// Get the details of the anonymous record type. + member AnonRecordTypeDetails: FSharpAnonRecordTypeDetails + /// Indicates if the type is a variable type, whether declared, generalized or an inference type parameter member IsGenericParameter : bool diff --git a/src/fsharp/tast.fs b/src/fsharp/tast.fs index 27130dc085..63e7412d90 100644 --- a/src/fsharp/tast.fs +++ b/src/fsharp/tast.fs @@ -261,7 +261,7 @@ type ValFlags(flags:int64) = (flags &&& ~~~0b0011001100000000000L) /// Represents the kind of a type parameter -[] +[] type TyparKind = | Type @@ -270,13 +270,13 @@ type TyparKind = member x.AttrName = match x with - | TyparKind.Type -> None - | TyparKind.Measure -> Some "Measure" + | TyparKind.Type -> ValueNone + | TyparKind.Measure -> ValueSome "Measure" - [] - member x.DebugText = x.ToString() + //[] + //member x.DebugText = x.ToString() - override x.ToString() = + override x.ToString() = match x with | TyparKind.Type -> "type" | TyparKind.Measure -> "measure" @@ -480,10 +480,11 @@ let KeyTyconByDemangledNameAndArity nm (typars: _ list) x = /// Generic types can be accessed either by 'List' or 'List`1'. This lists both keys. The second form should really be deprecated. let KeyTyconByAccessNames nm x = - if IsMangledGenericName nm then - let dnm = DemangleGenericTypeName nm + match TryDemangleGenericNameAndPos nm with + | ValueSome pos -> + let dnm = DemangleGenericTypeNameWithPos pos nm [| KeyValuePair(nm,x); KeyValuePair(dnm,x) |] - else + | _ -> [| KeyValuePair(nm,x) |] type ModuleOrNamespaceKind = @@ -965,14 +966,14 @@ and /// Represents a type definition, exception definition, module definition or /// Get the union cases and other union-type information for a type, if any member x.UnionTypeInfo = match x.TypeReprInfo with - | TUnionRepr x -> Some x - | _ -> None + | TUnionRepr x -> ValueSome x + | _ -> ValueNone /// Get the union cases for a type, if any member x.UnionCasesArray = match x.UnionTypeInfo with - | Some x -> x.CasesTable.CasesByIndex - | None -> [| |] + | ValueSome x -> x.CasesTable.CasesByIndex + | ValueNone -> [| |] /// Get the union cases for a type, if any, as a list member x.UnionCasesAsList = x.UnionCasesArray |> Array.toList @@ -980,8 +981,8 @@ and /// Represents a type definition, exception definition, module definition or /// Get a union case of a type by name member x.GetUnionCaseByName n = match x.UnionTypeInfo with - | Some x -> NameMap.tryFind n x.CasesTable.CasesByName - | None -> None + | ValueSome x -> NameMap.tryFind n x.CasesTable.CasesByName + | ValueNone -> None /// Create a new entity with empty, unlinked data. Only used during unpickling of F# metadata. @@ -1349,7 +1350,7 @@ and override x.ToString() = "TyconAugmentation(...)" and - [] + [] /// The information for the contents of a type. Also used for a provided namespace. TyconRepresentation = @@ -1393,10 +1394,10 @@ and /// The information for exception definitions should be folded into here. | TNoRepr - [] - member x.DebugText = x.ToString() + //[] + //member x.DebugText = x.ToString() - override x.ToString() = "TyconRepresentation(...)" + override x.ToString() = sprintf "%+A" x and [] @@ -1751,7 +1752,7 @@ and override x.ToString() = x.Name and - [] + [] ExceptionInfo = /// Indicates that an exception is an abbreviation for the given exception | TExnAbbrevRepr of TyconRef @@ -1765,10 +1766,11 @@ and /// Indicates that an exception is abstract, i.e. is in a signature file, and we do not know the representation | TExnNone - [] - member x.DebugText = x.ToString() + // %+A formatting is used, so this is not needed + //[] + //member x.DebugText = x.ToString() - override x.ToString() = "ExceptionInfo(...)" + override x.ToString() = sprintf "%+A" x and [] ModuleOrNamespaceType(kind: ModuleOrNamespaceKind, vals: QueueList, entities: QueueList) = @@ -1899,7 +1901,7 @@ and [] |> List.tryFind (fun v -> match key.TypeForLinkage with | None -> true | Some keyTy -> ccu.MemberSignatureEquality(keyTy,v.Type)) - |> ValueOption.ofOption + |> ValueOptionInternal.ofOption /// Get a table of values indexed by logical name member mtyp.AllValsByLogicalName = @@ -2340,11 +2342,11 @@ and /// Indicates a constraint that a type is .NET unmanaged type | IsUnmanaged of range - // Prefer the default formatting of this union type + // %+A formatting is used, so this is not needed //[] //member x.DebugText = x.ToString() - // - //override x.ToString() = "TyparConstraint(...)" + + override x.ToString() = sprintf "%+A" x /// The specification of a member constraint that must be solved and @@ -2374,7 +2376,7 @@ and override x.ToString() = "TTrait(" + x.MemberName + ")" and - [] + [] /// Indicates the solution of a member constraint during inference. TraitConstraintSln = @@ -2394,6 +2396,9 @@ and /// isSetProp -- indicates if this is a set of a record field | FSRecdFieldSln of TypeInst * RecdFieldRef * bool + /// Indicates a trait is solved by an F# anonymous record field. + | FSAnonRecdFieldSln of AnonRecdTypeInfo * TypeInst * int + /// ILMethSln(ty, extOpt, ilMethodRef, minst) /// /// Indicates a trait is solved by a .NET method. @@ -2411,10 +2416,11 @@ and /// Indicates a trait is solved by a 'fake' instance of an operator, like '+' on integers | BuiltInSln - [] - member x.DebugText = x.ToString() + // %+A formatting is used, so this is not needed + //[] + //member x.DebugText = x.ToString() - override x.ToString() = "TraitConstraintSln(...)" + override x.ToString() = sprintf "%+A" x /// The partial information used to index the methods of all those in a ModuleOrNamespace. and [] @@ -3043,13 +3049,12 @@ and static member TryDerefEntityPath(ccu: CcuThunk, path:string[], i:int, entity:Entity) = if i >= path.Length then ValueSome entity else - let next = entity.ModuleOrNamespaceType.AllEntitiesByCompiledAndLogicalMangledNames.TryFind(path.[i]) - match next with - | Some res -> NonLocalEntityRef.TryDerefEntityPath(ccu, path, (i+1), res) + match entity.ModuleOrNamespaceType.AllEntitiesByCompiledAndLogicalMangledNames.TryGetValue path.[i] with + | true, res -> NonLocalEntityRef.TryDerefEntityPath(ccu, path, (i+1), res) #if !NO_EXTENSIONTYPING - | None -> NonLocalEntityRef.TryDerefEntityPathViaProvidedType(ccu, path, i, entity) + | _ -> NonLocalEntityRef.TryDerefEntityPathViaProvidedType(ccu, path, i, entity) #else - | None -> ValueNone + | _ -> ValueNone #endif #if !NO_EXTENSIONTYPING @@ -3258,7 +3263,7 @@ and ValueSome tcr.binding /// Is the destination assembly available? - member tcr.CanDeref = tcr.TryDeref.IsSome + member tcr.CanDeref = ValueOptionInternal.isSome tcr.TryDeref /// Gets the data indicating the compiled representation of a type or module in terms of Abstract IL data structures. member x.CompiledRepresentation = x.Deref.CompiledRepresentation @@ -3809,7 +3814,7 @@ and | None -> error(InternalError(sprintf "union case %s not found in type %s" x.CaseName x.TyconRef.LogicalName, x.TyconRef.Range)) /// Try to dereference the reference - member x.TryUnionCase = x.TyconRef.TryDeref |> ValueOption.bind (fun tcref -> tcref.GetUnionCaseByName x.CaseName |> ValueOption.ofOption) + member x.TryUnionCase = x.TyconRef.TryDeref |> ValueOptionInternal.bind (fun tcref -> tcref.GetUnionCaseByName x.CaseName |> ValueOptionInternal.ofOption) /// Get the attributes associated with the union case member x.Attribs = x.UnionCase.Attribs @@ -3868,7 +3873,7 @@ and | None -> error(InternalError(sprintf "field %s not found in type %s" id tcref.LogicalName, tcref.Range)) /// Try to dereference the reference - member x.TryRecdField = x.TyconRef.TryDeref |> ValueOption.bind (fun tcref -> tcref.GetFieldByName x.FieldName |> ValueOption.ofOption) + member x.TryRecdField = x.TyconRef.TryDeref |> ValueOptionInternal.bind (fun tcref -> tcref.GetFieldByName x.FieldName |> ValueOptionInternal.ofOption) /// Get the attributes associated with the compiled property of the record field member x.PropertyAttribs = x.RecdField.PropertyAttribs @@ -3910,6 +3915,11 @@ and /// Indicates the type is built from a named type and a number of type arguments | TType_app of TyconRef * TypeInst + /// TType_anon + /// + /// Indicates the type is an anonymous record type whose compiled representation is located in the given assembly + | TType_anon of AnonRecdTypeInfo * TType list + /// TType_tuple(elementTypes). /// /// Indicates the type is a tuple type. elementTypes must be of length 2 or greater. @@ -3940,6 +3950,7 @@ and | TType_forall (_tps, ty) -> ty.GetAssemblyName() | TType_app (tcref, _tinst) -> tcref.CompilationPath.ILScopeRef.QualifiedName | TType_tuple (_tupInfo, _tinst) -> "" + | TType_anon (anonInfo, _tinst) -> defaultArg anonInfo.Assembly.QualifiedName "" | TType_fun (_d,_r) -> "" | TType_measure _ms -> "" | TType_var tp -> tp.Solution |> function Some sln -> sln.GetAssemblyName() | None -> "" @@ -3958,7 +3969,12 @@ and (match tupInfo with | TupInfo.Const false -> "" | TupInfo.Const true -> "struct ") - + String.concat "," (List.map string tinst) + ")" + + String.concat "," (List.map string tinst) + | TType_anon (anonInfo, tinst) -> + (match anonInfo.TupInfo with + | TupInfo.Const false -> "" + | TupInfo.Const true -> "struct ") + + "{|" + String.concat "," (Seq.map2 (fun nm ty -> nm + " " + string ty + ";") anonInfo.SortedNames tinst) + ")" + "|}" | TType_fun (d,r) -> "(" + string d + " -> " + string r + ")" | TType_ucase (uc,tinst) -> "ucase " + uc.CaseName + (match tinst with [] -> "" | tys -> "<" + String.concat "," (List.map string tys) + ">") | TType_var tp -> @@ -3970,7 +3986,50 @@ and and TypeInst = TType list and TTypes = TType list - +and [] AnonRecdTypeInfo = + // Mutability for pickling/unpickling only + { mutable Assembly: CcuThunk + mutable TupInfo: TupInfo + mutable SortedIds: Ident[] + mutable Stamp: Stamp + mutable SortedNames: string[] } + + /// Create an AnonRecdTypeInfo from the basic data + static member Create(ccu: CcuThunk, tupInfo, ids: Ident[]) = + let sortedIds = ids |> Array.sortBy (fun id -> id.idText) + // Hash all the data to form a unique stamp + let stamp = + sha1HashInt64 + [| for c in ccu.AssemblyName do yield byte c; yield byte (int32 c >>> 8); + match tupInfo with + | TupInfo.Const b -> yield (if b then 0uy else 1uy) + for id in sortedIds do + for c in id.idText do yield byte c; yield byte (int32 c >>> 8) |] + let sortedNames = Array.map textOfId sortedIds + { Assembly = ccu; TupInfo = tupInfo; SortedIds = sortedIds; Stamp = stamp; SortedNames = sortedNames } + + /// Get the ILTypeRef for the generated type implied by the anonymous type + member x.ILTypeRef = + let ilTypeName = sprintf "<>f__AnonymousType%s%u`%d'" (match x.TupInfo with TupInfo.Const b -> if b then "1000" else "") (uint32 x.Stamp) x.SortedIds.Length + mkILTyRef(x.Assembly.ILScopeRef,ilTypeName) + + static member NewUnlinked() : AnonRecdTypeInfo = + { Assembly = Unchecked.defaultof<_> + TupInfo = Unchecked.defaultof<_> + SortedIds = Unchecked.defaultof<_> + Stamp = Unchecked.defaultof<_> + SortedNames = Unchecked.defaultof<_> } + + member x.Link d = + let sortedNames = Array.map textOfId d.SortedIds + x.Assembly <- d.Assembly + x.TupInfo <- d.TupInfo + x.SortedIds <- d.SortedIds + x.Stamp <- d.Stamp + x.SortedNames <- sortedNames + + member x.IsLinked = (match x.SortedIds with null -> true | _ -> false) + and [] TupInfo = /// Some constant, e.g. true or false for tupInfo | Const of bool @@ -3996,11 +4055,11 @@ and /// Raising a measure to a rational power | RationalPower of Measure * Rational - // Prefer the default formatting of this union type + // %+A formatting is used, so this is not needed //[] //member x.DebugText = x.ToString() - // - //override x.ToString() = "Measure(...)" + + override x.ToString() = sprintf "%+A" x and [] @@ -4196,9 +4255,10 @@ and /// Try to resolve a path into the CCU by referencing the .NET/CLI type forwarder table of the CCU member ccu.TryForward(nlpath:string[],item:string) : EntityRef option = ccu.EnsureDerefable(nlpath) - match ccu.TypeForwarders.TryFind(nlpath,item) with - | Some entity -> Some(entity.Force()) - | None -> None + let key = nlpath,item + match ccu.TypeForwarders.TryGetValue key with + | true, entity -> Some(entity.Force()) + | _ -> None //printfn "trying to forward %A::%s from ccu '%s', res = '%A'" p n ccu.AssemblyName res.IsSome /// Used to make forward calls into the type/assembly loader when comparing member signatures during linking @@ -4249,7 +4309,7 @@ and and Attribs = Attrib list and - [] + [] AttribKind = /// Indicates an attribute refers to a type defined in an imported .NET assembly @@ -4258,10 +4318,11 @@ and /// Indicates an attribute refers to a type defined in an imported F# assembly | FSAttrib of ValRef - [] - member x.DebugText = x.ToString() + // %+A formatting is used, so this is not needed + //[] + //member x.DebugText = x.ToString() - override x.ToString() = sprintf "AttribKind(...)" + override x.ToString() = sprintf "%+A" x /// Attrib(kind,unnamedArgs,propVal,appliedToAGetterOrSetter,targetsOpt,range) and @@ -4325,10 +4386,11 @@ and [] /// Decision trees. Pattern matching has been compiled down to /// a decision tree by this point. The right-hand-sides (actions) of +/// a decision tree by this point. The right-hand-sides (actions) of /// the decision tree are labelled by integers that are unique for that /// particular tree. and - [] + [] DecisionTree = /// TDSwitch(input, cases, default, range) @@ -4357,10 +4419,11 @@ and /// body -- the rest of the decision tree | TDBind of Binding * DecisionTree - [] - member x.DebugText = x.ToString() + // %+A formatting is used, so this is not needed + //[] + //member x.DebugText = x.ToString() - override x.ToString() = sprintf "DecisionTree(...)" + override x.ToString() = sprintf "%+A" x /// Represents a test and a subsequent decision tree and @@ -4380,7 +4443,7 @@ and override x.ToString() = sprintf "DecisionTreeCase(...)" and - [] + [] DecisionTreeTest = /// Test if the input to a decision tree matches the given union case | UnionCase of UnionCaseRef * TypeInst @@ -4410,10 +4473,11 @@ and /// activePatternInfo -- The extracted info for the active pattern. | ActivePatternCase of Expr * TTypes * (ValRef * TypeInst) option * int * ActivePatternInfo - [] - member x.DebugText = x.ToString() + // %+A formatting is used, so this is not needed + //[] + //member x.DebugText = x.ToString() - override x.ToString() = sprintf "DecisionTreeTest(...)" + override x.ToString() = sprintf "%+A" x /// A target of a decision tree. Can be thought of as a little function, though is compiled as a local block. and @@ -4644,6 +4708,12 @@ and /// An operation representing the creation of a tuple value | Tuple of TupInfo + /// An operation representing the creation of an anonymous record + | AnonRecd of AnonRecdTypeInfo + + /// An operation representing the get of a property from an anonymous record + | AnonRecdGet of AnonRecdTypeInfo * int + /// An operation representing the creation of an array value | Array @@ -4907,7 +4977,7 @@ and /// The contents of a module-or-namespace-fragment definition and - [] + [] ModuleOrNamespaceExpr = /// Indicates the module is a module with a signature | TMAbstract of ModuleOrNamespaceExprWithSig @@ -4924,10 +4994,11 @@ and /// Indicates the module fragment is a 'rec' or 'non-rec' definition of types and modules | TMDefRec of isRec:bool * Tycon list * ModuleOrNamespaceBinding list * range - [] + // %+A formatting is used, so this is not needed + //[] member x.DebugText = x.ToString() - override x.ToString() = "ModuleOrNamespaceExpr(...)" + override x.ToString() = sprintf "%+A" x /// A named module-or-namespace-fragment definition and @@ -4954,7 +5025,7 @@ and and [] TypedImplFile = - | TImplFile of QualifiedNameOfFile * ScopedPragma list * ModuleOrNamespaceExprWithSig * bool * bool + | TImplFile of QualifiedNameOfFile * ScopedPragma list * ModuleOrNamespaceExprWithSig * bool * bool * StampMap [] member x.DebugText = x.ToString() @@ -5128,6 +5199,7 @@ let arityOfVal (v:Val) = (match v.ValReprInfo with None -> ValReprInfo.emptyValD let tupInfoRef = TupInfo.Const false let tupInfoStruct = TupInfo.Const true +let mkTupInfo b = if b then tupInfoStruct else tupInfoRef let structnessDefault = false let mkRawRefTupleTy tys = TType_tuple (tupInfoRef, tys) let mkRawStructTupleTy tys = TType_tuple (tupInfoStruct, tys) @@ -5137,9 +5209,9 @@ let mkRawStructTupleTy tys = TType_tuple (tupInfoStruct, tys) // make up the entire compilation unit //--------------------------------------------------------------------------- -let mapTImplFile f (TImplFile(fragName,pragmas,moduleExpr,hasExplicitEntryPoint,isScript)) = TImplFile(fragName, pragmas,f moduleExpr,hasExplicitEntryPoint,isScript) -let mapAccImplFile f z (TImplFile(fragName,pragmas,moduleExpr,hasExplicitEntryPoint,isScript)) = let moduleExpr,z = f z moduleExpr in TImplFile(fragName,pragmas,moduleExpr,hasExplicitEntryPoint,isScript), z -let foldTImplFile f z (TImplFile(_,_,moduleExpr,_,_)) = f z moduleExpr +let mapTImplFile f (TImplFile(fragName,pragmas,moduleExpr,hasExplicitEntryPoint,isScript,anonRecdTypes)) = TImplFile(fragName, pragmas,f moduleExpr,hasExplicitEntryPoint,isScript,anonRecdTypes) +let mapAccImplFile f z (TImplFile(fragName,pragmas,moduleExpr,hasExplicitEntryPoint,isScript,anonRecdTypes)) = let moduleExpr,z = f z moduleExpr in TImplFile(fragName,pragmas,moduleExpr,hasExplicitEntryPoint,isScript,anonRecdTypes), z +let foldTImplFile f z (TImplFile(_,_,moduleExpr,_,_,_)) = f z moduleExpr //--------------------------------------------------------------------------- // Equality relations on locally defined things @@ -5415,7 +5487,7 @@ let fslibValRefEq fslibCcu vref1 vref2 = // is not significant nlr1.ItemKey.PartialKey = nm2.PartialKey && fslibRefEq nlr1.EnclosingEntity.nlr pp2 - | None -> + | _ -> false // Note: I suspect this private-to-private reference comparison is not needed | (VRefLocal e1, VRefLocal e2) -> @@ -5439,9 +5511,9 @@ let primEntityRefEq compilingFslib fslibCcu (x : EntityRef) (y : EntityRef) = // The tcrefs may have forwarders. If they may possibly be equal then resolve them to get their canonical references // and compare those using pointer equality. (not (nonLocalRefDefinitelyNotEq x.nlr y.nlr) && - let v1 = x.TryDeref - let v2 = y.TryDeref - v1.IsSome && v2.IsSome && v1.Value === v2.Value)) then + match x.TryDeref with + | ValueSome v1 -> match y.TryDeref with ValueSome v2 -> v1 === v2 | _ -> false + | _ -> match y.TryDeref with ValueNone -> true | _ -> false)) then true else compilingFslib && fslibEntityRefEq fslibCcu x y @@ -5465,9 +5537,9 @@ let primValRefEq compilingFslib fslibCcu (x : ValRef) (y : ValRef) = else (// Use TryDeref to guard against the platforms/times when certain F# language features aren't available, // e.g. CompactFramework doesn't have support for quotations. - let v1 = x.TryDeref - let v2 = y.TryDeref - v1.IsSome && v2.IsSome && v1.Value === v2.Value) + match x.TryDeref with + | ValueSome v1 -> match y.TryDeref with ValueSome v2 -> v1 === v2 | _ -> false + | _ -> match y.TryDeref with ValueNone -> true | _ -> false) || (if compilingFslib then fslibValRefEq fslibCcu x y else false) //--------------------------------------------------------------------------- @@ -5711,13 +5783,13 @@ let CombineCcuContentFragments m l = let tab2 = mty2.AllEntitiesByLogicalMangledName let entities = [ for e1 in mty1.AllEntities do - match tab2.TryFind e1.LogicalName with - | Some e2 -> yield CombineEntites path e1 e2 - | None -> yield e1 + match tab2.TryGetValue e1.LogicalName with + | true, e2 -> yield CombineEntites path e1 e2 + | _ -> yield e1 for e2 in mty2.AllEntities do - match tab1.TryFind e2.LogicalName with - | Some _ -> () - | None -> yield e2 ] + match tab1.TryGetValue e2.LogicalName with + | true, _ -> () + | _ -> yield e2 ] let vals = QueueList.append mty1.AllValsAndMembers mty2.AllValsAndMembers @@ -5767,3 +5839,4 @@ let FSharpOptimizationDataResourceName2 = "FSharpOptimizationInfo." let FSharpSignatureDataResourceName2 = "FSharpSignatureInfo." + diff --git a/src/ilx/ilxsettings.fs b/src/ilx/ilxsettings.fs index 9033fca069..520da651c1 100755 --- a/src/ilx/ilxsettings.fs +++ b/src/ilx/ilxsettings.fs @@ -22,7 +22,7 @@ let ilxFsharpCoreLibScopeRef () = if !ilxCompilingFSharpCoreLib then ILScopeRef.Local else - let assref = + let assemblyRef = match !ilxFsharpCoreLibAssemRef with | Some o -> o | None -> @@ -34,6 +34,6 @@ let ilxFsharpCoreLibScopeRef () = Some (PublicKeyToken(Bytes.ofInt32Array [| 0xb0; 0x3f; 0x5f; 0x7f; 0x11; 0xd5; 0x0a; 0x3a |])), false, Some (IL.parseILVersion "0.0.0.0"), None) - ILScopeRef.Assembly assref + ILScopeRef.Assembly assemblyRef let ilxNamespace () = "Microsoft.FSharp.Core" \ No newline at end of file diff --git a/src/scripts/fssrgen.fsx b/src/scripts/fssrgen.fsx deleted file mode 100644 index 32c5b4fa58..0000000000 --- a/src/scripts/fssrgen.fsx +++ /dev/null @@ -1,494 +0,0 @@ -// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. -open System -open System.IO - -let PrintErr(filename, line, msg) = - printfn "%s(%d): error : %s" filename line msg - -let Err(filename, line, msg) = - PrintErr(filename, line, msg) - printfn "Note that the syntax of each line is one of these three alternatives:" - printfn "# comment" - printfn "ident,\"string\"" - printfn "errNum,ident,\"string\"" - failwith (sprintf "there were errors in the file '%s'" filename) - -let xmlBoilerPlateString = @" - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - -" - - -type HoleType = string - - -// The kinds of 'holes' we can do -let ComputeHoles filename lineNum (txt:string) : ResizeArray * string = - // takes in a %d%s kind of string, returns array of HoleType and {0}{1} kind of string - let mutable i = 0 - let mutable holeNumber = 0 - let mutable holes = ResizeArray() // order - let sb = new System.Text.StringBuilder() - let AddHole holeType = - sb.Append(sprintf "{%d}" holeNumber) |> ignore - holeNumber <- holeNumber + 1 - holes.Add(holeType) - while i < txt.Length do - if txt.[i] = '%' then - if i+1 = txt.Length then - Err(filename, lineNum, "(at end of string) % must be followed by d, f, s, or %") - else - match txt.[i+1] with - | 'd' -> AddHole "System.Int32" - | 'f' -> AddHole "System.Double" - | 's' -> AddHole "System.String" - | '%' -> sb.Append('%') |> ignore - | c -> Err(filename, lineNum, sprintf "'%%%c' is not a valid sequence, only %%d %%f %%s or %%%%" c) - i <- i + 2 - else - match txt.[i] with - | '{' -> sb.Append "{{" |> ignore - | '}' -> sb.Append "}}" |> ignore - | c -> sb.Append c |> ignore - i <- i + 1 - //printfn "holes.Length = %d, lineNum = %d" holes.Length //lineNum txt - (holes, sb.ToString()) - -let Unquote (s : string) = - if s.StartsWith "\"" && s.EndsWith "\"" then s.Substring(1, s.Length - 2) - else failwith "error message string should be quoted" - -let ParseLine filename lineNum (txt:string) = - let mutable errNum = None - let identB = new System.Text.StringBuilder() - let mutable i = 0 - // parse optional error number - if i < txt.Length && System.Char.IsDigit txt.[i] then - let numB = new System.Text.StringBuilder() - while i < txt.Length && System.Char.IsDigit txt.[i] do - numB.Append txt.[i] |> ignore - i <- i + 1 - errNum <- Some(int (numB.ToString())) - if i = txt.Length || not(txt.[i] = ',') then - Err(filename, lineNum, sprintf "After the error number '%d' there should be a comma" errNum.Value) - // Skip the comma - i <- i + 1 - // parse short identifier - if i < txt.Length && not(System.Char.IsLetter(txt.[i])) then - Err(filename, lineNum, sprintf "The first character in the short identifier should be a letter, but found '%c'" txt.[i]) - while i < txt.Length && System.Char.IsLetterOrDigit txt.[i] do - identB.Append txt.[i] |> ignore - i <- i + 1 - let ident = identB.ToString() - if ident.Length = 0 then - Err(filename, lineNum, "Did not find the short identifier") - else - if i = txt.Length || not(txt.[i] = ',') then - Err(filename, lineNum, sprintf "After the identifier '%s' there should be a comma" ident) - else - // Skip the comma - i <- i + 1 - if i = txt.Length then - Err(filename, lineNum, sprintf "After the identifier '%s' and comma, there should be the quoted string resource" ident) - else - let str = - try - System.String.Format(Unquote(txt.Substring i)) // Format turns e.g '\n' into that char, but also requires that we 'escape' curlies in the original .txt file, e.g. "{{" - with - e -> Err(filename, lineNum, sprintf "Error calling System.String.Format (note that curly braces must be escaped, and there cannot be trailing space on the line): >>>%s<<< -- %s" (txt.Substring i) e.Message) - let holes, netFormatString = ComputeHoles filename lineNum str - (lineNum, (errNum,ident), str, holes.ToArray(), netFormatString) - -let stringBoilerPlatePrefix = @" -open Microsoft.FSharp.Core.LanguagePrimitives.IntrinsicOperators -open Microsoft.FSharp.Reflection -open System.Reflection -// (namespaces below for specific case of using the tool to compile FSharp.Core itself) -open Microsoft.FSharp.Core -open Microsoft.FSharp.Core.Operators -open Microsoft.FSharp.Text -open Microsoft.FSharp.Collections -open Printf -" -let StringBoilerPlate filename = - - @" - // BEGIN BOILERPLATE - - static let getCurrentAssembly () = - #if FX_RESHAPED_REFLECTION - typeof.GetTypeInfo().Assembly - #else - System.Reflection.Assembly.GetExecutingAssembly() - #endif - - static let getTypeInfo (t: System.Type) = - #if FX_RESHAPED_REFLECTION - t.GetTypeInfo() - #else - t - #endif - - static let resources = lazy (new System.Resources.ResourceManager(""" + filename + @""", getCurrentAssembly())) - - static let GetString(name:string) = - let s = resources.Value.GetString(name, System.Globalization.CultureInfo.CurrentUICulture) - #if DEBUG - if null = s then - System.Diagnostics.Debug.Assert(false, sprintf ""**RESOURCE ERROR**: Resource token %s does not exist!"" name) - #endif - s - - static let mkFunctionValue (tys: System.Type[]) (impl:obj->obj) = - FSharpValue.MakeFunction(FSharpType.MakeFunctionType(tys.[0],tys.[1]), impl) - - static let funTyC = typeof<(obj -> obj)>.GetGenericTypeDefinition() - - static let isNamedType(ty:System.Type) = not (ty.IsArray || ty.IsByRef || ty.IsPointer) - static let isFunctionType (ty1:System.Type) = - isNamedType(ty1) && getTypeInfo(ty1).IsGenericType && (ty1.GetGenericTypeDefinition()).Equals(funTyC) - - static let rec destFunTy (ty:System.Type) = - if isFunctionType ty then - ty, ty.GetGenericArguments() - else - match getTypeInfo(ty).BaseType with - | null -> failwith ""destFunTy: not a function type"" - | b -> destFunTy b - - static let buildFunctionForOneArgPat (ty: System.Type) impl = - let _,tys = destFunTy ty - let rty = tys.[1] - // PERF: this technique is a bit slow (e.g. in simple cases, like 'sprintf ""%x""') - mkFunctionValue tys (fun inp -> impl rty inp) - - static let capture1 (fmt:string) i args ty (go : obj list -> System.Type -> int -> obj) : obj = - match fmt.[i] with - | '%' -> go args ty (i+1) - | 'd' - | 'f' - | 's' -> buildFunctionForOneArgPat ty (fun rty n -> go (n::args) rty (i+1)) - | _ -> failwith ""bad format specifier"" - - // newlines and tabs get converted to strings when read from a resource file - // this will preserve their original intention - static let postProcessString (s : string) = - s.Replace(""\\n"",""\n"").Replace(""\\t"",""\t"").Replace(""\\r"",""\r"").Replace(""\\\"""", ""\"""") - - static let createMessageString (messageString : string) (fmt : Printf.StringFormat<'T>) : 'T = - let fmt = fmt.Value // here, we use the actual error string, as opposed to the one stored as fmt - let len = fmt.Length - - /// Function to capture the arguments and then run. - let rec capture args ty i = - if i >= len || (fmt.[i] = '%' && i+1 >= len) then - let b = new System.Text.StringBuilder() - b.AppendFormat(messageString, [| for x in List.rev args -> x |]) |> ignore - box(b.ToString()) - // REVIEW: For these purposes, this should be a nop, but I'm leaving it - // in incase we ever decide to support labels for the error format string - // E.g., ""%s%d"" - elif System.Char.IsSurrogatePair(fmt,i) then - capture args ty (i+2) - else - match fmt.[i] with - | '%' -> - let i = i+1 - capture1 fmt i args ty capture - | _ -> - capture args ty (i+1) - - (unbox (capture [] (typeof<'T>) 0) : 'T) - - static let mutable swallowResourceText = false - - static let GetStringFunc((messageID : string),(fmt : Printf.StringFormat<'T>)) : 'T = - if swallowResourceText then - sprintf fmt - else - let mutable messageString = GetString(messageID) - messageString <- postProcessString messageString - createMessageString messageString fmt - - /// If set to true, then all error messages will just return the filled 'holes' delimited by ',,,'s - this is for language-neutral testing (e.g. localization-invariant baselines). - static member SwallowResourceText with get () = swallowResourceText - and set (b) = swallowResourceText <- b - // END BOILERPLATE -" - -let RunMain(filename, outFilename, outXmlFilenameOpt, projectNameOpt) = - try - let justfilename = System.IO.Path.GetFileNameWithoutExtension(filename) - if justfilename |> Seq.exists (fun c -> not(System.Char.IsLetterOrDigit(c))) then - Err(filename, 0, sprintf "The filename '%s' is not allowed; only letters and digits can be used, as the filename also becomes the namespace for the SR class" justfilename) - - printfn "fssrgen.fsx: Reading %s" filename - let lines = System.IO.File.ReadAllLines(filename) - |> Array.mapi (fun i s -> i,s) // keep line numbers - |> Array.filter (fun (i,s) -> not(s.StartsWith "#")) // filter out comments - - printfn "fssrgen.fsx: Parsing %s" filename - let stringInfos = lines |> Array.map (fun (i,s) -> ParseLine filename i s) - // now we have array of (lineNum, ident, str, holes, netFormatString) // str has %d, netFormatString has {0} - - printfn "fssrgen.fsx: Validating %s" filename - // validate that all the idents are unique - let allIdents = new System.Collections.Generic.Dictionary() - for (line,(_,ident),_,_,_) in stringInfos do - if allIdents.ContainsKey(ident) then - Err(filename,line,sprintf "Identifier '%s' is already used previously on line %d - each identifier must be unique" ident allIdents.[ident]) - allIdents.Add(ident,line) - - printfn "fssrgen.fsx: Validating uniqueness of %s" filename - // validate that all the strings themselves are unique - let allStrs = new System.Collections.Generic.Dictionary() - for (line,(_,ident),str,_,_) in stringInfos do - if allStrs.ContainsKey(str) then - let prevLine,prevIdent = allStrs.[str] - Err(filename,line,sprintf "String '%s' already appears on line %d with identifier '%s' - each string must be unique" str prevLine prevIdent) - allStrs.Add(str,(line,ident)) - - printfn "fssrgen.fsx: Generating %s" outFilename - - use out = new System.IO.StringWriter() - fprintfn out "// This is a generated file; the original input is '%s'" filename - fprintfn out "namespace %s" justfilename - if Option.isNone outXmlFilenameOpt then - fprintfn out "type internal SR private() =" - else - fprintfn out "%s" stringBoilerPlatePrefix - fprintfn out "type internal SR private() =" - let theResourceName = match projectNameOpt with Some p -> sprintf "%s.%s" p justfilename | None -> justfilename - fprintfn out "%s" (StringBoilerPlate theResourceName) - - printfn "fssrgen.fsx: Generating resource methods for %s" outFilename - // gen each resource method - stringInfos |> Seq.iter (fun (lineNum, (optErrNum,ident), str, holes, netFormatString) -> - let formalArgs = System.Text.StringBuilder() - let actualArgs = System.Text.StringBuilder() - let firstTime = ref true - let n = ref 0 - formalArgs.Append "(" |> ignore - for hole in holes do - if !firstTime then - firstTime := false - else - formalArgs.Append ", " |> ignore - actualArgs.Append " " |> ignore - formalArgs.Append(sprintf "a%d : %s" !n hole) |> ignore - actualArgs.Append(sprintf "a%d" !n) |> ignore - n := !n + 1 - formalArgs.Append ")" |> ignore - fprintfn out " /// %s" str - fprintfn out " /// (Originally from %s:%d)" filename (lineNum+1) - let justPercentsFromFormatString = - (holes |> Array.fold (fun acc holeType -> - acc + match holeType with - | "System.Int32" -> ",,,%d" - | "System.Double" -> ",,,%f" - | "System.String" -> ",,,%s" - | _ -> failwith "unreachable") "") + ",,," - let errPrefix = match optErrNum with - | None -> "" - | Some n -> sprintf "%d, " n - if Option.isNone outXmlFilenameOpt then - fprintfn out " static member %s%s = (%ssprintf \"%s\" %s)" ident (formalArgs.ToString()) errPrefix str (actualArgs.ToString()) - else - fprintfn out " static member %s%s = (%sGetStringFunc(\"%s\",\"%s\") %s)" ident (formalArgs.ToString()) errPrefix ident justPercentsFromFormatString (actualArgs.ToString()) - ) - - if Option.isSome outXmlFilenameOpt then - printfn "fssrgen.fsx: Generating .resx for %s" outFilename - fprintfn out "" - // gen validation method - fprintfn out " /// Call this method once to validate that all known resources are valid; throws if not" - fprintfn out " static member RunStartupValidation() =" - stringInfos |> Seq.iter (fun (lineNum, (optErrNum,ident), str, holes, netFormatString) -> - fprintfn out " ignore(GetString(\"%s\"))" ident - ) - fprintfn out " ()" // in case there are 0 strings, we need the generated code to parse - - let outFileNewText = out.ToString() - let nothingChanged = try File.Exists(outFilename) && File.ReadAllText(outFilename) = outFileNewText with _ -> false - if not nothingChanged then - File.WriteAllText(outFilename, outFileNewText, System.Text.Encoding.UTF8) - - if Option.isSome outXmlFilenameOpt then - // gen resx - let xd = new System.Xml.XmlDocument() - xd.LoadXml(xmlBoilerPlateString) - stringInfos |> Seq.iter (fun (lineNum, (optErrNum,ident), str, holes, netFormatString) -> - let xn = xd.CreateElement("data") - xn.SetAttribute("name",ident) |> ignore - xn.SetAttribute("xml:space","preserve") |> ignore - let xnc = xd.CreateElement "value" - xn.AppendChild xnc |> ignore - xnc.AppendChild(xd.CreateTextNode netFormatString) |> ignore - xd.LastChild.AppendChild xn |> ignore - ) - let outXmlFileNewText = - use outXmlStream = new System.IO.StringWriter() - xd.Save outXmlStream - outXmlStream.ToString() - let outXmlFile = outXmlFilenameOpt.Value - let nothingChanged = try File.Exists(outXmlFile) && File.ReadAllText(outXmlFile) = outXmlFileNewText with _ -> false - if not nothingChanged then - File.WriteAllText(outXmlFile, outXmlFileNewText, System.Text.Encoding.Unicode) - - - printfn "fssrgen.fsx: Done %s" outFilename - 0 - with e -> - PrintErr(filename, 0, sprintf "An exception occurred when processing '%s'\n%s" filename (e.ToString())) - 1 - -#if COMPILED -[] -#endif -let Main args = - - match args |> List.ofArray with - | [ inputFile; outFile; ] -> - let filename = System.IO.Path.GetFullPath(inputFile) - let outFilename = System.IO.Path.GetFullPath(outFile) - - RunMain(filename, outFilename, None, None) - - | [ inputFile; outFile; outXml ] -> - let filename = System.IO.Path.GetFullPath inputFile - let outFilename = System.IO.Path.GetFullPath outFile - let outXmlFilename = System.IO.Path.GetFullPath outXml - - RunMain(filename, outFilename, Some outXmlFilename, None) - - | [ inputFile; outFile; outXml; projectName ] -> - let filename = System.IO.Path.GetFullPath inputFile - let outFilename = System.IO.Path.GetFullPath outFile - let outXmlFilename = System.IO.Path.GetFullPath outXml - - RunMain(filename, outFilename, Some outXmlFilename, Some projectName) - - | _ -> - printfn "Error: invalid arguments." - printfn "Usage: " - 1 -#if !COMPILED -printfn "fssrgen: args = %A" fsi.CommandLineArgs -Main (fsi.CommandLineArgs |> Seq.skip 1 |> Seq.toArray) -#endif diff --git a/src/scripts/fssrgen.targets b/src/scripts/fssrgen.targets deleted file mode 100644 index 3458dd5bff..0000000000 --- a/src/scripts/fssrgen.targets +++ /dev/null @@ -1,57 +0,0 @@ - - - - - ProcessFsSrGen;$(BuildDependsOn) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - false - - - diff --git a/src/scripts/scriptlib.fsx b/src/scripts/scriptlib.fsx index 6835b9418f..df3c548cbc 100644 --- a/src/scripts/scriptlib.fsx +++ b/src/scripts/scriptlib.fsx @@ -60,15 +60,15 @@ module Scripting = let (++) a b = Path.Combine(a,b) - let getBasename a = Path.GetFileNameWithoutExtension a - let getFullPath a = Path.GetFullPath a - let getFilename a = Path.GetFileName a - let getDirectoryName a = Path.GetDirectoryName a + let getBasename (a:string) = Path.GetFileNameWithoutExtension a + let getFullPath (a:string) = Path.GetFullPath a + let getFilename (a:string) = Path.GetFileName a + let getDirectoryName (a:string) = Path.GetDirectoryName a - let copyFile source dir = + let copyFile (source:string) dir = let dest = if not (Directory.Exists dir) then Directory.CreateDirectory dir |>ignore - let result = Path.Combine(dir, Path.GetFileName source) + let result = Path.Combine(dir, getFilename source) result //printfn "Copy %s --> %s" source dest File.Copy(source, dest, true) @@ -93,10 +93,10 @@ module Scripting = module Process = - let processExePath baseDir exe = + let processExePath baseDir (exe:string) = if Path.IsPathRooted(exe) then exe else - match Path.GetDirectoryName(exe) with + match getDirectoryName exe with | "" -> exe | _ -> Path.Combine(baseDir,exe) |> Path.GetFullPath @@ -108,7 +108,7 @@ module Scripting = processInfo.UseShellExecute <- false processInfo.WorkingDirectory <- workDir -#if NETSTANDARD1_6 +#if !NET46 ignore envs // work out what to do about this #else envs @@ -159,9 +159,9 @@ module Scripting = match p.ExitCode with | 0 -> Success - | err -> + | errCode -> let msg = sprintf "Error running command '%s' with args '%s' in directory '%s'.\n---- stdout below --- \n%s\n---- stderr below --- \n%s " exePath arguments workDir (out.ToString()) (err.ToString()) - ErrorLevel (msg, err) + ErrorLevel (msg, errCode) type OutPipe (writer: TextWriter) = member x.Post (msg:string) = lock writer (fun () -> writer.WriteLine(msg)) diff --git a/src/scripts/subst.fsx b/src/scripts/subst.fsx deleted file mode 100644 index 4e8199e0ab..0000000000 --- a/src/scripts/subst.fsx +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. -// -//========================================================================================= - -#load "scriptlib.fsx" - -open System.IO -open System.Text.RegularExpressions - -try - let input = getCmdLineArgReqd "--in:" - let output = getCmdLineArgReqd "--out:" - let pattern1 = getCmdLineArgReqd "--pattern1:" - let replacement1 = getCmdLineArgReqd "--replacement1:" - let pattern2 = getCmdLineArgOptional "--pattern2:" - let replacement2 = getCmdLineArgOptional "--replacement2:" - - let inp0 = File.ReadAllText(input) - let inp1 = Regex.Replace(inp0, pattern1, replacement1) - let inp2 = match pattern2, replacement2 with Some p2, Some r2 -> Regex.Replace(inp1, p2, r2) | None, None -> inp1 | _ -> failwith "if pattern2 is given, replacement2 must also be given" - File.WriteAllText(output,inp2) - exit 0 -with e -> - eprintfn "%A" e - exit 1 diff --git a/src/utils/CompilerLocationUtils.fs b/src/utils/CompilerLocationUtils.fs index 3499e7e5b2..55dcac8ccc 100755 --- a/src/utils/CompilerLocationUtils.fs +++ b/src/utils/CompilerLocationUtils.fs @@ -37,19 +37,6 @@ module internal FSharpEnvironment = | s -> Some(s) with _ -> None - - // The F# team version number. This version number is used for - // - the F# version number reported by the fsc.exe and fsi.exe banners in the CTP release - // - the F# version number printed in the HTML documentation generator - // - the .NET DLL version number for all VS2008 DLLs - // - the VS2008 registry key, written by the VS2008 installer - // HKEY_LOCAL_MACHINE\Software\Microsoft\.NETFramework\AssemblyFolders\Microsoft.FSharp-" + FSharpTeamVersionNumber - // Also - // - for Beta2, the language revision number indicated on the F# language spec - // - // It is NOT the version number listed on FSharp.Core.dll - let FSharpTeamVersionNumber = "2.0.0.0" - // The F# binary format revision number. The first three digits of this form the significant part of the // format revision number for F# binary signature and optimization metadata. The last digit is not significant. // diff --git a/src/utils/EditDistance.fs b/src/utils/EditDistance.fs index 6beac0c408..503662400f 100644 --- a/src/utils/EditDistance.fs +++ b/src/utils/EditDistance.fs @@ -23,33 +23,45 @@ let jaro (s1: string) (s2: string) = let matchRadius = let minLen = Math.Min(s1.Length, s2.Length) minLen / 2 + minLen % 2 - - // An inner function which recursively finds the number - // of matched characters within the radius. - let commonChars (chars1: string) (chars2: string) = - let result = ResizeArray(chars1.Length) - for i = 0 to chars1.Length - 1 do - let c = chars1.[i] - if existsInWin c chars2 i matchRadius then - result.Add c - result - - // The sets of common characters and their lengths as floats - let c1 = commonChars s1 s2 - let c2 = commonChars s2 s1 - let c1length = float c1.Count - let c2length = float c2.Count - + + let rec nextChar (s1:string) (s2:string) i c = + if i < s1.Length then + let c = s1.[i] + if not (existsInWin c s2 i matchRadius) then + nextChar s1 s2 (i + 1) c + else + struct (i, c) + else + struct (i, c) + + // The sets of common characters and their lengths as floats // The number of transpositions within the sets of common characters. - let transpositions = - let mutable mismatches = 0.0 - for i = 0 to (Math.Min(c1.Count, c2.Count)) - 1 do - if c1.[i] <> c2.[i] then - mismatches <- mismatches + 1.0 - - // If one common string is longer than the other - // each additional char counts as half a transposition - (mismatches + abs (c1length - c2length)) / 2.0 + let struct (transpositions, c1length, c2length) = + let rec loop i j mismatches c1length c2length = + if i < s1.Length && j < s2.Length then + let struct (ti, ci) = nextChar s1 s2 i ' ' + let struct (tj, cj) = nextChar s2 s1 j ' ' + if ci <> cj then + loop (ti + 1) (tj + 1) (mismatches + 1) (c1length + 1) (c2length + 1) + else + loop (ti + 1) (tj + 1) mismatches (c1length + 1) (c2length + 1) + else struct (i, j, mismatches, c1length, c2length) + + let struct (i, j, mismatches, c1length, c2length) = loop 0 0 0 0 0 + + let rec loop (s1:string) (s2:string) i length = + if i < s1.Length - 1 then + let c = s1.[i] + if existsInWin c s2 i matchRadius then + loop s1 s2 (i + 1) (length + 1) + else + loop s1 s2 (i + 1) length + else + length + let c1length = loop s1 s2 i c1length |> float + let c2length = loop s2 s1 j c2length |> float + + struct ((float mismatches + abs (c1length - c2length)) / 2.0, c1length, c2length) let tLength = Math.Max(c1length, c2length) diff --git a/src/utils/prim-lexing.fs b/src/utils/prim-lexing.fs index 531e3e5f18..2a49afc579 100755 --- a/src/utils/prim-lexing.fs +++ b/src/utils/prim-lexing.fs @@ -2,6 +2,7 @@ #nowarn "47" // recursive initialization of LexBuffer +// NOTE: the code in this file is a drop-in replacement runtime for Lexing.fs from the FsLexYacc repository namespace Internal.Utilities.Text.Lexing diff --git a/src/utils/prim-lexing.fsi b/src/utils/prim-lexing.fsi index 49eb2e6bc4..9ee890b8d1 100755 --- a/src/utils/prim-lexing.fsi +++ b/src/utils/prim-lexing.fsi @@ -2,7 +2,10 @@ // LexBuffers are for use with automatically generated lexical analyzers, // in particular those produced by 'fslex'. - +// +// NOTE: the code in this file is a drop-in replacement runtime for Lexing.fsi from the FsLexYacc repository +// and is referenced by generated code for the three FsLex generated lexers in the F# compiler. +// The underlying table format intepreted must precisely match the format generated by FsLex. namespace Internal.Utilities.Text.Lexing open System.Collections.Generic @@ -14,27 +17,35 @@ open Microsoft.FSharp.Control type internal Position = /// The file index for the file associated with the input stream, use fileOfFileIndex in range.fs to decode val FileIndex : int + /// The line number in the input stream, assuming fresh positions have been updated /// for the new line by modifying the EndPos property of the LexBuffer. val Line : int + /// The line number for the position in the input stream, assuming fresh positions have been updated /// using for the new line. val OriginalLine : int + /// The character number in the input stream. val AbsoluteOffset : int + /// Return absolute offset of the start of the line marked by the position. val StartOfLineAbsoluteOffset : int + /// Return the column number marked by the position, /// i.e. the difference between the AbsoluteOffset and the StartOfLineAbsoluteOffset member Column : int - // Given a position just beyond the end of a line, return a position at the start of the next line. + + /// Given a position just beyond the end of a line, return a position at the start of the next line. member NextLine : Position /// Given a position at the start of a token of length n, return a position just beyond the end of the token. member EndOfToken: n:int -> Position + /// Gives a position shifted by specified number of characters. member ShiftColumnBy: by:int -> Position - // Same line, column -1. + + /// Same line, column -1. member ColumnMinusOne : Position /// Apply a #line directive. @@ -47,11 +58,15 @@ type internal Position = [] /// Input buffers consumed by lexers generated by fslex.exe. +/// The type must be generic to match the code generated by FsLex and FsYacc (if you would like to +/// fix this, please submit a PR to the FsLexYacc repository allowing for optional emit of a non-generic type reference). type internal LexBuffer<'Char> = /// The start position for the lexeme. member StartPos: Position with get,set + /// The end position for the lexeme. member EndPos: Position with get,set + /// The matched string. member Lexeme: 'Char [] @@ -67,13 +82,17 @@ type internal LexBuffer<'Char> = /// Create a lex buffer suitable for Unicode lexing that reads characters from the given array. /// Important: does take ownership of the array. static member FromChars: char[] -> LexBuffer + /// Create a lex buffer that reads character or byte inputs by using the given function. static member FromFunction: ('Char[] * int * int -> int) -> LexBuffer<'Char> /// The type of tables for an unicode lexer generated by fslex.exe. [] type internal UnicodeTables = + + /// Create the tables from raw data static member Create : uint16[][] * uint16[] -> UnicodeTables + /// Interpret tables for a unicode lexer generated by fslex.exe. member Interpret: initialState:int * LexBuffer -> int diff --git a/src/utils/prim-parsing.fs b/src/utils/prim-parsing.fs index b5e87d19f2..c9ff1bb595 100755 --- a/src/utils/prim-parsing.fs +++ b/src/utils/prim-parsing.fs @@ -1,6 +1,9 @@ // Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. +// NOTE: the code in this file is a drop-in replacement runtime for Parsing.fs from the FsLexYacc repository + namespace Internal.Utilities.Text.Parsing + open Internal.Utilities open Internal.Utilities.Text.Lexing @@ -11,21 +14,29 @@ exception RecoverableParseError exception Accept of obj [] -type internal IParseState(ruleStartPoss:Position[],ruleEndPoss:Position[],lhsPos:Position[],ruleValues:obj[],lexbuf:LexBuffer) = +type internal IParseState(ruleStartPoss:Position[], ruleEndPoss:Position[], lhsPos:Position[], ruleValues:obj[], lexbuf:LexBuffer) = member p.LexBuffer = lexbuf - member p.InputRange n = ruleStartPoss.[n-1], ruleEndPoss.[n-1]; + + member p.InputRange n = ruleStartPoss.[n-1], ruleEndPoss.[n-1] + member p.InputStartPosition n = ruleStartPoss.[n-1] - member p.InputEndPosition n = ruleEndPoss.[n-1]; + + member p.InputEndPosition n = ruleEndPoss.[n-1] + member p.ResultStartPosition = lhsPos.[0] - member p.ResultEndPosition = lhsPos.[1]; - member p.GetInput n = ruleValues.[n-1]; - member p.ResultRange = (lhsPos.[0], lhsPos.[1]); - member p.RaiseError() = raise RecoverableParseError (* NOTE: this binding tests the fairly complex logic associated with an object expression implementing a generic abstract method *) -//------------------------------------------------------------------------- -// This context is passed to the error reporter when a syntax error occurs + member p.ResultEndPosition = lhsPos.[1] + + member p.GetInput n = ruleValues.[n-1] + + member p.ResultRange = (lhsPos.[0], lhsPos.[1]) + + // Side note: this definition coincidentally tests the fairly complex logic associated with an object expression implementing a generic abstract method. + member p.RaiseError() = raise RecoverableParseError + [] +/// This context is passed to the error reporter when a syntax error occurs type internal ParseErrorContext<'tok> (//lexbuf: LexBuffer<_>, stateStack:int list, @@ -49,24 +60,24 @@ type internal ParseErrorContext<'tok> // This is the data structure emitted as code by FSYACC. type internal Tables<'tok> = - { reductions: (IParseState -> obj)[]; - endOfInputTag: int; - tagOfToken: 'tok -> int; - dataOfToken: 'tok -> obj; - actionTableElements: uint16[]; - actionTableRowOffsets: uint16[]; - reductionSymbolCounts: uint16[]; - immediateActions: uint16[]; - gotos: uint16[]; - sparseGotoTableRowOffsets: uint16[]; - stateToProdIdxsTableElements: uint16[]; - stateToProdIdxsTableRowOffsets: uint16[]; - productionToNonTerminalTable: uint16[]; + { reductions: (IParseState -> obj)[] + endOfInputTag: int + tagOfToken: 'tok -> int + dataOfToken: 'tok -> obj + actionTableElements: uint16[] + actionTableRowOffsets: uint16[] + reductionSymbolCounts: uint16[] + immediateActions: uint16[] + gotos: uint16[] + sparseGotoTableRowOffsets: uint16[] + stateToProdIdxsTableElements: uint16[] + stateToProdIdxsTableRowOffsets: uint16[] + productionToNonTerminalTable: uint16[] /// For fsyacc.exe, this entry is filled in by context from the generated parser file. If no 'parse_error' function /// is defined by the user then ParseHelpers.parse_error is used by default (ParseHelpers is opened /// at the top of the generated parser file) - parseError: ParseErrorContext<'tok> -> unit; - numTerminals: int; + parseError: ParseErrorContext<'tok> -> unit + numTerminals: int tagOfErrorTerminal: int } //------------------------------------------------------------------------- @@ -91,8 +102,8 @@ type Stack<'a>(n) = member buf.Peep() = contents.[count - 1] member buf.Top(n) = [ for x in contents.[max 0 (count-n)..count - 1] -> x ] |> List.rev member buf.Push(x) = - buf.Ensure(count + 1); - contents.[count] <- x; + buf.Ensure(count + 1) + contents.[count] <- x count <- count + 1 member buf.IsEmpty = (count = 0) @@ -197,10 +208,10 @@ module internal Implementation = let interpret (tables: Tables<'tok>) lexer (lexbuf : LexBuffer<_>) initialState = #if DEBUG - if Flags.debug then System.Console.WriteLine("\nParser: interpret tables"); + if Flags.debug then System.Console.WriteLine("\nParser: interpret tables") #endif let stateStack : Stack = new Stack<_>(100) - stateStack.Push(initialState); + stateStack.Push(initialState) let valueStack = new Stack(100) let mutable haveLookahead = false let mutable lookaheadToken = Unchecked.defaultof<'tok> @@ -244,19 +255,19 @@ module internal Implementation = let rec popStackUntilErrorShifted(tokenOpt) = // Keep popping the stack until the "error" terminal is shifted #if DEBUG - if Flags.debug then System.Console.WriteLine("popStackUntilErrorShifted"); + if Flags.debug then System.Console.WriteLine("popStackUntilErrorShifted") #endif if stateStack.IsEmpty then #if DEBUG if Flags.debug then - System.Console.WriteLine("state stack empty during error recovery - generating parse error"); + System.Console.WriteLine("state stack empty during error recovery - generating parse error") #endif - failwith "parse error"; + failwith "parse error" let currState = stateStack.Peep() #if DEBUG if Flags.debug then - System.Console.WriteLine("In state {0} during error recovery", currState); + System.Console.WriteLine("In state {0} during error recovery", currState) #endif let action = actionTable.Read(currState, tables.tagOfErrorTerminal) @@ -269,22 +280,22 @@ module internal Implementation = actionKind (actionTable.Read(nextState, tables.tagOfToken(token))) = shiftFlag) then #if DEBUG - if Flags.debug then System.Console.WriteLine("shifting error, continuing with error recovery"); + if Flags.debug then System.Console.WriteLine("shifting error, continuing with error recovery") #endif let nextState = actionValue action // The "error" non terminal needs position information, though it tends to be unreliable. // Use the StartPos/EndPos from the lex buffer. - valueStack.Push(ValueInfo(box (), lexbuf.StartPos, lexbuf.EndPos)); + valueStack.Push(ValueInfo(box (), lexbuf.StartPos, lexbuf.EndPos)) stateStack.Push(nextState) else if valueStack.IsEmpty then - failwith "parse error"; + failwith "parse error" #if DEBUG if Flags.debug then - System.Console.WriteLine("popping stack during error recovery"); + System.Console.WriteLine("popping stack during error recovery") #endif - valueStack.Pop(); - stateStack.Pop(); + valueStack.Pop() + stateStack.Pop() popStackUntilErrorShifted(tokenOpt) while not finished do @@ -316,7 +327,7 @@ module internal Implementation = lookaheadToken <- lexer lexbuf lookaheadStartPos <- lexbuf.StartPos lookaheadEndPos <- lexbuf.EndPos - haveLookahead <- true; + haveLookahead <- true let tag = if haveLookahead then tables.tagOfToken lookaheadToken @@ -328,17 +339,17 @@ module internal Implementation = let kind = actionKind action if kind = shiftFlag then ( if errorSuppressionCountDown > 0 then - errorSuppressionCountDown <- errorSuppressionCountDown - 1; + errorSuppressionCountDown <- errorSuppressionCountDown - 1 #if DEBUG - if Flags.debug then Console.WriteLine("shifting, reduced errorRecoverylevel to {0}\n", errorSuppressionCountDown); + if Flags.debug then Console.WriteLine("shifting, reduced errorRecoverylevel to {0}\n", errorSuppressionCountDown) #endif let nextState = actionValue action - if not haveLookahead then failwith "shift on end of input!"; + if not haveLookahead then failwith "shift on end of input!" let data = tables.dataOfToken lookaheadToken - valueStack.Push(ValueInfo(data, lookaheadStartPos, lookaheadEndPos)); - stateStack.Push(nextState); + valueStack.Push(ValueInfo(data, lookaheadStartPos, lookaheadEndPos)) + stateStack.Push(nextState) #if DEBUG - if Flags.debug then Console.WriteLine("shift/consume input {0}, shift to state {1}", report haveLookahead lookaheadToken, nextState); + if Flags.debug then Console.WriteLine("shift/consume input {0}, shift to state {1}", report haveLookahead lookaheadToken, nextState) #endif haveLookahead <- false @@ -348,31 +359,31 @@ module internal Implementation = let n = int tables.reductionSymbolCounts.[prod] // pop the symbols, populate the values and populate the locations #if DEBUG - if Flags.debug then Console.Write("reduce popping {0} values/states, lookahead {1}", n, report haveLookahead lookaheadToken); + if Flags.debug then Console.Write("reduce popping {0} values/states, lookahead {1}", n, report haveLookahead lookaheadToken) #endif for i = 0 to n - 1 do - if valueStack.IsEmpty then failwith "empty symbol stack"; + if valueStack.IsEmpty then failwith "empty symbol stack" let topVal = valueStack.Peep() - valueStack.Pop(); - stateStack.Pop(); - ruleValues.[(n-i)-1] <- topVal.value; - ruleStartPoss.[(n-i)-1] <- topVal.startPos; - ruleEndPoss.[(n-i)-1] <- topVal.endPos; - if i = 0 then lhsPos.[1] <- topVal.endPos; + valueStack.Pop() + stateStack.Pop() + ruleValues.[(n-i)-1] <- topVal.value + ruleStartPoss.[(n-i)-1] <- topVal.startPos + ruleEndPoss.[(n-i)-1] <- topVal.endPos + if i = 0 then lhsPos.[1] <- topVal.endPos if i = n - 1 then lhsPos.[0] <- topVal.startPos // Use the lookahead token to populate the locations if the rhs is empty if n = 0 then if haveLookahead then - lhsPos.[0] <- lookaheadStartPos; - lhsPos.[1] <- lookaheadEndPos; + lhsPos.[0] <- lookaheadStartPos + lhsPos.[1] <- lookaheadEndPos else - lhsPos.[0] <- lexbuf.StartPos; - lhsPos.[1] <- lexbuf.EndPos; + lhsPos.[0] <- lexbuf.StartPos + lhsPos.[1] <- lexbuf.EndPos try - // printf "reduce %d\n" prod; + // printf "reduce %d\n" prod let redResult = reduction parseState - valueStack.Push(ValueInfo(redResult, lhsPos.[0], lhsPos.[1])); + valueStack.Push(ValueInfo(redResult, lhsPos.[0], lhsPos.[1])) let currState = stateStack.Peep() let newGotoState = gotoTable.Read(int tables.productionToNonTerminalTable.[prod], currState) stateStack.Push(newGotoState) @@ -381,23 +392,23 @@ module internal Implementation = #endif with | Accept res -> - finished <- true; + finished <- true valueStack.Push(ValueInfo(res, lhsPos.[0], lhsPos.[1])) | RecoverableParseError -> #if DEBUG - if Flags.debug then Console.WriteLine("RecoverableParseErrorException...\n"); + if Flags.debug then Console.WriteLine("RecoverableParseErrorException...\n") #endif - popStackUntilErrorShifted(None); + popStackUntilErrorShifted(None) // User code raised a Parse_error. Don't report errors again until three tokens have been shifted errorSuppressionCountDown <- 3 elif kind = errorFlag then ( #if DEBUG - if Flags.debug then Console.Write("ErrorFlag... "); + if Flags.debug then Console.Write("ErrorFlag... ") #endif // Silently discard inputs and don't report errors // until three tokens in a row have been shifted #if DEBUG - if Flags.debug then printfn "error on token '%s' " (report haveLookahead lookaheadToken); + if Flags.debug then printfn "error on token '%s' " (report haveLookahead lookaheadToken) #endif if errorSuppressionCountDown > 0 then // If we're in the end-of-file count down then we're very keen to 'Accept'. @@ -405,16 +416,16 @@ module internal Implementation = // and an EOF token. if inEofCountDown && eofCountDown < 10 then #if DEBUG - if Flags.debug then printfn "popping stack, looking to shift both 'error' and that token, during end-of-file error recovery" ; + if Flags.debug then printfn "popping stack, looking to shift both 'error' and that token, during end-of-file error recovery" #endif - popStackUntilErrorShifted(if haveLookahead then Some(lookaheadToken) else None); + popStackUntilErrorShifted(if haveLookahead then Some(lookaheadToken) else None) // If we don't haveLookahead then the end-of-file count down is over and we have no further options. if not haveLookahead then failwith "parse error: unexpected end of file" #if DEBUG - if Flags.debug then printfn "discarding token '%s' during error suppression" (report haveLookahead lookaheadToken); + if Flags.debug then printfn "discarding token '%s' during error suppression" (report haveLookahead lookaheadToken) #endif // Discard the token haveLookahead <- false @@ -449,28 +460,30 @@ module internal Implementation = if not (explicit.Contains(tag)) then yield tag ] in //let activeRules = stateStack |> List.iter (fun state -> - let errorContext = new ParseErrorContext<'tok>(stateStack,parseState, reduceTokens,currentToken,reducibleProductions, shiftableTokens, "syntax error") - tables.parseError(errorContext); - popStackUntilErrorShifted(None); - errorSuppressionCountDown <- 3; + let errorContext = new ParseErrorContext<'tok>(stateStack, parseState, reduceTokens, currentToken, reducibleProductions, shiftableTokens, "syntax error") + tables.parseError(errorContext) + popStackUntilErrorShifted(None) + errorSuppressionCountDown <- 3 #if DEBUG - if Flags.debug then System.Console.WriteLine("generated syntax error and shifted error token, haveLookahead = {0}\n", haveLookahead); + if Flags.debug then System.Console.WriteLine("generated syntax error and shifted error token, haveLookahead = {0}\n", haveLookahead) #endif ) ) elif kind = acceptFlag then finished <- true #if DEBUG else - if Flags.debug then System.Console.WriteLine("ALARM!!! drop through case in parser"); + if Flags.debug then System.Console.WriteLine("ALARM!!! drop through case in parser") #endif - done; + done // OK, we're done - read off the overall generated value valueStack.Peep().value type internal Tables<'tok> with - member tables.Interpret (lexer,lexbuf,initialState) = + member tables.Interpret (lexer, lexbuf, initialState) = Implementation.interpret tables lexer lexbuf initialState module internal ParseHelpers = + let parse_error (_s:string) = () + let parse_error_rich = (None : (ParseErrorContext<_> -> unit) option) diff --git a/src/utils/prim-parsing.fsi b/src/utils/prim-parsing.fsi index d6502da55b..7ec3e7a0a8 100755 --- a/src/utils/prim-parsing.fsi +++ b/src/utils/prim-parsing.fsi @@ -1,6 +1,9 @@ // Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. +// NOTE: the code in this file is a drop-in replacement runtime for Parsing.fsi from the FsLexYacc repository + namespace Internal.Utilities.Text.Parsing + open Internal.Utilities open Internal.Utilities.Text.Lexing @@ -8,22 +11,31 @@ open System.Collections.Generic [] type internal IParseState = + /// Get the start and end position for the terminal or non-terminal at a given index matched by the production. member InputRange: index:int -> Position * Position + /// Get the end position for the terminal or non-terminal at a given index matched by the production. member InputEndPosition: int -> Position + /// Get the start position for the terminal or non-terminal at a given index matched by the production. member InputStartPosition: int -> Position + /// Get the start of the range of positions matched by the production. member ResultStartPosition: Position + /// Get the end of the range of positions matched by the production. member ResultEndPosition: Position + /// Get the full range of positions matched by the production. member ResultRange: Position * Position + /// Get the value produced by the terminal or non-terminal at the given position. member GetInput : int -> obj + /// Raise an error in this parse context. member RaiseError<'b> : unit -> 'b + /// Return the LexBuffer for this parser instance. member LexBuffer : LexBuffer @@ -33,16 +45,22 @@ type internal IParseState = type internal ParseErrorContext<'tok> = /// The stack of state indexes active at the parse error . member StateStack : int list + /// The state active at the parse error. member ParseState : IParseState + /// The tokens that would cause a reduction at the parse error. member ReduceTokens: int list + /// The stack of productions that would be reduced at the parse error. member ReducibleProductions : int list list + /// The token that caused the parse error. member CurrentToken : 'tok option + /// The token that would cause a shift at the parse error. member ShiftTokens : int list + /// The message associated with the parse error. member Message : string @@ -51,35 +69,50 @@ type internal ParseErrorContext<'tok> = type internal Tables<'tok> = { /// The reduction table. - reductions: (IParseState -> obj) array ; + reductions: (IParseState -> obj)[] + /// The token number indicating the end of input. - endOfInputTag: int; + endOfInputTag: int + /// A function to compute the tag of a token. - tagOfToken: 'tok -> int; + tagOfToken: 'tok -> int + /// A function to compute the data carried by a token. - dataOfToken: 'tok -> obj; + dataOfToken: 'tok -> obj + /// The sparse action table elements. - actionTableElements: uint16[]; + actionTableElements: uint16[] + /// The sparse action table row offsets. - actionTableRowOffsets: uint16[]; + actionTableRowOffsets: uint16[] + /// The number of symbols for each reduction. - reductionSymbolCounts: uint16[]; + reductionSymbolCounts: uint16[] + /// The immediate action table. - immediateActions: uint16[]; + immediateActions: uint16[] + /// The sparse goto table. - gotos: uint16[]; + gotos: uint16[] + /// The sparse goto table row offsets. - sparseGotoTableRowOffsets: uint16[]; + sparseGotoTableRowOffsets: uint16[] + /// The sparse table for the productions active for each state. - stateToProdIdxsTableElements: uint16[]; + stateToProdIdxsTableElements: uint16[] + /// The sparse table offsets for the productions active for each state. - stateToProdIdxsTableRowOffsets: uint16[]; + stateToProdIdxsTableRowOffsets: uint16[] + /// This table is logically part of the Goto table. - productionToNonTerminalTable: uint16[]; + productionToNonTerminalTable: uint16[] + /// This function is used to hold the user specified "parse_error" or "parse_error_rich" functions. - parseError: ParseErrorContext<'tok> -> unit; + parseError: ParseErrorContext<'tok> -> unit + /// The total number of terminals. - numTerminals: int; + numTerminals: int + /// The tag of the error terminal. tagOfErrorTerminal: int } @@ -89,6 +122,7 @@ type internal Tables<'tok> = /// Indicates an accept action has occurred. exception internal Accept of obj + /// Indicates a parse error has occurred and parse recovery is in progress. exception internal RecoverableParseError @@ -99,8 +133,10 @@ module internal Flags = /// Helpers used by generated parsers. module internal ParseHelpers = + /// The default implementation of the parse_error_rich function. val parse_error_rich: (ParseErrorContext<'tok> -> unit) option + /// The default implementation of the parse_error function. val parse_error: string -> unit diff --git a/src/utils/reshapedmsbuild.fs b/src/utils/reshapedmsbuild.fs index 925b904e3e..f84e8a5d31 100644 --- a/src/utils/reshapedmsbuild.fs +++ b/src/utils/reshapedmsbuild.fs @@ -85,6 +85,10 @@ module internal MsBuildAdapters = | Version46 = 7 | Version461 = 8 | Version452 = 9 + | Version462 = 10 + | Version47 = 11 + | Version471 = 12 + | Version472 = 13 | VersionLatest = 8 //TargetDotNetFrameworkVersion.Version461 /// diff --git a/src/utils/sformat.fs b/src/utils/sformat.fs index d2d3511777..7620a2c411 100755 --- a/src/utils/sformat.fs +++ b/src/utils/sformat.fs @@ -199,6 +199,8 @@ namespace Microsoft.FSharp.Text.StructuredPrintfImpl let rightBracket = tagPunctuation "]" let leftBrace= tagPunctuation "{" let rightBrace = tagPunctuation "}" + let leftBraceBar = tagPunctuation "{|" + let rightBraceBar = tagPunctuation "|}" let equals = tagOperator "=" let arrow = tagPunctuation "->" let questionMark = tagPunctuation "?" diff --git a/src/utils/sformat.fsi b/src/utils/sformat.fsi index fb768703e1..afdd931f90 100755 --- a/src/utils/sformat.fsi +++ b/src/utils/sformat.fsi @@ -148,6 +148,8 @@ namespace Microsoft.FSharp.Text.StructuredPrintfImpl val rightBracket : TaggedText val leftBrace: TaggedText val rightBrace : TaggedText + val leftBraceBar: TaggedText + val rightBraceBar : TaggedText val equals : TaggedText val arrow : TaggedText val questionMark : TaggedText diff --git a/tests/FSharp.Compiler.UnitTests/Directory.Build.props b/tests/FSharp.Compiler.UnitTests/Directory.Build.props new file mode 100644 index 0000000000..bb8eac309b --- /dev/null +++ b/tests/FSharp.Compiler.UnitTests/Directory.Build.props @@ -0,0 +1,3 @@ + + + diff --git a/tests/FSharp.Compiler.UnitTests/Directory.Build.targets b/tests/FSharp.Compiler.UnitTests/Directory.Build.targets new file mode 100644 index 0000000000..ccd47cc0a9 --- /dev/null +++ b/tests/FSharp.Compiler.UnitTests/Directory.Build.targets @@ -0,0 +1,3 @@ + + + diff --git a/tests/FSharp.Compiler.UnitTests/FSharp.Compiler.UnitTests.fsproj b/tests/FSharp.Compiler.UnitTests/FSharp.Compiler.UnitTests.fsproj new file mode 100644 index 0000000000..4b9f4d21a3 --- /dev/null +++ b/tests/FSharp.Compiler.UnitTests/FSharp.Compiler.UnitTests.fsproj @@ -0,0 +1,28 @@ + + + + + + net46;netcoreapp2.0 + Library + true + nunit + + + + + + + + + + + + + + + + + + + diff --git a/tests/FSharp.Compiler.UnitTests/ILHelpers.fs b/tests/FSharp.Compiler.UnitTests/ILHelpers.fs new file mode 100644 index 0000000000..372e11d070 --- /dev/null +++ b/tests/FSharp.Compiler.UnitTests/ILHelpers.fs @@ -0,0 +1,116 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.UnitTests + +open System +open System.IO +open System.Diagnostics + +open NUnit.Framework + +open Microsoft.FSharp.Compiler.SourceCodeServices + +module ILChecker = + + let checker = FSharpChecker.Create() + + let private (++) a b = Path.Combine(a,b) + + let private getfullpath workDir path = + let rooted = + if Path.IsPathRooted(path) then path + else Path.Combine(workDir, path) + rooted |> Path.GetFullPath + + let private fileExists workDir path = + if path |> getfullpath workDir |> File.Exists then Some path else None + + let private requireFile nm = + if fileExists __SOURCE_DIRECTORY__ nm |> Option.isSome then nm else failwith (sprintf "couldn't find %s. Running 'build test' once might solve this issue" nm) + + let private exec exe args = + let startInfo = ProcessStartInfo(exe, String.concat " " args) + startInfo.RedirectStandardError <- true + startInfo.UseShellExecute <- false + use p = Process.Start(startInfo) + p.WaitForExit() + p.StandardError.ReadToEnd(), p.ExitCode + + /// Compile the source and check to see if the expected IL exists. + /// The first line of each expected IL string is found first. + let check source expectedIL = + let packagesDir = Environment.GetEnvironmentVariable("USERPROFILE") ++ ".nuget" ++ "packages" + let Is64BitOperatingSystem = sizeof = 8 + let architectureMoniker = if Is64BitOperatingSystem then "x64" else "x86" + let ildasmExe = requireFile (packagesDir ++ ("runtime.win-" + architectureMoniker + ".Microsoft.NETCore.ILDAsm") ++ "2.0.3" ++ "runtimes" ++ ("win-" + architectureMoniker) ++ "native" ++ "ildasm.exe") + let coreclrDll = requireFile (packagesDir ++ ("runtime.win-" + architectureMoniker + ".Microsoft.NETCore.Runtime.CoreCLR") ++ "2.0.3" ++ "runtimes" ++ ("win-" + architectureMoniker) ++ "native" ++ "coreclr.dll") + + let tmp = Path.GetTempFileName() + let tmpFs = Path.ChangeExtension(tmp, ".fs") + let tmpDll = Path.ChangeExtension(tmp, ".dll") + let tmpIL = Path.ChangeExtension(tmp, ".il") + + let mutable errorMsgOpt = None + try + // ildasm requires coreclr.dll to run which has already been restored to the packages directory + File.Copy(coreclrDll, Path.GetDirectoryName(ildasmExe) ++ "coreclr.dll", overwrite=true) + + File.WriteAllText(tmpFs, source) + + let errors, exitCode = checker.Compile([| "fsc.exe"; "--optimize+"; "-o"; tmpDll; "-a"; tmpFs |]) |> Async.RunSynchronously + let errors = + String.concat "\n" (errors |> Array.map (fun x -> x.Message)) + + if exitCode = 0 then + exec ildasmExe [ sprintf "%s /out=%s" tmpDll tmpIL ] |> ignore + + let text = File.ReadAllText(tmpIL) + let blockComments = @"/\*(.*?)\*/" + let lineComments = @"//(.*?)\r?\n" + let strings = @"""((\\[^\n]|[^""\n])*)""" + let verbatimStrings = @"@(""[^""]*"")+" + let textNoComments = + System.Text.RegularExpressions.Regex.Replace(text, + blockComments + "|" + lineComments + "|" + strings + "|" + verbatimStrings, + (fun me -> + if (me.Value.StartsWith("/*") || me.Value.StartsWith("//")) then + if me.Value.StartsWith("//") then Environment.NewLine else String.Empty + else + me.Value), System.Text.RegularExpressions.RegexOptions.Singleline) + + expectedIL + |> List.iter (fun (ilCode: string) -> + let expectedLines = ilCode.Split('\n') + let startIndex = textNoComments.IndexOf(expectedLines.[0]) + if startIndex = -1 || textNoComments.Length < startIndex + ilCode.Length then + errorMsgOpt <- Some("==EXPECTED CONTAINS==\n" + ilCode + "\n") + else + let errors = ResizeArray() + let actualLines = textNoComments.Substring(startIndex, textNoComments.Length - startIndex).Split('\n') + for i = 0 to expectedLines.Length - 1 do + let expected = expectedLines.[i].Trim() + let actual = actualLines.[i].Trim() + if expected <> actual then + errors.Add(sprintf "\n==\nName: %s\n\nExpected:\t %s\nActual:\t\t %s\n==" actualLines.[0] expected actual) + + if errors.Count > 0 then + let msg = String.concat "\n" errors + "\n\n\n==EXPECTED==\n" + ilCode + "\n" + errorMsgOpt <- Some(msg + "\n\n\n==ACTUAL==\n" + String.Join("\n", actualLines, 0, expectedLines.Length)) + ) + + match errorMsgOpt with + | Some(msg) -> errorMsgOpt <- Some(msg + "\n\n\n==ENTIRE ACTUAL==\n" + textNoComments) + | _ -> () + else + errorMsgOpt <- Some(errors) + finally + try File.Delete(tmp) with | _ -> () + try File.Delete(tmpFs) with | _ -> () + try File.Delete(tmpDll) with | _ -> () + try File.Delete(tmpIL) with | _ -> () + + match errorMsgOpt with + | Some(errorMsg) -> + Assert.Fail(errorMsg) + | _ -> () + diff --git a/tests/FSharp.Compiler.UnitTests/Language/StringConcat.fs b/tests/FSharp.Compiler.UnitTests/Language/StringConcat.fs new file mode 100644 index 0000000000..fa18e7bb42 --- /dev/null +++ b/tests/FSharp.Compiler.UnitTests/Language/StringConcat.fs @@ -0,0 +1,845 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.UnitTests + +open System +open NUnit.Framework + +[] +module StringConcat = + + [] + let Optimizations () = + let baseSource = """ +module Test + +open System + +let arr = ResizeArray() + +let inline ss (x: int) = + arr.Add(x) + "_" + x.ToString() + "_" +""" + + let test1Source = """ +let test1 () = + ss 1 + ss 2 + ss 3 +""" + let test1IL = """.method public static string test1() cil managed + { + + .maxstack 7 + .locals init (int32 V_0) + IL_0000: ldc.i4.1 + IL_0001: stloc.0 + IL_0002: call class [mscorlib]System.Collections.Generic.List`1 Test::get_arr() + IL_0007: ldc.i4.1 + IL_0008: callvirt instance void class [mscorlib]System.Collections.Generic.List`1::Add(!0) + IL_000d: ldstr "_" + IL_0012: ldloca.s V_0 + IL_0014: constrained. [mscorlib]System.Int32 + IL_001a: callvirt instance string [mscorlib]System.Object::ToString() + IL_001f: ldstr "_" + IL_0024: call string [mscorlib]System.String::Concat(string, + string, + string) + IL_0029: ldc.i4.2 + IL_002a: stloc.0 + IL_002b: call class [mscorlib]System.Collections.Generic.List`1 Test::get_arr() + IL_0030: ldc.i4.2 + IL_0031: callvirt instance void class [mscorlib]System.Collections.Generic.List`1::Add(!0) + IL_0036: ldstr "_" + IL_003b: ldloca.s V_0 + IL_003d: constrained. [mscorlib]System.Int32 + IL_0043: callvirt instance string [mscorlib]System.Object::ToString() + IL_0048: ldstr "_" + IL_004d: call string [mscorlib]System.String::Concat(string, + string, + string) + IL_0052: ldc.i4.3 + IL_0053: stloc.0 + IL_0054: call class [mscorlib]System.Collections.Generic.List`1 Test::get_arr() + IL_0059: ldc.i4.3 + IL_005a: callvirt instance void class [mscorlib]System.Collections.Generic.List`1::Add(!0) + IL_005f: ldstr "_" + IL_0064: ldloca.s V_0 + IL_0066: constrained. [mscorlib]System.Int32 + IL_006c: callvirt instance string [mscorlib]System.Object::ToString() + IL_0071: ldstr "_" + IL_0076: call string [mscorlib]System.String::Concat(string, + string, + string) + IL_007b: call string [mscorlib]System.String::Concat(string, + string, + string) + IL_0080: ret + }""" + + let test2Source = """ +let test2 () = + ss 1 + ss 2 + ss 3 + ss 4 +""" + let test2IL = """.method public static string test2() cil managed + { + + .maxstack 8 + .locals init (int32 V_0) + IL_0000: ldc.i4.1 + IL_0001: stloc.0 + IL_0002: call class [mscorlib]System.Collections.Generic.List`1 Test::get_arr() + IL_0007: ldc.i4.1 + IL_0008: callvirt instance void class [mscorlib]System.Collections.Generic.List`1::Add(!0) + IL_000d: ldstr "_" + IL_0012: ldloca.s V_0 + IL_0014: constrained. [mscorlib]System.Int32 + IL_001a: callvirt instance string [mscorlib]System.Object::ToString() + IL_001f: ldstr "_" + IL_0024: call string [mscorlib]System.String::Concat(string, + string, + string) + IL_0029: ldc.i4.2 + IL_002a: stloc.0 + IL_002b: call class [mscorlib]System.Collections.Generic.List`1 Test::get_arr() + IL_0030: ldc.i4.2 + IL_0031: callvirt instance void class [mscorlib]System.Collections.Generic.List`1::Add(!0) + IL_0036: ldstr "_" + IL_003b: ldloca.s V_0 + IL_003d: constrained. [mscorlib]System.Int32 + IL_0043: callvirt instance string [mscorlib]System.Object::ToString() + IL_0048: ldstr "_" + IL_004d: call string [mscorlib]System.String::Concat(string, + string, + string) + IL_0052: ldc.i4.3 + IL_0053: stloc.0 + IL_0054: call class [mscorlib]System.Collections.Generic.List`1 Test::get_arr() + IL_0059: ldc.i4.3 + IL_005a: callvirt instance void class [mscorlib]System.Collections.Generic.List`1::Add(!0) + IL_005f: ldstr "_" + IL_0064: ldloca.s V_0 + IL_0066: constrained. [mscorlib]System.Int32 + IL_006c: callvirt instance string [mscorlib]System.Object::ToString() + IL_0071: ldstr "_" + IL_0076: call string [mscorlib]System.String::Concat(string, + string, + string) + IL_007b: ldc.i4.4 + IL_007c: stloc.0 + IL_007d: call class [mscorlib]System.Collections.Generic.List`1 Test::get_arr() + IL_0082: ldc.i4.4 + IL_0083: callvirt instance void class [mscorlib]System.Collections.Generic.List`1::Add(!0) + IL_0088: ldstr "_" + IL_008d: ldloca.s V_0 + IL_008f: constrained. [mscorlib]System.Int32 + IL_0095: callvirt instance string [mscorlib]System.Object::ToString() + IL_009a: ldstr "_" + IL_009f: call string [mscorlib]System.String::Concat(string, + string, + string) + IL_00a4: call string [mscorlib]System.String::Concat(string, + string, + string, + string) + IL_00a9: ret + }""" + + let test3Source = """ +let test3 () = + ss 1 + ss 2 + ss 3 + ss 4 + ss 5 +""" + let test3IL = """.method public static string test3() cil managed + { + + .maxstack 8 + .locals init (int32 V_0) + IL_0000: ldc.i4.5 + IL_0001: newarr [mscorlib]System.String + IL_0006: dup + IL_0007: ldc.i4.0 + IL_0008: ldc.i4.1 + IL_0009: stloc.0 + IL_000a: call class [mscorlib]System.Collections.Generic.List`1 Test::get_arr() + IL_000f: ldc.i4.1 + IL_0010: callvirt instance void class [mscorlib]System.Collections.Generic.List`1::Add(!0) + IL_0015: ldstr "_" + IL_001a: ldloca.s V_0 + IL_001c: constrained. [mscorlib]System.Int32 + IL_0022: callvirt instance string [mscorlib]System.Object::ToString() + IL_0027: ldstr "_" + IL_002c: call string [mscorlib]System.String::Concat(string, + string, + string) + IL_0031: stelem [mscorlib]System.String + IL_0036: dup + IL_0037: ldc.i4.1 + IL_0038: ldc.i4.2 + IL_0039: stloc.0 + IL_003a: call class [mscorlib]System.Collections.Generic.List`1 Test::get_arr() + IL_003f: ldc.i4.2 + IL_0040: callvirt instance void class [mscorlib]System.Collections.Generic.List`1::Add(!0) + IL_0045: ldstr "_" + IL_004a: ldloca.s V_0 + IL_004c: constrained. [mscorlib]System.Int32 + IL_0052: callvirt instance string [mscorlib]System.Object::ToString() + IL_0057: ldstr "_" + IL_005c: call string [mscorlib]System.String::Concat(string, + string, + string) + IL_0061: stelem [mscorlib]System.String + IL_0066: dup + IL_0067: ldc.i4.2 + IL_0068: ldc.i4.3 + IL_0069: stloc.0 + IL_006a: call class [mscorlib]System.Collections.Generic.List`1 Test::get_arr() + IL_006f: ldc.i4.3 + IL_0070: callvirt instance void class [mscorlib]System.Collections.Generic.List`1::Add(!0) + IL_0075: ldstr "_" + IL_007a: ldloca.s V_0 + IL_007c: constrained. [mscorlib]System.Int32 + IL_0082: callvirt instance string [mscorlib]System.Object::ToString() + IL_0087: ldstr "_" + IL_008c: call string [mscorlib]System.String::Concat(string, + string, + string) + IL_0091: stelem [mscorlib]System.String + IL_0096: dup + IL_0097: ldc.i4.3 + IL_0098: ldc.i4.4 + IL_0099: stloc.0 + IL_009a: call class [mscorlib]System.Collections.Generic.List`1 Test::get_arr() + IL_009f: ldc.i4.4 + IL_00a0: callvirt instance void class [mscorlib]System.Collections.Generic.List`1::Add(!0) + IL_00a5: ldstr "_" + IL_00aa: ldloca.s V_0 + IL_00ac: constrained. [mscorlib]System.Int32 + IL_00b2: callvirt instance string [mscorlib]System.Object::ToString() + IL_00b7: ldstr "_" + IL_00bc: call string [mscorlib]System.String::Concat(string, + string, + string) + IL_00c1: stelem [mscorlib]System.String + IL_00c6: dup + IL_00c7: ldc.i4.4 + IL_00c8: ldc.i4.5 + IL_00c9: stloc.0 + IL_00ca: call class [mscorlib]System.Collections.Generic.List`1 Test::get_arr() + IL_00cf: ldc.i4.5 + IL_00d0: callvirt instance void class [mscorlib]System.Collections.Generic.List`1::Add(!0) + IL_00d5: ldstr "_" + IL_00da: ldloca.s V_0 + IL_00dc: constrained. [mscorlib]System.Int32 + IL_00e2: callvirt instance string [mscorlib]System.Object::ToString() + IL_00e7: ldstr "_" + IL_00ec: call string [mscorlib]System.String::Concat(string, + string, + string) + IL_00f1: stelem [mscorlib]System.String + IL_00f6: call string [mscorlib]System.String::Concat(string[]) + IL_00fb: ret + }""" + + let test4Source = """ +let test4 () = + ss 5 + ss 6 + ss 7 + String.Concat(ss 8, ss 9) + ss 10 + "_50_" + "_60_" + String.Concat(ss 100, String.Concat(ss 101, ss 102), ss 103) + String.Concat([|"_104_";"_105_"|]) + ss 106 +""" + let test4IL = """.method public static string test4() cil managed + { + + .maxstack 8 + .locals init (int32 V_0) + IL_0000: ldc.i4.s 13 + IL_0002: newarr [mscorlib]System.String + IL_0007: dup + IL_0008: ldc.i4.0 + IL_0009: ldc.i4.5 + IL_000a: stloc.0 + IL_000b: call class [mscorlib]System.Collections.Generic.List`1 Test::get_arr() + IL_0010: ldc.i4.5 + IL_0011: callvirt instance void class [mscorlib]System.Collections.Generic.List`1::Add(!0) + IL_0016: ldstr "_" + IL_001b: ldloca.s V_0 + IL_001d: constrained. [mscorlib]System.Int32 + IL_0023: callvirt instance string [mscorlib]System.Object::ToString() + IL_0028: ldstr "_" + IL_002d: call string [mscorlib]System.String::Concat(string, + string, + string) + IL_0032: stelem [mscorlib]System.String + IL_0037: dup + IL_0038: ldc.i4.1 + IL_0039: ldc.i4.6 + IL_003a: stloc.0 + IL_003b: call class [mscorlib]System.Collections.Generic.List`1 Test::get_arr() + IL_0040: ldc.i4.6 + IL_0041: callvirt instance void class [mscorlib]System.Collections.Generic.List`1::Add(!0) + IL_0046: ldstr "_" + IL_004b: ldloca.s V_0 + IL_004d: constrained. [mscorlib]System.Int32 + IL_0053: callvirt instance string [mscorlib]System.Object::ToString() + IL_0058: ldstr "_" + IL_005d: call string [mscorlib]System.String::Concat(string, + string, + string) + IL_0062: stelem [mscorlib]System.String + IL_0067: dup + IL_0068: ldc.i4.2 + IL_0069: ldc.i4.7 + IL_006a: stloc.0 + IL_006b: call class [mscorlib]System.Collections.Generic.List`1 Test::get_arr() + IL_0070: ldc.i4.7 + IL_0071: callvirt instance void class [mscorlib]System.Collections.Generic.List`1::Add(!0) + IL_0076: ldstr "_" + IL_007b: ldloca.s V_0 + IL_007d: constrained. [mscorlib]System.Int32 + IL_0083: callvirt instance string [mscorlib]System.Object::ToString() + IL_0088: ldstr "_" + IL_008d: call string [mscorlib]System.String::Concat(string, + string, + string) + IL_0092: stelem [mscorlib]System.String + IL_0097: dup + IL_0098: ldc.i4.3 + IL_0099: ldc.i4.8 + IL_009a: stloc.0 + IL_009b: call class [mscorlib]System.Collections.Generic.List`1 Test::get_arr() + IL_00a0: ldc.i4.8 + IL_00a1: callvirt instance void class [mscorlib]System.Collections.Generic.List`1::Add(!0) + IL_00a6: ldstr "_" + IL_00ab: ldloca.s V_0 + IL_00ad: constrained. [mscorlib]System.Int32 + IL_00b3: callvirt instance string [mscorlib]System.Object::ToString() + IL_00b8: ldstr "_" + IL_00bd: call string [mscorlib]System.String::Concat(string, + string, + string) + IL_00c2: stelem [mscorlib]System.String + IL_00c7: dup + IL_00c8: ldc.i4.4 + IL_00c9: ldc.i4.s 9 + IL_00cb: stloc.0 + IL_00cc: call class [mscorlib]System.Collections.Generic.List`1 Test::get_arr() + IL_00d1: ldc.i4.s 9 + IL_00d3: callvirt instance void class [mscorlib]System.Collections.Generic.List`1::Add(!0) + IL_00d8: ldstr "_" + IL_00dd: ldloca.s V_0 + IL_00df: constrained. [mscorlib]System.Int32 + IL_00e5: callvirt instance string [mscorlib]System.Object::ToString() + IL_00ea: ldstr "_" + IL_00ef: call string [mscorlib]System.String::Concat(string, + string, + string) + IL_00f4: stelem [mscorlib]System.String + IL_00f9: dup + IL_00fa: ldc.i4.5 + IL_00fb: ldc.i4.s 10 + IL_00fd: stloc.0 + IL_00fe: call class [mscorlib]System.Collections.Generic.List`1 Test::get_arr() + IL_0103: ldc.i4.s 10 + IL_0105: callvirt instance void class [mscorlib]System.Collections.Generic.List`1::Add(!0) + IL_010a: ldstr "_" + IL_010f: ldloca.s V_0 + IL_0111: constrained. [mscorlib]System.Int32 + IL_0117: callvirt instance string [mscorlib]System.Object::ToString() + IL_011c: ldstr "_" + IL_0121: call string [mscorlib]System.String::Concat(string, + string, + string) + IL_0126: stelem [mscorlib]System.String + IL_012b: dup + IL_012c: ldc.i4.6 + IL_012d: ldstr "_50__60_" + IL_0132: stelem [mscorlib]System.String + IL_0137: dup + IL_0138: ldc.i4.7 + IL_0139: ldc.i4.s 100 + IL_013b: stloc.0 + IL_013c: call class [mscorlib]System.Collections.Generic.List`1 Test::get_arr() + IL_0141: ldc.i4.s 100 + IL_0143: callvirt instance void class [mscorlib]System.Collections.Generic.List`1::Add(!0) + IL_0148: ldstr "_" + IL_014d: ldloca.s V_0 + IL_014f: constrained. [mscorlib]System.Int32 + IL_0155: callvirt instance string [mscorlib]System.Object::ToString() + IL_015a: ldstr "_" + IL_015f: call string [mscorlib]System.String::Concat(string, + string, + string) + IL_0164: stelem [mscorlib]System.String + IL_0169: dup + IL_016a: ldc.i4.8 + IL_016b: ldc.i4.s 101 + IL_016d: stloc.0 + IL_016e: call class [mscorlib]System.Collections.Generic.List`1 Test::get_arr() + IL_0173: ldc.i4.s 101 + IL_0175: callvirt instance void class [mscorlib]System.Collections.Generic.List`1::Add(!0) + IL_017a: ldstr "_" + IL_017f: ldloca.s V_0 + IL_0181: constrained. [mscorlib]System.Int32 + IL_0187: callvirt instance string [mscorlib]System.Object::ToString() + IL_018c: ldstr "_" + IL_0191: call string [mscorlib]System.String::Concat(string, + string, + string) + IL_0196: stelem [mscorlib]System.String + IL_019b: dup + IL_019c: ldc.i4.s 9 + IL_019e: ldc.i4.s 102 + IL_01a0: stloc.0 + IL_01a1: call class [mscorlib]System.Collections.Generic.List`1 Test::get_arr() + IL_01a6: ldc.i4.s 102 + IL_01a8: callvirt instance void class [mscorlib]System.Collections.Generic.List`1::Add(!0) + IL_01ad: ldstr "_" + IL_01b2: ldloca.s V_0 + IL_01b4: constrained. [mscorlib]System.Int32 + IL_01ba: callvirt instance string [mscorlib]System.Object::ToString() + IL_01bf: ldstr "_" + IL_01c4: call string [mscorlib]System.String::Concat(string, + string, + string) + IL_01c9: stelem [mscorlib]System.String + IL_01ce: dup + IL_01cf: ldc.i4.s 10 + IL_01d1: ldc.i4.s 103 + IL_01d3: stloc.0 + IL_01d4: call class [mscorlib]System.Collections.Generic.List`1 Test::get_arr() + IL_01d9: ldc.i4.s 103 + IL_01db: callvirt instance void class [mscorlib]System.Collections.Generic.List`1::Add(!0) + IL_01e0: ldstr "_" + IL_01e5: ldloca.s V_0 + IL_01e7: constrained. [mscorlib]System.Int32 + IL_01ed: callvirt instance string [mscorlib]System.Object::ToString() + IL_01f2: ldstr "_" + IL_01f7: call string [mscorlib]System.String::Concat(string, + string, + string) + IL_01fc: stelem [mscorlib]System.String + IL_0201: dup + IL_0202: ldc.i4.s 11 + IL_0204: ldstr "_104__105_" + IL_0209: stelem [mscorlib]System.String + IL_020e: dup + IL_020f: ldc.i4.s 12 + IL_0211: ldc.i4.s 106 + IL_0213: stloc.0 + IL_0214: call class [mscorlib]System.Collections.Generic.List`1 Test::get_arr() + IL_0219: ldc.i4.s 106 + IL_021b: callvirt instance void class [mscorlib]System.Collections.Generic.List`1::Add(!0) + IL_0220: ldstr "_" + IL_0225: ldloca.s V_0 + IL_0227: constrained. [mscorlib]System.Int32 + IL_022d: callvirt instance string [mscorlib]System.Object::ToString() + IL_0232: ldstr "_" + IL_0237: call string [mscorlib]System.String::Concat(string, + string, + string) + IL_023c: stelem [mscorlib]System.String + IL_0241: call string [mscorlib]System.String::Concat(string[]) + IL_0246: ret + }""" + + let test5Source = """ +let test5 () = + ss 5 + ss 6 + ss 7 + String.Concat(ss 8, ss 9) + ss 10 + "_50_" + "_60_" + String.Concat(ss 100, (let x = String.Concat(ss 101, ss 102) in Console.WriteLine(x);x), ss 103) + String.Concat([|"_104_";"_105_"|]) + ss 106 +""" + let test5IL = """.method public static string test5() cil managed + { + + .maxstack 9 + .locals init (int32 V_0, + string V_1) + IL_0000: ldc.i4.s 12 + IL_0002: newarr [mscorlib]System.String + IL_0007: dup + IL_0008: ldc.i4.0 + IL_0009: ldc.i4.5 + IL_000a: stloc.0 + IL_000b: call class [mscorlib]System.Collections.Generic.List`1 Test::get_arr() + IL_0010: ldc.i4.5 + IL_0011: callvirt instance void class [mscorlib]System.Collections.Generic.List`1::Add(!0) + IL_0016: ldstr "_" + IL_001b: ldloca.s V_0 + IL_001d: constrained. [mscorlib]System.Int32 + IL_0023: callvirt instance string [mscorlib]System.Object::ToString() + IL_0028: ldstr "_" + IL_002d: call string [mscorlib]System.String::Concat(string, + string, + string) + IL_0032: stelem [mscorlib]System.String + IL_0037: dup + IL_0038: ldc.i4.1 + IL_0039: ldc.i4.6 + IL_003a: stloc.0 + IL_003b: call class [mscorlib]System.Collections.Generic.List`1 Test::get_arr() + IL_0040: ldc.i4.6 + IL_0041: callvirt instance void class [mscorlib]System.Collections.Generic.List`1::Add(!0) + IL_0046: ldstr "_" + IL_004b: ldloca.s V_0 + IL_004d: constrained. [mscorlib]System.Int32 + IL_0053: callvirt instance string [mscorlib]System.Object::ToString() + IL_0058: ldstr "_" + IL_005d: call string [mscorlib]System.String::Concat(string, + string, + string) + IL_0062: stelem [mscorlib]System.String + IL_0067: dup + IL_0068: ldc.i4.2 + IL_0069: ldc.i4.7 + IL_006a: stloc.0 + IL_006b: call class [mscorlib]System.Collections.Generic.List`1 Test::get_arr() + IL_0070: ldc.i4.7 + IL_0071: callvirt instance void class [mscorlib]System.Collections.Generic.List`1::Add(!0) + IL_0076: ldstr "_" + IL_007b: ldloca.s V_0 + IL_007d: constrained. [mscorlib]System.Int32 + IL_0083: callvirt instance string [mscorlib]System.Object::ToString() + IL_0088: ldstr "_" + IL_008d: call string [mscorlib]System.String::Concat(string, + string, + string) + IL_0092: stelem [mscorlib]System.String + IL_0097: dup + IL_0098: ldc.i4.3 + IL_0099: ldc.i4.8 + IL_009a: stloc.0 + IL_009b: call class [mscorlib]System.Collections.Generic.List`1 Test::get_arr() + IL_00a0: ldc.i4.8 + IL_00a1: callvirt instance void class [mscorlib]System.Collections.Generic.List`1::Add(!0) + IL_00a6: ldstr "_" + IL_00ab: ldloca.s V_0 + IL_00ad: constrained. [mscorlib]System.Int32 + IL_00b3: callvirt instance string [mscorlib]System.Object::ToString() + IL_00b8: ldstr "_" + IL_00bd: call string [mscorlib]System.String::Concat(string, + string, + string) + IL_00c2: stelem [mscorlib]System.String + IL_00c7: dup + IL_00c8: ldc.i4.4 + IL_00c9: ldc.i4.s 9 + IL_00cb: stloc.0 + IL_00cc: call class [mscorlib]System.Collections.Generic.List`1 Test::get_arr() + IL_00d1: ldc.i4.s 9 + IL_00d3: callvirt instance void class [mscorlib]System.Collections.Generic.List`1::Add(!0) + IL_00d8: ldstr "_" + IL_00dd: ldloca.s V_0 + IL_00df: constrained. [mscorlib]System.Int32 + IL_00e5: callvirt instance string [mscorlib]System.Object::ToString() + IL_00ea: ldstr "_" + IL_00ef: call string [mscorlib]System.String::Concat(string, + string, + string) + IL_00f4: stelem [mscorlib]System.String + IL_00f9: dup + IL_00fa: ldc.i4.5 + IL_00fb: ldc.i4.s 10 + IL_00fd: stloc.0 + IL_00fe: call class [mscorlib]System.Collections.Generic.List`1 Test::get_arr() + IL_0103: ldc.i4.s 10 + IL_0105: callvirt instance void class [mscorlib]System.Collections.Generic.List`1::Add(!0) + IL_010a: ldstr "_" + IL_010f: ldloca.s V_0 + IL_0111: constrained. [mscorlib]System.Int32 + IL_0117: callvirt instance string [mscorlib]System.Object::ToString() + IL_011c: ldstr "_" + IL_0121: call string [mscorlib]System.String::Concat(string, + string, + string) + IL_0126: stelem [mscorlib]System.String + IL_012b: dup + IL_012c: ldc.i4.6 + IL_012d: ldstr "_50__60_" + IL_0132: stelem [mscorlib]System.String + IL_0137: dup + IL_0138: ldc.i4.7 + IL_0139: ldc.i4.s 100 + IL_013b: stloc.0 + IL_013c: call class [mscorlib]System.Collections.Generic.List`1 Test::get_arr() + IL_0141: ldc.i4.s 100 + IL_0143: callvirt instance void class [mscorlib]System.Collections.Generic.List`1::Add(!0) + IL_0148: ldstr "_" + IL_014d: ldloca.s V_0 + IL_014f: constrained. [mscorlib]System.Int32 + IL_0155: callvirt instance string [mscorlib]System.Object::ToString() + IL_015a: ldstr "_" + IL_015f: call string [mscorlib]System.String::Concat(string, + string, + string) + IL_0164: stelem [mscorlib]System.String + IL_0169: dup + IL_016a: ldc.i4.8 + IL_016b: ldc.i4.s 101 + IL_016d: stloc.0 + IL_016e: call class [mscorlib]System.Collections.Generic.List`1 Test::get_arr() + IL_0173: ldc.i4.s 101 + IL_0175: callvirt instance void class [mscorlib]System.Collections.Generic.List`1::Add(!0) + IL_017a: ldstr "_" + IL_017f: ldloca.s V_0 + IL_0181: constrained. [mscorlib]System.Int32 + IL_0187: callvirt instance string [mscorlib]System.Object::ToString() + IL_018c: ldstr "_" + IL_0191: call string [mscorlib]System.String::Concat(string, + string, + string) + IL_0196: ldc.i4.s 102 + IL_0198: stloc.0 + IL_0199: call class [mscorlib]System.Collections.Generic.List`1 Test::get_arr() + IL_019e: ldc.i4.s 102 + IL_01a0: callvirt instance void class [mscorlib]System.Collections.Generic.List`1::Add(!0) + IL_01a5: ldstr "_" + IL_01aa: ldloca.s V_0 + IL_01ac: constrained. [mscorlib]System.Int32 + IL_01b2: callvirt instance string [mscorlib]System.Object::ToString() + IL_01b7: ldstr "_" + IL_01bc: call string [mscorlib]System.String::Concat(string, + string, + string) + IL_01c1: call string [mscorlib]System.String::Concat(string, + string) + IL_01c6: stloc.1 + IL_01c7: ldloc.1 + IL_01c8: call void [mscorlib]System.Console::WriteLine(string) + IL_01cd: ldloc.1 + IL_01ce: stelem [mscorlib]System.String + IL_01d3: dup + IL_01d4: ldc.i4.s 9 + IL_01d6: ldc.i4.s 103 + IL_01d8: stloc.0 + IL_01d9: call class [mscorlib]System.Collections.Generic.List`1 Test::get_arr() + IL_01de: ldc.i4.s 103 + IL_01e0: callvirt instance void class [mscorlib]System.Collections.Generic.List`1::Add(!0) + IL_01e5: ldstr "_" + IL_01ea: ldloca.s V_0 + IL_01ec: constrained. [mscorlib]System.Int32 + IL_01f2: callvirt instance string [mscorlib]System.Object::ToString() + IL_01f7: ldstr "_" + IL_01fc: call string [mscorlib]System.String::Concat(string, + string, + string) + IL_0201: stelem [mscorlib]System.String + IL_0206: dup + IL_0207: ldc.i4.s 10 + IL_0209: ldstr "_104__105_" + IL_020e: stelem [mscorlib]System.String + IL_0213: dup + IL_0214: ldc.i4.s 11 + IL_0216: ldc.i4.s 106 + IL_0218: stloc.0 + IL_0219: call class [mscorlib]System.Collections.Generic.List`1 Test::get_arr() + IL_021e: ldc.i4.s 106 + IL_0220: callvirt instance void class [mscorlib]System.Collections.Generic.List`1::Add(!0) + IL_0225: ldstr "_" + IL_022a: ldloca.s V_0 + IL_022c: constrained. [mscorlib]System.Int32 + IL_0232: callvirt instance string [mscorlib]System.Object::ToString() + IL_0237: ldstr "_" + IL_023c: call string [mscorlib]System.String::Concat(string, + string, + string) + IL_0241: stelem [mscorlib]System.String + IL_0246: call string [mscorlib]System.String::Concat(string[]) + IL_024b: ret + }""" + + let test6Source = """ +let inline inlineStringConcat str1 str2 = str1 + str2 + +let test6 () = + inlineStringConcat (inlineStringConcat (ss 1) (ss 2)) (ss 3) + ss 4 +""" + let test6IL = """.method public static string test6() cil managed + { + + .maxstack 8 + .locals init (int32 V_0) + IL_0000: ldc.i4.1 + IL_0001: stloc.0 + IL_0002: call class [mscorlib]System.Collections.Generic.List`1 Test::get_arr() + IL_0007: ldc.i4.1 + IL_0008: callvirt instance void class [mscorlib]System.Collections.Generic.List`1::Add(!0) + IL_000d: ldstr "_" + IL_0012: ldloca.s V_0 + IL_0014: constrained. [mscorlib]System.Int32 + IL_001a: callvirt instance string [mscorlib]System.Object::ToString() + IL_001f: ldstr "_" + IL_0024: call string [mscorlib]System.String::Concat(string, + string, + string) + IL_0029: ldc.i4.2 + IL_002a: stloc.0 + IL_002b: call class [mscorlib]System.Collections.Generic.List`1 Test::get_arr() + IL_0030: ldc.i4.2 + IL_0031: callvirt instance void class [mscorlib]System.Collections.Generic.List`1::Add(!0) + IL_0036: ldstr "_" + IL_003b: ldloca.s V_0 + IL_003d: constrained. [mscorlib]System.Int32 + IL_0043: callvirt instance string [mscorlib]System.Object::ToString() + IL_0048: ldstr "_" + IL_004d: call string [mscorlib]System.String::Concat(string, + string, + string) + IL_0052: ldc.i4.3 + IL_0053: stloc.0 + IL_0054: call class [mscorlib]System.Collections.Generic.List`1 Test::get_arr() + IL_0059: ldc.i4.3 + IL_005a: callvirt instance void class [mscorlib]System.Collections.Generic.List`1::Add(!0) + IL_005f: ldstr "_" + IL_0064: ldloca.s V_0 + IL_0066: constrained. [mscorlib]System.Int32 + IL_006c: callvirt instance string [mscorlib]System.Object::ToString() + IL_0071: ldstr "_" + IL_0076: call string [mscorlib]System.String::Concat(string, + string, + string) + IL_007b: ldc.i4.4 + IL_007c: stloc.0 + IL_007d: call class [mscorlib]System.Collections.Generic.List`1 Test::get_arr() + IL_0082: ldc.i4.4 + IL_0083: callvirt instance void class [mscorlib]System.Collections.Generic.List`1::Add(!0) + IL_0088: ldstr "_" + IL_008d: ldloca.s V_0 + IL_008f: constrained. [mscorlib]System.Int32 + IL_0095: callvirt instance string [mscorlib]System.Object::ToString() + IL_009a: ldstr "_" + IL_009f: call string [mscorlib]System.String::Concat(string, + string, + string) + IL_00a4: call string [mscorlib]System.String::Concat(string, + string, + string, + string) + IL_00a9: ret + }""" + + let test7Source = """ +let test7 () = + let x = 1 + x.ToString() + x.ToString() + x.ToString() +""" + let test7IL = """.method public static string test7() cil managed + { + + .maxstack 5 + .locals init (int32 V_0) + IL_0000: ldc.i4.1 + IL_0001: stloc.0 + IL_0002: ldloca.s V_0 + IL_0004: constrained. [mscorlib]System.Int32 + IL_000a: callvirt instance string [mscorlib]System.Object::ToString() + IL_000f: ldloca.s V_0 + IL_0011: constrained. [mscorlib]System.Int32 + IL_0017: callvirt instance string [mscorlib]System.Object::ToString() + IL_001c: ldloca.s V_0 + IL_001e: constrained. [mscorlib]System.Int32 + IL_0024: callvirt instance string [mscorlib]System.Object::ToString() + IL_0029: call string [mscorlib]System.String::Concat(string, + string, + string) + IL_002e: ret + }""" + + let test8Source = """ +let test8 () = + let x = 1 + x.ToString() + x.ToString() + x.ToString() + x.ToString() +""" + let test8IL = """.method public static string test8() cil managed + { + + .maxstack 6 + .locals init (int32 V_0) + IL_0000: ldc.i4.1 + IL_0001: stloc.0 + IL_0002: ldloca.s V_0 + IL_0004: constrained. [mscorlib]System.Int32 + IL_000a: callvirt instance string [mscorlib]System.Object::ToString() + IL_000f: ldloca.s V_0 + IL_0011: constrained. [mscorlib]System.Int32 + IL_0017: callvirt instance string [mscorlib]System.Object::ToString() + IL_001c: ldloca.s V_0 + IL_001e: constrained. [mscorlib]System.Int32 + IL_0024: callvirt instance string [mscorlib]System.Object::ToString() + IL_0029: ldloca.s V_0 + IL_002b: constrained. [mscorlib]System.Int32 + IL_0031: callvirt instance string [mscorlib]System.Object::ToString() + IL_0036: call string [mscorlib]System.String::Concat(string, + string, + string, + string) + IL_003b: ret + }""" + + let test9Source = """ +let test9 () = + let x = 1 + x.ToString() + x.ToString() + x.ToString() + x.ToString() + x.ToString() +""" + let test9IL = """.method public static string test9() cil managed + { + + .maxstack 6 + .locals init (int32 V_0) + IL_0000: ldc.i4.1 + IL_0001: stloc.0 + IL_0002: ldc.i4.5 + IL_0003: newarr [mscorlib]System.String + IL_0008: dup + IL_0009: ldc.i4.0 + IL_000a: ldloca.s V_0 + IL_000c: constrained. [mscorlib]System.Int32 + IL_0012: callvirt instance string [mscorlib]System.Object::ToString() + IL_0017: stelem [mscorlib]System.String + IL_001c: dup + IL_001d: ldc.i4.1 + IL_001e: ldloca.s V_0 + IL_0020: constrained. [mscorlib]System.Int32 + IL_0026: callvirt instance string [mscorlib]System.Object::ToString() + IL_002b: stelem [mscorlib]System.String + IL_0030: dup + IL_0031: ldc.i4.2 + IL_0032: ldloca.s V_0 + IL_0034: constrained. [mscorlib]System.Int32 + IL_003a: callvirt instance string [mscorlib]System.Object::ToString() + IL_003f: stelem [mscorlib]System.String + IL_0044: dup + IL_0045: ldc.i4.3 + IL_0046: ldloca.s V_0 + IL_0048: constrained. [mscorlib]System.Int32 + IL_004e: callvirt instance string [mscorlib]System.Object::ToString() + IL_0053: stelem [mscorlib]System.String + IL_0058: dup + IL_0059: ldc.i4.4 + IL_005a: ldloca.s V_0 + IL_005c: constrained. [mscorlib]System.Int32 + IL_0062: callvirt instance string [mscorlib]System.Object::ToString() + IL_0067: stelem [mscorlib]System.String + IL_006c: call string [mscorlib]System.String::Concat(string[]) + IL_0071: ret + }""" + + let sources = + [ + baseSource + test1Source + test2Source + test3Source + test4Source + test5Source + test6Source + test7Source + test8Source + test9Source + ] + let source = String.Join("", sources) + ILChecker.check source + [ + test1IL + test2IL + test3IL + test4IL + test5IL + test6IL + test7IL + test8IL + test9IL + ] diff --git a/tests/FSharp.Directory.Build.props b/tests/FSharp.Directory.Build.props new file mode 100644 index 0000000000..bb8eac309b --- /dev/null +++ b/tests/FSharp.Directory.Build.props @@ -0,0 +1,3 @@ + + + diff --git a/tests/FSharp.Directory.Build.targets b/tests/FSharp.Directory.Build.targets new file mode 100644 index 0000000000..590214e9b0 --- /dev/null +++ b/tests/FSharp.Directory.Build.targets @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/tests/projects/Directory.Build.props b/tests/projects/Directory.Build.props new file mode 100644 index 0000000000..bb5b23d29d --- /dev/null +++ b/tests/projects/Directory.Build.props @@ -0,0 +1,3 @@ + + + diff --git a/tests/projects/Directory.Build.targets b/tests/projects/Directory.Build.targets new file mode 100644 index 0000000000..bb5b23d29d --- /dev/null +++ b/tests/projects/Directory.Build.targets @@ -0,0 +1,3 @@ + + + diff --git a/tests/projects/Sample_NETCoreSDK_FSharp_Library_netstandard2_0/Directory.Build.props b/tests/projects/Sample_NETCoreSDK_FSharp_Library_netstandard2_0/Directory.Build.props new file mode 100644 index 0000000000..bb8eac309b --- /dev/null +++ b/tests/projects/Sample_NETCoreSDK_FSharp_Library_netstandard2_0/Directory.Build.props @@ -0,0 +1,3 @@ + + + diff --git a/tests/projects/Sample_NETCoreSDK_FSharp_Library_netstandard2_0/Directory.Build.targets b/tests/projects/Sample_NETCoreSDK_FSharp_Library_netstandard2_0/Directory.Build.targets new file mode 100644 index 0000000000..ccd47cc0a9 --- /dev/null +++ b/tests/projects/Sample_NETCoreSDK_FSharp_Library_netstandard2_0/Directory.Build.targets @@ -0,0 +1,3 @@ + + + diff --git a/tests/projects/misc/Directory.Build.props b/tests/projects/misc/Directory.Build.props new file mode 100644 index 0000000000..056d355249 --- /dev/null +++ b/tests/projects/misc/Directory.Build.props @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/tests/projects/misc/Directory.Build.targets b/tests/projects/misc/Directory.Build.targets new file mode 100644 index 0000000000..056d355249 --- /dev/null +++ b/tests/projects/misc/Directory.Build.targets @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/tests/projects/misc/ProjectWithBuildErrors/ProjectWithBuildErrors/ProjectWithBuildErrors.fsproj b/tests/projects/misc/ProjectWithBuildErrors/ProjectWithBuildErrors/ProjectWithBuildErrors.fsproj index 43aa06b77c..b1a44ceda7 100644 --- a/tests/projects/misc/ProjectWithBuildErrors/ProjectWithBuildErrors/ProjectWithBuildErrors.fsproj +++ b/tests/projects/misc/ProjectWithBuildErrors/ProjectWithBuildErrors/ProjectWithBuildErrors.fsproj @@ -1,83 +1,15 @@  - - + + - Debug - AnyCPU - 2.0 - 9eda4075-e1e5-4f51-8908-5d608c092254 - Exe - ProjectWithBuildErrors - ProjectWithBuildErrors - v4.5.2 - true + net452 4.4.1.0 - ProjectWithBuildErrors - - true - full - false - false - bin\$(Configuration)\ - DEBUG;TRACE - 3 - AnyCPU - bin\$(Configuration)\$(AssemblyName).XML - true - - - pdbonly - true - true - bin\$(Configuration)\ - TRACE - 3 - AnyCPU - bin\$(Configuration)\$(AssemblyName).XML - true - - - 11 - - - - - $(MSBuildExtensionsPath32)\..\Microsoft SDKs\F#\3.0\Framework\v4.0\Microsoft.FSharp.Targets - - - - - $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\FSharp\Microsoft.FSharp.Targets - - - - + - - - - - - FSharp.Core - FSharp.Core.dll - $(MSBuildProgramFiles32)\Reference Assemblies\Microsoft\FSharp\.NETFramework\v4.0\$(TargetFSharpCoreVersion)\FSharp.Core.dll - - - - - - ..\packages\System.ValueTuple.4.4.0\lib\netstandard1.0\System.ValueTuple.dll - - - \ No newline at end of file + + diff --git a/tests/projects/misc/ProjectWithBuildErrors/ProjectWithBuildErrors/packages.config b/tests/projects/misc/ProjectWithBuildErrors/ProjectWithBuildErrors/packages.config deleted file mode 100644 index 4db38eab9c..0000000000 --- a/tests/projects/misc/ProjectWithBuildErrors/ProjectWithBuildErrors/packages.config +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/tests/projects/misc/SameFileBelongsToMultipleProjects/Library2/Library2.fsproj b/tests/projects/misc/SameFileBelongsToMultipleProjects/Library2/Library2.fsproj index 2bbd1c6f28..090a7331af 100644 --- a/tests/projects/misc/SameFileBelongsToMultipleProjects/Library2/Library2.fsproj +++ b/tests/projects/misc/SameFileBelongsToMultipleProjects/Library2/Library2.fsproj @@ -1,81 +1,17 @@  - - + + - Debug - AnyCPU - 2.0 - e72ee9de-323e-4f99-8d7e-1a1ed8a3477c - Library - Library2 - Library2 - v4.5.2 + net452 4.4.1.0 - true - Library2 - - true - full - false - false - bin\$(Configuration)\ - DEBUG;TRACE - 3 - bin\$(Configuration)\$(AssemblyName).XML - - - pdbonly - true - true - bin\$(Configuration)\ - RELEASE;TRACE - 3 - bin\$(Configuration)\$(AssemblyName).XML - - - 11 - - - - - $(MSBuildExtensionsPath32)\..\Microsoft SDKs\F#\3.0\Framework\v4.0\Microsoft.FSharp.Targets - - - - - $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\FSharp\Microsoft.FSharp.Targets - - - - + Class.fs - - - - - - FSharp.Core - FSharp.Core.dll - $(MSBuildProgramFiles32)\Reference Assemblies\Microsoft\FSharp\.NETFramework\v4.0\$(TargetFSharpCoreVersion)\FSharp.Core.dll - - - - - - ..\packages\System.ValueTuple.4.4.0\lib\netstandard1.0\System.ValueTuple.dll - - - \ No newline at end of file + + diff --git a/tests/projects/misc/SameFileBelongsToMultipleProjects/Library2/packages.config b/tests/projects/misc/SameFileBelongsToMultipleProjects/Library2/packages.config deleted file mode 100644 index 4db38eab9c..0000000000 --- a/tests/projects/misc/SameFileBelongsToMultipleProjects/Library2/packages.config +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/tests/projects/misc/SameFileBelongsToMultipleProjects/SameFileBelongsToMultipleProjects/SameFileBelongsToMultipleProjects.fsproj b/tests/projects/misc/SameFileBelongsToMultipleProjects/SameFileBelongsToMultipleProjects/SameFileBelongsToMultipleProjects.fsproj index 5215c45575..f8ab90c783 100644 --- a/tests/projects/misc/SameFileBelongsToMultipleProjects/SameFileBelongsToMultipleProjects/SameFileBelongsToMultipleProjects.fsproj +++ b/tests/projects/misc/SameFileBelongsToMultipleProjects/SameFileBelongsToMultipleProjects/SameFileBelongsToMultipleProjects.fsproj @@ -1,90 +1,19 @@  - - + + - Debug - AnyCPU - 2.0 - df29450f-abd7-49fb-96c5-c9cae9a54f40 - Exe - ConsoleApplication1 - ConsoleApplication1 - v4.5.2 - true + net452> 4.4.1.0 - SameFileBelongsToMultipleProjects - - true - full - false - false - bin\$(Configuration)\ - DEBUG;TRACE - 3 - AnyCPU - bin\$(Configuration)\$(AssemblyName).XML - true - - - pdbonly - true - true - bin\$(Configuration)\ - TRACE - 3 - AnyCPU - bin\$(Configuration)\$(AssemblyName).XML - true - - - - - FSharp.Core - FSharp.Core.dll - $(MSBuildProgramFiles32)\Reference Assemblies\Microsoft\FSharp\.NETFramework\v4.0\$(TargetFSharpCoreVersion)\FSharp.Core.dll - - - ..\packages\System.ValueTuple.4.4.0\lib\netstandard1.0\System.ValueTuple.dll - True - - - - - + + - - Library2 - {e72ee9de-323e-4f99-8d7e-1a1ed8a3477c} - True - + - - 11 - - - - - $(MSBuildExtensionsPath32)\..\Microsoft SDKs\F#\3.0\Framework\v4.0\Microsoft.FSharp.Targets - - - - - $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\FSharp\Microsoft.FSharp.Targets - - - - - - \ No newline at end of file + + diff --git a/tests/projects/misc/TestProjectChanges/Library1AlwaysInMatchingConfiguration/Library1AlwaysInMatchingConfiguration.fsproj b/tests/projects/misc/TestProjectChanges/Library1AlwaysInMatchingConfiguration/Library1AlwaysInMatchingConfiguration.fsproj index a69c8f4efe..7b711f6166 100644 --- a/tests/projects/misc/TestProjectChanges/Library1AlwaysInMatchingConfiguration/Library1AlwaysInMatchingConfiguration.fsproj +++ b/tests/projects/misc/TestProjectChanges/Library1AlwaysInMatchingConfiguration/Library1AlwaysInMatchingConfiguration.fsproj @@ -1,77 +1,14 @@  - - + + - Debug - AnyCPU - 2.0 - 9f36577a-657b-4117-a118-f69ab182aa31 - Library - Library1AlwaysInMatchingConfiguration - Library1AlwaysInMatchingConfiguration - v4.5.2 + net452 4.4.1.0 - true - Library1AlwaysInMatchingConfiguration - - true - full - false - false - bin\$(Configuration)\ - DEBUG;TRACE - 3 - bin\$(Configuration)\$(AssemblyName).XML - - - pdbonly - true - true - bin\$(Configuration)\ - RELEASE;TRACE - 3 - bin\$(Configuration)\$(AssemblyName).XML - - - 11 - - - - - $(MSBuildExtensionsPath32)\..\Microsoft SDKs\F#\3.0\Framework\v4.0\Microsoft.FSharp.Targets - - - - - $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\FSharp\Microsoft.FSharp.Targets - - - - + - - - - FSharp.Core - FSharp.Core.dll - $(MSBuildProgramFiles32)\Reference Assemblies\Microsoft\FSharp\.NETFramework\v4.0\$(TargetFSharpCoreVersion)\FSharp.Core.dll - - - - - - ..\packages\System.ValueTuple.4.4.0\lib\netstandard1.0\System.ValueTuple.dll - - - - \ No newline at end of file + + diff --git a/tests/projects/misc/TestProjectChanges/Library1AlwaysInMatchingConfiguration/fff.config b/tests/projects/misc/TestProjectChanges/Library1AlwaysInMatchingConfiguration/fff.config deleted file mode 100644 index 4db38eab9c..0000000000 --- a/tests/projects/misc/TestProjectChanges/Library1AlwaysInMatchingConfiguration/fff.config +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/tests/projects/misc/TestProjectChanges/Library2AlwaysInDebugConfiguration/Library2AlwaysInDebugConfiguration.fsproj b/tests/projects/misc/TestProjectChanges/Library2AlwaysInDebugConfiguration/Library2AlwaysInDebugConfiguration.fsproj index a39259e191..7b711f6166 100644 --- a/tests/projects/misc/TestProjectChanges/Library2AlwaysInDebugConfiguration/Library2AlwaysInDebugConfiguration.fsproj +++ b/tests/projects/misc/TestProjectChanges/Library2AlwaysInDebugConfiguration/Library2AlwaysInDebugConfiguration.fsproj @@ -1,78 +1,14 @@  - - + + - Debug - AnyCPU - 2.0 - e72ee9de-323e-4f99-8d7e-1a1ed8a3477c - Library - Library2AlwaysInDebugConfiguration - Library2AlwaysInDebugConfiguration - v4.5.2 + net452 4.4.1.0 - true - Library2AlwaysInDebugConfiguration - - true - full - false - false - bin\$(Configuration)\ - DEBUG;TRACE - 3 - bin\$(Configuration)\$(AssemblyName).XML - - - pdbonly - true - true - bin\$(Configuration)\ - RELEASE;TRACE - 3 - bin\$(Configuration)\$(AssemblyName).XML - - - 11 - - - - - $(MSBuildExtensionsPath32)\..\Microsoft SDKs\F#\3.0\Framework\v4.0\Microsoft.FSharp.Targets - - - - - $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\FSharp\Microsoft.FSharp.Targets - - - - + - - - - - - FSharp.Core - FSharp.Core.dll - $(MSBuildProgramFiles32)\Reference Assemblies\Microsoft\FSharp\.NETFramework\v4.0\$(TargetFSharpCoreVersion)\FSharp.Core.dll - - - - - - ..\packages\System.ValueTuple.4.4.0\lib\netstandard1.0\System.ValueTuple.dll - - - \ No newline at end of file + + diff --git a/tests/projects/misc/TestProjectChanges/Library2AlwaysInDebugConfiguration/packages.config b/tests/projects/misc/TestProjectChanges/Library2AlwaysInDebugConfiguration/packages.config deleted file mode 100644 index 4db38eab9c..0000000000 --- a/tests/projects/misc/TestProjectChanges/Library2AlwaysInDebugConfiguration/packages.config +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/tests/projects/misc/TestProjectChanges/TestProjectChanges/TestProjectChanges.fsproj b/tests/projects/misc/TestProjectChanges/TestProjectChanges/TestProjectChanges.fsproj index 1428be0568..3c5f9cd080 100644 --- a/tests/projects/misc/TestProjectChanges/TestProjectChanges/TestProjectChanges.fsproj +++ b/tests/projects/misc/TestProjectChanges/TestProjectChanges/TestProjectChanges.fsproj @@ -1,96 +1,20 @@  - - + + - Debug - AnyCPU - 2.0 - df29450f-abd7-49fb-96c5-c9cae9a54f40 - Exe - ConsoleApplication1 - ConsoleApplication1 - v4.5.2 - true + net452 4.4.1.0 - TestProjectChanges - - - true - full - false - false - bin\$(Configuration)\ - DEBUG;TRACE - 3 - AnyCPU - bin\$(Configuration)\$(AssemblyName).XML - true - - - pdbonly - true - true - bin\$(Configuration)\ - TRACE - 3 - AnyCPU - bin\$(Configuration)\$(AssemblyName).XML - true - - - - FSharp.Core - FSharp.Core.dll - $(MSBuildProgramFiles32)\Reference Assemblies\Microsoft\FSharp\.NETFramework\v4.0\$(TargetFSharpCoreVersion)\FSharp.Core.dll - - - ..\packages\System.ValueTuple.4.4.0\lib\netstandard1.0\System.ValueTuple.dll - True - - - - - + + - - Library1AlwaysInMatchingConfiguration - {9f36577a-657b-4117-a118-f69ab182aa31} - True - - - Library2AlwaysInDebugConfiguration - {e72ee9de-323e-4f99-8d7e-1a1ed8a3477c} - True - + + - - 11 - - - - - $(MSBuildExtensionsPath32)\..\Microsoft SDKs\F#\3.0\Framework\v4.0\Microsoft.FSharp.Targets - - - - - $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\FSharp\Microsoft.FSharp.Targets - - - - - - + diff --git a/tests/scripts/update-baselines.fsx b/tests/scripts/update-baselines.fsx new file mode 100644 index 0000000000..389517a9c3 --- /dev/null +++ b/tests/scripts/update-baselines.fsx @@ -0,0 +1,83 @@ +open System +open System.IO + +// this script is usefull for tests using a .bsl file (baseline) containing expected compiler output +// which is matched against .vserr or .err file aside once the test has run +// the script replaces all the .bsl/.bslpp with either .err or .vserr + +let diff path1 path2 = + let result = System.Text.StringBuilder() + let append s = result.AppendLine s |> ignore + + if not <| File.Exists(path1) then failwithf "Invalid path %s" path1 + if not <| File.Exists(path2) then failwithf "Invalid path %s" path2 + + let lines1 = File.ReadAllLines(path1) + let lines2 = File.ReadAllLines(path2) + + let minLines = min lines1.Length lines2.Length + + for i = 0 to (minLines - 1) do + + let normalizePath line = line + let line1 = normalizePath lines1.[i] + let line2 = normalizePath lines2.[i] + + if not (line1.Contains "// MVID") && + not (line1.Contains "// Image base:") && + not (line1.Contains ".line") && + not (line1.Contains " .ver ") && + not (line1.Contains "// Offset:") then + if line1 <> line2 then + append <| sprintf "diff between [%s] and [%s]" path1 path2 + append <| sprintf "line %d" (i+1) + append <| sprintf " - %s" line1 + append <| sprintf " + %s" line2 + + if lines1.Length <> lines2.Length then + append <| sprintf "diff between [%s] and [%s]" path1 path2 + append <| sprintf "diff at line %d" minLines + lines1.[minLines .. (lines1.Length - 1)] |> Array.iter (append << sprintf "- %s") + lines2.[minLines .. (lines2.Length - 1)] |> Array.iter (append << sprintf "+ %s") + + result.ToString() + +let fsdiff actualFile expectedFile = + let errorText = System.IO.File.ReadAllText actualFile + + let result = diff expectedFile actualFile + if result <> "" then + printfn "%s" result + + result + +let directories = + [ + "../fsharp/typecheck/sigs" + "../fsharp/typeProviders/negTests" + "../fsharpqa/Source" + ] + |> List.map (fun d -> Path.Combine(__SOURCE_DIRECTORY__, d) |> DirectoryInfo) + +let extensionPatterns = ["*.bsl"; "*.vsbsl"; "*.il.bsl"] +for d in directories do + for p in extensionPatterns do + for bslFile in d.GetFiles (p, SearchOption.AllDirectories) do + let baseLineFileName = bslFile.FullName + if not (baseLineFileName.EndsWith("bslpp")) then + let errFileName = + if baseLineFileName.EndsWith "vsbsl" then Path.ChangeExtension(baseLineFileName, "vserr") + elif baseLineFileName.EndsWith "il.bsl" then baseLineFileName.Replace("il.bsl", "il") + else Path.ChangeExtension(baseLineFileName, "err") + let baseLineFile = FileInfo(baseLineFileName) + let errFile = FileInfo(errFileName) + //let baseLineFilePreProcess = FileInfo(Path.ChangeExtension(errFile.FullName, "bslpp")) + + if baseLineFile.Exists && errFile.Exists then + + //printfn "consider %s and %s" baseLineFile.FullName errFileName + if fsdiff errFileName baseLineFileName <> "" then + + printfn "%s not matching, replacing with %s" baseLineFileName errFileName + if not (fsi.CommandLineArgs |> Array.contains "-n") then + errFile.CopyTo(baseLineFileName, true) |> ignore diff --git a/tests/service/CSharpProjectAnalysis.fs b/tests/service/CSharpProjectAnalysis.fs index a8b300abac..1aea1c82ef 100644 --- a/tests/service/CSharpProjectAnalysis.fs +++ b/tests/service/CSharpProjectAnalysis.fs @@ -30,8 +30,8 @@ open FSharp.Compiler.Service.Tests.Common let ``Test that csharp references are recognized as such`` () = let csharpAssembly = PathRelativeToTestAssembly "CSharp_Analysis.dll" let _, table = getProjectReferences("""module M""", [csharpAssembly]) - let ass = table.["CSharp_Analysis"] - let search = ass.Contents.Entities |> Seq.tryFind (fun e -> e.DisplayName = "CSharpClass") + let assembly = table.["CSharp_Analysis"] + let search = assembly.Contents.Entities |> Seq.tryFind (fun e -> e.DisplayName = "CSharpClass") Assert.True search.IsSome let found = search.Value // this is no F# thing diff --git a/tests/service/Common.fs b/tests/service/Common.fs index 0b60faa11a..589bcb3528 100644 --- a/tests/service/Common.fs +++ b/tests/service/Common.fs @@ -109,7 +109,7 @@ let mkProjectCommandLineArgsSilent (dllName, fileNames) = yield "--noframework" yield "--debug:full" yield "--define:DEBUG" -#if NETCOREAPP2_0 +#if NETCOREAPP yield "--targetprofile:netcore" #endif yield "--optimize-" @@ -212,17 +212,18 @@ let parseAndCheckScript (file, input) = | FSharpCheckFileAnswer.Succeeded(res) -> parseResult, res | res -> failwithf "Parsing did not finish... (%A)" res -let parseSourceCode (name: string, code: string) = - let location = Path.Combine(Path.GetTempPath(),"test"+string(hash (name, code))) - try Directory.CreateDirectory(location) |> ignore with _ -> () +let parseSource (source: string) = + let location = Path.GetTempFileName() + let filePath = Path.Combine(location, ".fs") + let dllPath = Path.Combine(location, ".dll") - let projPath = Path.Combine(location, name + ".fsproj") - let filePath = Path.Combine(location, name + ".fs") - let dllPath = Path.Combine(location, name + ".dll") let args = mkProjectCommandLineArgs(dllPath, [filePath]) let options, errors = checker.GetParsingOptionsFromCommandLineArgs(List.ofArray args) - let parseResults = checker.ParseFile(filePath, code, options) |> Async.RunSynchronously - parseResults.ParseTree + let parseResults = checker.ParseFile(filePath, source, options) |> Async.RunSynchronously + + match parseResults.ParseTree with + | Some parseTree -> parseTree + | None -> failwithf "Expected there to be a parse tree for source:\n%s" source /// Extract range info let tups (m:Range.range) = (m.StartLine, m.StartColumn), (m.EndLine, m.EndColumn) @@ -248,6 +249,9 @@ let attribsOfSymbol (s:FSharpSymbol) = if v.IsVolatile then yield "volatile" if v.IsStatic then yield "static" if v.IsLiteral then yield sprintf "%A" v.LiteralValue.Value + if v.IsAnonRecordField then + let info, tys, i = v.AnonRecordFieldDetails + yield "anon(" + string i + ", [" + info.Assembly.QualifiedName + "/" + String.concat "+" info.EnclosingCompiledTypeNames + "/" + info.CompiledName + "]" + String.concat "," info.SortedFieldNames + ")" | :? FSharpEntity as v -> diff --git a/tests/service/EditorTests.fs b/tests/service/EditorTests.fs index d097c71065..91990f95b7 100755 --- a/tests/service/EditorTests.fs +++ b/tests/service/EditorTests.fs @@ -36,12 +36,17 @@ open Microsoft.FSharp.Compiler.SourceCodeServices open FSharp.Compiler.Service.Tests.Common let stringMethods = - ["Chars"; "Clone"; "CompareTo"; "Contains"; "CopyTo"; "EndsWith"; "Equals"; - "GetEnumerator"; "GetHashCode"; "GetType"; "GetTypeCode"; "IndexOf"; - "IndexOfAny"; "Insert"; "IsNormalized"; "LastIndexOf"; "LastIndexOfAny"; + ["Chars"; "Clone"; "CompareTo"; "Contains"; "CopyTo"; + "EndsWith"; "Equals"; "GetEnumerator"; "GetHashCode"; "GetType"; "GetTypeCode"; + "IndexOf"; "IndexOfAny"; "Insert"; "IsNormalized"; "LastIndexOf"; "LastIndexOfAny"; "Length"; "Normalize"; "PadLeft"; "PadRight"; "Remove"; "Replace"; "Split"; "StartsWith"; "Substring"; "ToCharArray"; "ToLower"; "ToLowerInvariant"; - "ToString"; "ToUpper"; "ToUpperInvariant"; "Trim"; "TrimEnd"; "TrimStart"] + "ToString"; "ToUpper"; "ToUpperInvariant"; "Trim"; "TrimEnd"; "TrimStart"; ] + +// opening System introduces these methods, and some samples here, do this and then assert +// on the string methods, so here we adjust the 'expected' list to include the new methods +let stringMethodsWhenSystemNamespaceOpened = + ["AsMemory"; "AsSpan"] @ stringMethods let input = """ @@ -63,6 +68,12 @@ let ``Intro test`` () = let identToken = FSharpTokenTag.IDENT // let projectOptions = checker.GetProjectOptionsFromScript(file, input) |> Async.RunSynchronously + // So we check that the messages are the same + for msg in typeCheckResults.Errors do + printfn "Got an error, hopefully with the right text: %A" msg + + printfn "typeCheckResults.Errors.Length = %d" typeCheckResults.Errors.Length + // We only expect one reported error. However, // on Unix, using filenames like /home/user/Test.fsx gives a second copy of all parse errors due to the // way the load closure for scripts is generated. So this returns two identical errors @@ -433,8 +444,7 @@ let _ = printf " %*a" 3 (fun _ _ -> ()) 2 typeCheckResults.GetFormatSpecifierLocationsAndArity() |> Array.map (fun (range,numArgs) -> range.StartLine, range.StartColumn, range.EndLine, range.EndColumn, numArgs) |> shouldEqual - [|(2, 45, 2, 47, 1); (3, 23, 3, 25, 1); (4, 38, 4, 40, 1); (5, 27, 5, 29 -, 1); + [|(2, 45, 2, 47, 1); (3, 23, 3, 25, 1); (4, 38, 4, 40, 1); (5, 27, 5, 29, 1); (6, 17, 6, 20, 2); (7, 17, 7, 22, 1); (8, 17, 8, 23, 1); (9, 18, 9, 22, 1); (10, 18, 10, 21, 1); (12, 12, 12, 15, 1); (15, 12, 15, 15, 1); (16, 28, 16, 30, 1); (18, 30, 18, 32, 1); (19, 30, 19, 32, 1); @@ -1093,7 +1103,7 @@ let _ = RegexTypedStatic.IsMatch<"ABC" >( (*$*) ) // TEST: no assert on Ctrl-sp File.WriteAllText(fileName1, fileSource1) let fileLines1 = File.ReadAllLines(fileName1) let fileNames = [fileName1] - let args = Array.append (mkProjectCommandLineArgs (dllName, fileNames)) [| "-r:" + PathRelativeToTestAssembly(@"UnitTests\MockTypeProviders\DummyProviderForLanguageServiceTesting.dll") |] + let args = Array.append (mkProjectCommandLineArgs (dllName, fileNames)) [| "-r:" + PathRelativeToTestAssembly(@"DummyProviderForLanguageServiceTesting.dll") |] let options = checker.GetProjectOptionsFromCommandLineArgs (projFileName, args) let cleanFileName a = if a = fileName1 then "file1" else "??" diff --git a/tests/service/FscTests.fs b/tests/service/FscTests.fs index 82914dbdba..553f5e468b 100644 --- a/tests/service/FscTests.fs +++ b/tests/service/FscTests.fs @@ -48,7 +48,7 @@ type PEVerifier () = Some ("pedump", "--verify all") else let peverifyPath configuration = - Path.Combine(__SOURCE_DIRECTORY__, "..", "fsharpqa", "testenv", "src", "PEVerify", "bin", configuration, "net46", "PEVerify.exe") + Path.Combine(__SOURCE_DIRECTORY__, "..", "..", "artifacts", "bin", "PEVerify", configuration, "net46", "PEVerify.exe") let peverify = if File.Exists(peverifyPath "Debug") then peverifyPath "Debug" else peverifyPath "Release" diff --git a/tests/service/InteractiveCheckerTests.fs b/tests/service/InteractiveCheckerTests.fs index fba9adcb63..136505b6dd 100644 --- a/tests/service/InteractiveCheckerTests.fs +++ b/tests/service/InteractiveCheckerTests.fs @@ -54,11 +54,7 @@ let internal identsAndRanges (input: Ast.ParsedInput) = | Ast.ParsedInput.SigFile _ -> [] let internal parseAndExtractRanges code = - let file = "Test" - let result = parseSourceCode (file, code) - match result with - | Some tree -> tree |> identsAndRanges - | None -> failwith "fail to parse..." + parseSource code |> identsAndRanges let input = """ diff --git a/tests/service/ProjectAnalysisTests.fs b/tests/service/ProjectAnalysisTests.fs index 60c936fbf2..5ea55a4050 100644 --- a/tests/service/ProjectAnalysisTests.fs +++ b/tests/service/ProjectAnalysisTests.fs @@ -3811,6 +3811,10 @@ let ``Test Project26 parameter symbols`` () = let objSymbol = wholeProjectResults.GetAllUsesOfAllSymbols() |> Async.RunSynchronously |> Array.find (fun su -> su.Symbol.DisplayName = "Class") let objEntity = objSymbol.Symbol :?> FSharpEntity + let rec isByRef (ty: FSharpType) = + if ty.IsAbbreviation then isByRef ty.AbbreviatedType + else ty.IsNamedType && ty.NamedEntity.IsByRef + // check we can get the CurriedParameterGroups let objMethodsCurriedParameterGroups = [ for x in objEntity.MembersFunctionsAndValues do @@ -3823,14 +3827,14 @@ let ``Test Project26 parameter symbols`` () = if p.IsOptionalArg then yield "optional" } |> String.concat "," - yield x.CompiledName, p.Name, p.Type.ToString(), attributeNames ] + yield x.CompiledName, p.Name, p.Type.ToString(), isByRef p.Type, attributeNames ] objMethodsCurriedParameterGroups |> shouldEqual - [("M1", Some "arg1", "type 'c", ""); - ("M1", Some "arg2", "type 'd Microsoft.FSharp.Core.option", "optional"); - ("M2", Some "arg1", "type 'a", "params"); - ("M2", Some "arg2", "type 'b", "optional"); - ("M3", Some "arg", "type Microsoft.FSharp.Core.byref", "out")] + [("M1", Some "arg1", "type 'c", false, ""); + ("M1", Some "arg2", "type 'd Microsoft.FSharp.Core.option", false, "optional"); + ("M2", Some "arg1", "type 'a", false, "params"); + ("M2", Some "arg2", "type 'b", false, "optional"); + ("M3", Some "arg", "type Microsoft.FSharp.Core.byref", true, "out")] // check we can get the ReturnParameter let objMethodsReturnParameter = @@ -5044,6 +5048,101 @@ let ``Test Project40 all symbols`` () = ("IsItAnAMethod", ((13, 25), (13, 40)), ["member"; "funky"]); ("g", ((13, 4), (13, 5)), ["val"]); ("M", ((2, 7), (2, 8)), ["module"])] +//-------------------------------------------- + +module internal Project41 = + open System.IO + + let fileName1 = Path.ChangeExtension(Path.GetTempFileName(), ".fs") + // We need to us a stable name to keep the hashes stable + let base2 = Path.Combine(Path.GetDirectoryName(Path.GetTempFileName()), "stabletmp.tmp") + let dllName = Path.ChangeExtension(base2, ".dll") + let projFileName = Path.ChangeExtension(base2, ".fsproj") + let fileSource1 = """ +module M + + let data1 = {| X = 1 |} + + // Types can be written with the same syntax + let data2 : {| X : int |} = data1 + + type D = {| X : int |} + + // Access is as expected + let f1 (v : {| X : int |}) = v.X + + // Access is as expected + let f2 (v : D) = v.X + + // Access can be nested + let f3 (v : {| X: {| X : int; Y : string |} |}) = v.X.X + + """ + File.WriteAllText(fileName1, fileSource1) + let fileNames = [fileName1] + let args = mkProjectCommandLineArgs (dllName, fileNames) + let options = checker.GetProjectOptionsFromCommandLineArgs (projFileName, args) + let cleanFileName a = if a = fileName1 then "file1" else "??" + +[] +let ``Test project41 all symbols`` () = + + let wholeProjectResults = checker.ParseAndCheckProject(Project41.options) |> Async.RunSynchronously + let allSymbolUses = wholeProjectResults.GetAllUsesOfAllSymbols() |> Async.RunSynchronously + let allSymbolUsesInfo = + [ for s in allSymbolUses do + let pos = + match s.Symbol.DeclarationLocation with + | Some r when r.FileName = Project41.fileName1 -> r.StartLine, r.StartColumn + | _ -> (0,0) + yield (s.Symbol.DisplayName, tups s.RangeAlternate, attribsOfSymbol s.Symbol, pos) ] + allSymbolUsesInfo |> shouldEqual + [("X", ((4, 19), (4, 20)), + ["field"; "anon(0, [//<>f__AnonymousType1416859829`1']X)"], (4, 19)); + ("data1", ((4, 8), (4, 13)), ["val"], (4, 8)); + ("int", ((7, 23), (7, 26)), ["abbrev"], (0, 0)); + ("X", ((7, 19), (7, 20)), + ["field"; "anon(0, [//<>f__AnonymousType1416859829`1']X)"], (7, 19)); + ("data1", ((7, 32), (7, 37)), ["val"], (4, 8)); + ("data2", ((7, 8), (7, 13)), ["val"], (7, 8)); + ("int", ((9, 20), (9, 23)), ["abbrev"], (0, 0)); + ("X", ((9, 16), (9, 17)), + ["field"; "anon(0, [//<>f__AnonymousType1416859829`1']X)"], (9, 16)); + ("int", ((9, 20), (9, 23)), ["abbrev"], (0, 0)); + ("X", ((9, 16), (9, 17)), + ["field"; "anon(0, [//<>f__AnonymousType1416859829`1']X)"], (9, 16)); + ("D", ((9, 9), (9, 10)), ["abbrev"], (9, 9)); + ("int", ((12, 23), (12, 26)), ["abbrev"], (0, 0)); + ("X", ((12, 19), (12, 20)), + ["field"; "anon(0, [//<>f__AnonymousType1416859829`1']X)"], (12, 19)); + ("v", ((12, 12), (12, 13)), [], (12, 12)); + ("v", ((12, 33), (12, 34)), [], (12, 12)); + ("X", ((12, 33), (12, 36)), + ["field"; "anon(0, [//<>f__AnonymousType1416859829`1']X)"], (12, 19)); + ("f1", ((12, 8), (12, 10)), ["val"], (12, 8)); + ("D", ((15, 16), (15, 17)), ["abbrev"], (9, 9)); + ("v", ((15, 12), (15, 13)), [], (15, 12)); + ("v", ((15, 21), (15, 22)), [], (15, 12)); + ("X", ((15, 21), (15, 24)), + ["field"; "anon(0, [//<>f__AnonymousType1416859829`1']X)"], (9, 16)); + ("f2", ((15, 8), (15, 10)), ["val"], (15, 8)); + ("int", ((18, 29), (18, 32)), ["abbrev"], (0, 0)); + ("string", ((18, 38), (18, 44)), ["abbrev"], (0, 0)); + ("X", ((18, 25), (18, 26)), + ["field"; "anon(0, [//<>f__AnonymousType4026451324`2']X,Y)"], (18, 25)); + ("Y", ((18, 34), (18, 35)), + ["field"; "anon(1, [//<>f__AnonymousType4026451324`2']X,Y)"], (18, 34)); + ("X", ((18, 19), (18, 20)), + ["field"; "anon(0, [//<>f__AnonymousType1416859829`1']X)"], (18, 19)); + ("v", ((18, 12), (18, 13)), [], (18, 12)); + ("v", ((18, 54), (18, 55)), [], (18, 12)); + ("X", ((18, 56), (18, 57)), + ["field"; "anon(0, [//<>f__AnonymousType1416859829`1']X)"], (18, 19)); + ("X", ((18, 54), (18, 59)), + ["field"; "anon(0, [//<>f__AnonymousType4026451324`2']X,Y)"], (18, 25)); + ("f3", ((18, 8), (18, 10)), ["val"], (18, 8)); + ("M", ((2, 7), (2, 8)), ["module"], (2, 7))] + module internal ProjectBig = open System.IO diff --git a/tests/service/ServiceUntypedParseTests.fs b/tests/service/ServiceUntypedParseTests.fs index d47acf69de..ccda4f5bac 100644 --- a/tests/service/ServiceUntypedParseTests.fs +++ b/tests/service/ServiceUntypedParseTests.fs @@ -40,14 +40,12 @@ let private (=>) (source: string) (expected: CompletionContext option) = match markerPos with | None -> failwithf "Marker '%s' was not found in the source code" Marker | Some markerPos -> - match parseSourceCode("C:\\test.fs", source) with - | None -> failwith "No parse tree" - | Some parseTree -> - let actual = UntypedParseImpl.TryGetCompletionContext(markerPos, parseTree, lines.[Line.toZ markerPos.Line]) - try Assert.AreEqual(expected, actual) - with e -> - printfn "ParseTree: %A" parseTree - reraise() + let parseTree = parseSource source + let actual = UntypedParseImpl.TryGetCompletionContext(markerPos, parseTree, lines.[Line.toZ markerPos.Line]) + try Assert.AreEqual(expected, actual) + with e -> + printfn "ParseTree: %A" parseTree + reraise() module AttributeCompletion = [] diff --git a/tests/service/StructureTests.fs b/tests/service/StructureTests.fs index f24948890f..c98027c4ca 100644 --- a/tests/service/StructureTests.fs +++ b/tests/service/StructureTests.fs @@ -40,27 +40,23 @@ let (=>) (source: string) (expectedRanges: (Range * Range) list) = let getRange (r: range) = (r.StartLine, r.StartColumn, r.EndLine, r.EndColumn) - let ast = parseSourceCode(fileName, source) - + let tree = parseSource source try - match ast with - | Some tree -> - let actual = - Structure.getOutliningRanges lines tree - |> Seq.filter (fun sr -> sr.Range.StartLine <> sr.Range.EndLine) - |> Seq.map (fun sr -> getRange sr.Range, getRange sr.CollapseRange) - |> Seq.sort - |> List.ofSeq - let expected = List.sort expectedRanges - if actual <> expected then - failwithf "Expected %s, but was %s" (formatList expected) (formatList actual) - | None -> failwithf "Expected there to be a parse tree for source:\n%s" source + let actual = + Structure.getOutliningRanges lines tree + |> Seq.filter (fun sr -> sr.Range.StartLine <> sr.Range.EndLine) + |> Seq.map (fun sr -> getRange sr.Range, getRange sr.CollapseRange) + |> Seq.sort + |> List.ofSeq + let expected = List.sort expectedRanges + if actual <> expected then + failwithf "Expected %s, but was %s" (formatList expected) (formatList actual) with _ -> - printfn "AST:\n%+A" ast + printfn "AST:\n%+A" tree reraise() [] -let ``empty file``() = "" => [ (1, 0, 2, 0), (1, 0, 2, 0) ] +let ``empty file``() = "" => [] [] let ``nested module``() = @@ -68,8 +64,7 @@ let ``nested module``() = module MyModule = () """ - => [ (1, 0, 4, 0), (1, 0, 4, 0) - (2, 0, 3, 6), (2, 15, 3, 6) ] + => [ (2, 0, 3, 6), (2, 15, 3, 6) ] [] let ``module with multiline function``() = @@ -78,8 +73,7 @@ module MyModule = let foo() = foo() """ - => [ (1, 0, 5, 0), (1, 0, 5, 0) - (2, 0, 4, 13), (2, 15, 4, 13) + => [ (2, 0, 4, 13), (2, 15, 4, 13) (3, 4, 4, 13), (3, 13, 4, 13) (3, 8, 4, 13), (3, 13, 4, 13) ] @@ -91,8 +85,7 @@ type Color = | Green | Blue """ - => [ (1, 0, 6, 0), (1, 0, 6, 0) - (2, 5, 5, 10), (2, 11, 5, 10) + => [ (2, 5, 5, 10), (2, 11, 5, 10) (3, 4, 5, 10), (3, 4, 5, 10) ] [] @@ -107,8 +100,7 @@ type Color = member __.Dispose() = (docEventListener :> IDisposable).Dispose() """ - => [ (1, 0, 10, 0), (1, 0, 10, 0) - (2, 5, 9, 55), (2, 11, 9, 55) + => [ (2, 5, 9, 55), (2, 11, 9, 55) (3, 4, 5, 10), (3, 4, 5, 10) (7, 4, 9, 55), (7, 25, 9, 55) (8, 15, 9, 55), (8, 27, 9, 55) @@ -128,8 +120,7 @@ type Color = (docEventListener :> IDisposable).Dispose() """ => - [ (1, 0, 11, 0), (1, 0, 11, 0) - (2, 5, 10, 55), (2, 11, 10, 55) + [ (2, 5, 10, 55), (2, 11, 10, 55) (3, 4, 4, 14), (3, 4, 4, 14) (3, 6, 4, 13), (3, 6, 4, 13) (8, 4, 10, 55), (8, 25, 10, 55) @@ -147,8 +138,7 @@ type Color() = // 2 foo() () // 8 """ - => [ (1, 0, 9, 0), (1, 0, 9, 0) - (2, 5, 8, 10), (2, 11, 8, 10) + => [ (2, 5, 8, 10), (2, 11, 8, 10) (3, 8, 4, 10), (3, 13, 4, 10) (6, 4, 8, 10), (6, 6, 8, 10) ] @@ -182,8 +172,7 @@ module MyModule = // 2 member __.Dispose() = (docEventListener :> IDisposable).Dispose() """ - => [ (1, 0, 28, 0), (1, 0, 28, 0) - (2, 0, 27, 63), (2, 15, 27, 63) + => [ (2, 0, 27, 63), (2, 15, 27, 63) (4, 4, 5, 10), (4, 13, 5, 10) (4, 8, 5, 10), (4, 13, 5, 10) (7, 9, 15, 59), (7, 15, 15, 59) @@ -228,8 +217,7 @@ open H open G open H """ - => [ (1, 0, 26, 6), (1, 0, 26, 6) - (2, 5, 3, 6), (2, 5, 3, 6) + => [ (2, 5, 3, 6), (2, 5, 3, 6) (5, 0, 19, 17), (5, 8, 19, 17) (8, 9, 9, 10), (8, 9, 9, 10) (11, 4, 14, 17), (11, 12, 14, 17) @@ -263,8 +251,7 @@ let x = 1 "c" #r "d" """ - => [ (1, 0, 23, 6), (1, 0, 23, 6) - (2, 3, 8, 6), (2, 3, 8, 6) + => [ (2, 3, 8, 6), (2, 3, 8, 6) (11, 3, 23, 6), (11, 3, 23, 6) ] [] @@ -277,8 +264,7 @@ let f x = // 2 () // 6 x // 7 """ - => [ (1, 0, 8, 0), (1, 0, 8, 0) - (2, 0, 7, 5), (2, 7, 7, 5) + => [ (2, 0, 7, 5), (2, 7, 7, 5) (2, 4, 7, 5), (2, 7, 7, 5) (3, 8, 6, 10), (3, 11, 6, 10) (4, 12, 5, 14), (4, 13, 5, 14) ] @@ -296,11 +282,31 @@ match None with // 2 let x = () // 9 () // 10 """ - => [ (1, 0, 11, 0), (1, 0, 11, 0) - (2, 0, 10, 10), (2, 15, 10, 10) + => [ (2, 0, 10, 10), (2, 15, 10, 10) (6, 4, 10, 10), (5, 6, 10, 10) (6, 4, 10, 10), (6, 19, 10, 10) (9, 8, 10, 10), (8, 10, 10, 10) ] + +[] +let ``matchbang``() = + """ +async { // 2 + match! async { return None } with // 3 + | Some _ -> // 4 + () // 5 + | None -> // 6 + match None with // 7 + | Some _ -> () // 8 + | None -> // 9 + let x = () // 10 + () // 11 +} // 12 +""" + => [ (2, 0, 12, 1), (2, 7, 12, 0) + (3, 4, 11, 14), (3, 37, 11, 14) + (7, 8, 11, 14), (6, 10, 11, 14) + (7, 8, 11, 14), (7, 23, 11, 14) + (10, 12, 11, 14), (9, 14, 11, 14) ] [] let ``computation expressions``() = @@ -313,8 +319,7 @@ seq { // 2 yield () } // 7 } // 8 """ - => [ (1, 0, 8, 1), (1, 0, 8, 1) - (2, 0, 8, 1), (2, 5, 8, 0) + => [ (2, 0, 8, 1), (2, 5, 8, 0) (4, 8, 5, 10), (4, 11, 5, 10) (6, 4, 7, 18), (6, 4, 7, 18) (6, 11, 7, 18), (6, 16, 7, 17) ] @@ -326,8 +331,7 @@ let _ = [ 1; 2 3 ] """ - => [ (1, 0, 5, 0), (1, 0, 5, 0) - (2, 0, 4, 9), (2, 5, 4, 9) + => [ (2, 0, 4, 9), (2, 5, 4, 9) (2, 4, 4, 9), (2, 5, 4, 9) (3, 4, 4, 9), (3, 5, 4, 8) ] @@ -338,8 +342,7 @@ let _ = { new System.IDisposable with member __.Dispose() = () } """ - => [ (1, 0, 5, 0), (1, 0, 5, 0) - (2, 0, 4, 34), (2, 5, 4, 34) + => [ (2, 0, 4, 34), (2, 5, 4, 34) (2, 4, 4, 34), (2, 5, 4, 34) (3, 4, 4, 34), (3, 28, 4, 34) ] @@ -354,8 +357,7 @@ with _ -> // 5 () // 7 () // 8 """ - => [ (1, 0, 9, 0), (1, 0, 9, 0) - (2, 0, 5, 0), (2, 3, 5, 0) + => [ (2, 0, 5, 0), (2, 3, 5, 0) (2, 0, 8, 6), (2, 3, 8, 6) (3, 8, 4, 10), (3, 11, 4, 10) (5, 0, 8, 6), (5, 4, 8, 6) @@ -373,8 +375,7 @@ finally // 5 () // 7 () // 8 """ - => [ (1, 0, 9, 0), (1, 0, 9, 0) - (2, 0, 8, 6), (2, 3, 8, 6) + => [ (2, 0, 8, 6), (2, 3, 8, 6) (3, 8, 4, 10), (3, 11, 4, 10) (5, 0, 8, 6), (5, 7, 8, 6) (6, 8, 7, 10), (6, 11, 7, 10) ] @@ -391,8 +392,7 @@ else () () """ - => [ (1, 0, 10, 0), (1, 0, 10, 0) - (2, 0, 9, 6), (2, 7, 9, 6) + => [ (2, 0, 9, 6), (2, 7, 9, 6) (2, 8, 5, 6), (2, 12, 5, 6) (3, 8, 4, 10), (3, 11, 4, 10) (7, 8, 8, 10), (7, 11, 8, 10) ] @@ -404,8 +404,7 @@ let ``code quotation``() = "code" @> """ - => [ (1, 0, 4, 10), (1, 0, 4, 10) - (2, 0, 4, 10), (2, 2, 4, 8) ] + => [ (2, 0, 4, 10), (2, 2, 4, 8) ] [] let ``raw code quotation``() = @@ -414,8 +413,7 @@ let ``raw code quotation``() = "code" @@> """ - => [ (1, 0, 4, 11), (1, 0, 4, 11) - (2, 0, 4, 11), (2, 3, 4, 8) ] + => [ (2, 0, 4, 11), (2, 3, 4, 8) ] [] let ``match lambda aka function``() = @@ -424,8 +422,7 @@ function | 0 -> () () """ - => [ (1, 0, 5, 0), (1, 0, 5, 0) - (2, 0, 4, 10), (2, 8, 4, 10) + => [ (2, 0, 4, 10), (2, 8, 4, 10) (3, 8, 4, 10), (3, 3, 4, 10) ] [] @@ -436,8 +433,7 @@ let matchwith num = | 0 -> () () """ - => [ (1, 0, 6, 0), (1, 0, 6, 0) - (2, 0, 5, 13), (2, 17, 5, 13) + => [ (2, 0, 5, 13), (2, 17, 5, 13) (2, 4, 5, 13), (2, 17, 5, 13) (3, 4, 5, 13), (3, 18, 5, 13) (4, 11, 5, 13), (4, 7, 5, 13) ] @@ -449,8 +445,7 @@ for x = 100 downto 10 do () () """ - => [ (1, 0, 5, 0), (1, 0, 5, 0) - (2, 0, 4, 6), (2, 0, 4, 6) ] + => [ (2, 0, 4, 6), (2, 0, 4, 6) ] [] let ``for each``() = @@ -459,8 +454,7 @@ for x in 0 .. 100 -> () () """ - => [ (1, 0, 5, 0), (1, 0, 5, 0) - (2, 0, 4, 14), (2, 0, 4, 14) + => [ (2, 0, 4, 14), (2, 0, 4, 14) (2, 18, 4, 14), (2, 18, 4, 14) ] [] @@ -470,8 +464,7 @@ let ``tuple``() = , 322 , 123123 ) """ - => [ (1, 0, 4, 10), (1, 0, 4, 10) - (2, 2, 4, 8), (2, 2, 4, 8) ] + => [ (2, 2, 4, 8), (2, 2, 4, 8) ] [] let ``do!``() = @@ -480,8 +473,7 @@ do! printfn "allo" printfn "allo" """ - => [(1, 0, 5, 0), (1, 0, 5, 0) - (2, 0, 4, 18), (2, 3, 4, 18)] + => [ (2, 0, 4, 18), (2, 3, 4, 18) ] [] let ``cexpr yield yield!``() = @@ -495,11 +487,10 @@ cexpr{ } } """ - => [(1, 0, 9, 5), (1, 0, 9, 5) - (2, 0, 9, 5), (2, 6, 9, 4) - (3, 4, 8, 17), (3, 4, 8, 17) - (4, 8, 8, 17), (4, 14, 8, 16) - (5, 20, 7, 26), (5, 20, 7, 26)] + => [ (2, 0, 9, 5), (2, 6, 9, 4) + (3, 4, 8, 17), (3, 4, 8, 17) + (4, 8, 8, 17), (4, 14, 8, 16) + (5, 20, 7, 26), (5, 20, 7, 26) ] [] let ``XML doc comments``() = @@ -517,8 +508,7 @@ module M = /// Single line comment let f x = x """ - => [ (1, 0, 14, 0), (1, 0, 14, 0) - (2, 0, 3, 10), (2, 0, 3, 10) + => [ (2, 0, 3, 10), (2, 0, 3, 10) (4, 0, 13, 15), (4, 8, 13, 15) (5, 4, 6, 14), (5, 4, 6, 14) (7, 9, 11, 19), (7, 11, 11, 19) @@ -540,8 +530,7 @@ module M = // Single line comment let f x = x """ - => [ (1, 0, 14, 0), (1, 0, 14, 0) - (2, 0, 3, 9), (2, 0, 3, 9) + => [ (2, 0, 3, 9), (2, 0, 3, 9) (4, 0, 13, 15), (4, 8, 13, 15) (5, 4, 6, 13), (5, 4, 6, 13) (7, 9, 11, 19), (7, 11, 11, 19) @@ -560,8 +549,7 @@ let ``XML doc and regular comments in one block``() = /// Line 8 /// Line 9 """ - => [ (1, 0, 11, 0), (1, 0, 11, 0) - (2, 0, 3, 9), (2, 0, 3, 9) + => [ (2, 0, 3, 9), (2, 0, 3, 9) (4, 0, 5, 10), (4, 0, 5, 10) (7, 0, 10, 10), (7, 0, 10, 10) ] @@ -574,9 +562,45 @@ module M = 'c', 1) """ - => [ (1, 0, 7, 0), (1, 0, 7, 0) - (2, 0, 6, 14), (2, 8, 6, 14) + => [ (2, 0, 6, 14), (2, 8, 6, 14) (3, 4, 6, 14), (3, 9, 6, 14) (3, 8, 6, 14), (3, 9, 6, 14) (4, 8, 6, 14), (4, 25, 6, 14) (5, 12, 6, 13), (5, 12, 6, 13) ] + +[] +let ``Top level module`` () = + """ +module TopLevelModule + +module Nested = + let x = 123 +""" + => [ (2, 7, 5, 15), (2, 21, 5, 15) + (4, 0, 5, 15), (4, 13, 5, 15) ] + +[] +let ``Top level namespace`` () = + """ +namespace TopLevelNamespace.Another + +module Nested = + let x = 123 +""" + => [ (4, 0, 5, 15), (4, 13, 5, 15) ] + +[] +let ``Multiple namespaces`` () = + """ +namespace TopLevelNamespace.Another + +module Nested = + let x = 123 + +namespace AnotherTopLevel.Nested + +module NestedModule = + let x = 123 +""" + => [ (4, 0, 5, 15), (4, 13, 5, 15) + (9, 0, 10, 15), (9, 19, 10, 15) ] diff --git a/tests/service/Symbols.fs b/tests/service/Symbols.fs index 8b5749f054..da2a779557 100644 --- a/tests/service/Symbols.fs +++ b/tests/service/Symbols.fs @@ -100,4 +100,27 @@ module Mod2 = mod1val1.XmlDocSig |> shouldEqual "P:Mod1.val1" mod2func2.XmlDocSig |> shouldEqual "M:Mod1.Mod2.func2" - \ No newline at end of file + +module Attributes = + [] + let ``Emit conditional attributes`` () = + let source = """ +open System +open System.Diagnostics + +[] +type FooAttribute() = + inherit Attribute() + +[] +let x = 123 +""" + let fileName, options = mkTestFileAndOptions source [| "--noconditionalerasure" |] + let _, checkResults = parseAndCheckFile fileName source options + + checkResults.GetAllUsesOfAllSymbolsInFile() + |> Async.RunSynchronously + |> Array.tryFind (fun su -> su.Symbol.DisplayName = "x") + |> Option.orElseWith (fun _ -> failwith "Could not get symbol") + |> Option.map (fun su -> su.Symbol :?> FSharpMemberOrFunctionOrValue) + |> Option.iter (fun symbol -> symbol.Attributes.Count |> shouldEqual 1) diff --git a/tests/service/TokenizerTests.fs b/tests/service/TokenizerTests.fs index 4973d398f2..84b95e5175 100644 --- a/tests/service/TokenizerTests.fs +++ b/tests/service/TokenizerTests.fs @@ -20,7 +20,7 @@ open System.IO let sourceTok = FSharpSourceTokenizer([], Some "C:\\test.fsx") -let rec parseLine(line: string, state: int64 ref, tokenizer: FSharpLineTokenizer) = seq { +let rec parseLine(line: string, state: FSharpTokenizerLexState ref, tokenizer: FSharpLineTokenizer) = seq { match tokenizer.ScanToken(!state) with | Some(tok), nstate -> let str = line.Substring(tok.LeftColumn, tok.RightColumn - tok.LeftColumn + 1) @@ -31,7 +31,7 @@ let rec parseLine(line: string, state: int64 ref, tokenizer: FSharpLineTokenizer state := nstate } let tokenizeLines (lines:string[]) = - [ let state = ref 0L + [ let state = ref FSharpTokenizerLexState.Initial for n, line in lines |> Seq.zip [ 0 .. lines.Length-1 ] do let tokenizer = sourceTok.CreateLineTokenizer(line) yield n, parseLine(line, state, tokenizer) |> List.ofSeq ] diff --git a/tests/service/TreeVisitorTests.fs b/tests/service/TreeVisitorTests.fs new file mode 100644 index 0000000000..e81d140011 --- /dev/null +++ b/tests/service/TreeVisitorTests.fs @@ -0,0 +1,22 @@ +module Tests.Service.TreeVisitorTests + +open FSharp.Compiler.Service.Tests.Common +open Microsoft.FSharp.Compiler.Range +open Microsoft.FSharp.Compiler.SourceCodeServices.AstTraversal +open NUnit.Framework + +[] +let ``Visit type test`` () = + let visitor = + { new AstVisitorBase<_>() with + member x.VisitExpr(_, _, defaultTraverse, expr) = defaultTraverse expr + member x.VisitType(_, _) = Some () } + + let source = "123 :? int" + let parseTree = parseSource source + + Traverse(mkPos 1 11, parseTree, visitor) + |> Option.defaultWith (fun _ -> failwith "Did not visit type") + + Traverse(mkPos 1 3, parseTree, visitor) + |> Option.iter (fun _ -> failwith "Should not visit type") diff --git a/tests/service/data/CSharp_Analysis/CSharp_Analysis.csproj b/tests/service/data/CSharp_Analysis/CSharp_Analysis.csproj index 4f88e4a787..4fc4184b23 100644 --- a/tests/service/data/CSharp_Analysis/CSharp_Analysis.csproj +++ b/tests/service/data/CSharp_Analysis/CSharp_Analysis.csproj @@ -1,58 +1,11 @@  - - + + - Debug - AnyCPU - {887630A3-4B1D-40EA-B8B3-2D842E9C40DB} - Library - Properties - CSharp_Analysis - CSharp_Analysis - v4.5 - ..\..\..\..\ - ..\..\..\..\$(Configuration)\net40\bin - 512 - + net45 + 1.0.0.0 + nunit + $(NoWarn);0067;1591 - - true - full - false - DEBUG;TRACE - prompt - 4 - - - pdbonly - true - TRACE - prompt - 4 - - - - - - - - - - - - - - - - - - - - ..\..\..\..\packages\NUnit.3.5.0\lib\net45\nunit.framework.dll - True - True - - - - - \ No newline at end of file + + diff --git a/tests/service/data/CSharp_Analysis/Properties/AssemblyInfo.cs b/tests/service/data/CSharp_Analysis/Properties/AssemblyInfo.cs index 6c36814e76..641372fb96 100644 --- a/tests/service/data/CSharp_Analysis/Properties/AssemblyInfo.cs +++ b/tests/service/data/CSharp_Analysis/Properties/AssemblyInfo.cs @@ -2,35 +2,7 @@ using System.Runtime.CompilerServices; using System.Runtime.InteropServices; -// Allgemeine Informationen über eine Assembly werden über die folgenden -// Attribute gesteuert. Ändern Sie diese Attributwerte, um die Informationen zu ändern, -// die mit einer Assembly verknüpft sind. -[assembly: AssemblyTitle("CSharp_Analysis")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("CSharp_Analysis")] -[assembly: AssemblyCopyright("Copyright © 2015")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - // Durch Festlegen von ComVisible auf "false" werden die Typen in dieser Assembly unsichtbar // für COM-Komponenten. Wenn Sie auf einen Typ in dieser Assembly von // COM zugreifen müssen, legen Sie das ComVisible-Attribut für diesen Typ auf "true" fest. [assembly: ComVisible(false)] - -// Die folgende GUID bestimmt die ID der Typbibliothek, wenn dieses Projekt für COM verfügbar gemacht wird -[assembly: Guid("e1b15939-475d-4134-a76c-20845e07be39")] - -// Versionsinformationen für eine Assembly bestehen aus den folgenden vier Werten: -// -// Hauptversion -// Nebenversion -// Buildnummer -// Revision -// -// Sie können alle Werte angeben oder die standardmäßigen Build- und Revisionsnummern -// übernehmen, indem Sie "*" eingeben: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/tests/service/data/Directory.Build.props b/tests/service/data/Directory.Build.props new file mode 100644 index 0000000000..bb8eac309b --- /dev/null +++ b/tests/service/data/Directory.Build.props @@ -0,0 +1,3 @@ + + + diff --git a/tests/service/data/Directory.Build.targets b/tests/service/data/Directory.Build.targets new file mode 100644 index 0000000000..ccd47cc0a9 --- /dev/null +++ b/tests/service/data/Directory.Build.targets @@ -0,0 +1,3 @@ + + + diff --git a/tests/service/data/FSharp.Data.DesignTime.dll b/tests/service/data/FSharp.Data.DesignTime.dll index fca7289ce5..db2a3317bb 100644 Binary files a/tests/service/data/FSharp.Data.DesignTime.dll and b/tests/service/data/FSharp.Data.DesignTime.dll differ diff --git a/tests/service/data/FSharp.Data.dll b/tests/service/data/FSharp.Data.dll index 39353541ee..95b4d8a914 100644 Binary files a/tests/service/data/FSharp.Data.dll and b/tests/service/data/FSharp.Data.dll differ diff --git a/tests/service/data/TestTP/TestTP.fsproj b/tests/service/data/TestTP/TestTP.fsproj index 2e0ac9aa19..c56ec5f349 100644 --- a/tests/service/data/TestTP/TestTP.fsproj +++ b/tests/service/data/TestTP/TestTP.fsproj @@ -1,76 +1,21 @@  - + + - $(MSBuildProjectDirectory)\..\..\..\..\src - - - - Debug - AnyCPU - 2.0 - ff76bd3c-5e0a-4752-b6c3-044f6e15719b - Library - TestTP - TestTP - v4.5 - true - TestTP - ..\..\..\..\$(Configuration)\net40\bin - - - - true - full - false - false - DEBUG;TRACE - 3 - AnyCPU - bin\Debug\TestTP.xml - true - - - pdbonly - true - true - TRACE - 3 - AnyCPU - bin\Release\TestTP.xml - true + net45 + true + nunit + + - - - ..\..\..\..\packages\Microsoft.Portable.FSharp.Core.10.1.0\lib\profiles\net40\FSharp.Core.dll - false - - - - - - - - CSharp_Analysis - {887630a3-4b1d-40ea-b8b3-2d842e9c40db} - True - + + - - - - - ..\..\..\..\packages\NUnit\lib\nunit.framework.dll - True - True - - - - - + diff --git a/verify-translations.cmd b/verify-translations.cmd index 6717de0f77..2580890c6f 100644 --- a/verify-translations.cmd +++ b/verify-translations.cmd @@ -1,3 +1,3 @@ @echo off -%~dp0release\net40\bin\fsi.exe %~dp0src\scripts\VerifyAllTranslations.fsx -- %~dp0 +%~dp0artifacts\bin\fsi\Release\net46\fsi.exe %~dp0src\scripts\VerifyAllTranslations.fsx -- %~dp0