提交 ff7b1e46 编写于 作者: D Don Syme

Merge commit 'd7f2a28b' into feature/ext

......@@ -8,9 +8,9 @@
</Dependency>
</ProductDependencies>
<ToolsetDependencies>
<Dependency Name="Microsoft.DotNet.Arcade.Sdk" Version="7.0.0-beta.22214.3">
<Dependency Name="Microsoft.DotNet.Arcade.Sdk" Version="7.0.0-beta.22215.2">
<Uri>https://github.com/dotnet/arcade</Uri>
<Sha>5ef2983363df5e0d85181b2948e2a5b0c16aa41a</Sha>
<Sha>4000024394df3049886c50e54ad0a2b903221ef0</Sha>
<SourceBuild RepoName="arcade" ManagedOnly="true" />
</Dependency>
</ToolsetDependencies>
......
......@@ -17,7 +17,7 @@
"perl": "5.32.1.1"
},
"msbuild-sdks": {
"Microsoft.DotNet.Arcade.Sdk": "7.0.0-beta.22214.3",
"Microsoft.DotNet.Arcade.Sdk": "7.0.0-beta.22215.2",
"Microsoft.DotNet.Helix.Sdk": "2.0.0-beta.19069.2"
}
}
......@@ -9498,19 +9498,23 @@ and TcMethodApplication
let MakeUnnamedCallerArgInfo x = (x, GetNewInferenceTypeForMethodArg cenv env tpenv x, x.Range)
let singleMethodCurriedArgs =
match candidates with
| [calledMeth] when List.forall isNil namedCurriedCallerArgs ->
let curriedCalledArgs = calledMeth.GetParamAttribs(cenv.amap, mItem)
match curriedCalledArgs with
| [arg :: _] when isSimpleFormalArg arg -> Some(curriedCalledArgs)
| _ -> None
| _ -> None
// "single named item" rule. This is where we have a single accessible method
// member x.M(arg1)
// being used with
// x.M (x, y)
// Without this rule this requires
// x.M ((x, y))
match candidates with
| [calledMeth]
when (namedCurriedCallerArgs |> List.forall isNil &&
let curriedCalledArgs = calledMeth.GetParamAttribs(cenv.amap, mItem)
curriedCalledArgs.Length = 1 &&
curriedCalledArgs.Head.Length = 1 &&
curriedCalledArgs.Head.Head |> isSimpleFormalArg) ->
match singleMethodCurriedArgs, unnamedCurriedCallerArgs with
| Some [[_]], _ ->
let unnamedCurriedCallerArgs = curriedCallerArgs |> List.map (MakeUnnamedCallerArgInfo >> List.singleton)
let namedCurriedCallerArgs = namedCurriedCallerArgs |> List.map (fun _ -> [])
(Some (unnamedCurriedCallerArgs, namedCurriedCallerArgs), None, exprTy)
......@@ -9522,15 +9526,7 @@ and TcMethodApplication
// We typecheck this as if it has been written "(fun (v1, v2) -> x.M(v1, v2)) p"
// Without this rule this requires
// x.M (fst p, snd p)
| [calledMeth]
when (namedCurriedCallerArgs |> List.forall isNil &&
unnamedCurriedCallerArgs.Length = 1 &&
unnamedCurriedCallerArgs.Head.Length = 1 &&
let curriedCalledArgs = calledMeth.GetParamAttribs(cenv.amap, mItem)
curriedCalledArgs.Length = 1 &&
curriedCalledArgs.Head.Length > 1 &&
curriedCalledArgs.Head |> List.forall isSimpleFormalArg) ->
| Some [_ :: args], [[_]] when List.forall isSimpleFormalArg args ->
// The call lambda has function type
let exprTy = mkFunTy g (NewInferenceType g) exprTy.Commit
......@@ -9550,9 +9546,9 @@ and TcMethodApplication
(Some (unnamedCurriedCallerArgs, namedCurriedCallerArgs), None, exprTy)
let CalledMethHasSingleArgumentGroupOfThisLength n (calledMeth: MethInfo) =
let curriedMethodArgAttribs = calledMeth.GetParamAttribs(cenv.amap, mItem)
curriedMethodArgAttribs.Length = 1 &&
curriedMethodArgAttribs.Head.Length = n
match calledMeth.NumArgs with
| [argAttribs] -> argAttribs = n
| _ -> false
let GenerateMatchingSimpleArgumentTypes (calledMeth: MethInfo) =
let curriedMethodArgAttribs = calledMeth.GetParamAttribs(cenv.amap, mItem)
......
......@@ -720,7 +720,7 @@ type TcConfigBuilder =
use unwindBuildPhase = PushThreadBuildPhaseUntilUnwind BuildPhase.Parameter
if sourceFiles = [] then errorR(Error(FSComp.SR.buildNoInputsSpecified(), rangeCmdArgs))
let ext() = match tcConfigB.target with CompilerTarget.Dll -> ".dll" | CompilerTarget.Module -> ".netmodule" | CompilerTarget.ConsoleExe | CompilerTarget.WinExe -> ".exe"
let implFiles = sourceFiles |> List.filter (fun lower -> List.exists (FileSystemUtils.checkSuffix (String.lowercase lower)) FSharpImplFileSuffixes)
let implFiles = sourceFiles |> List.filter (fun fileName -> List.exists (FileSystemUtils.checkSuffix fileName) FSharpImplFileSuffixes)
let outfile =
match tcConfigB.outputFile, List.rev implFiles with
| None, [] -> "out" + ext()
......@@ -1168,8 +1168,7 @@ type TcConfig private (data: TcConfigBuilder, validate: bool) =
member tcConfig.ComputeLightSyntaxInitialStatus filename =
use unwindBuildPhase = PushThreadBuildPhaseUntilUnwind BuildPhase.Parameter
let lower = String.lowercase filename
let lightOnByDefault = List.exists (FileSystemUtils.checkSuffix lower) FSharpLightSyntaxFileSuffixes
let lightOnByDefault = List.exists (FileSystemUtils.checkSuffix filename) FSharpLightSyntaxFileSuffixes
if lightOnByDefault then (tcConfig.light <> Some false) else (tcConfig.light = Some true )
member tcConfig.GetAvailableLoadedSources() =
......
......@@ -43,8 +43,7 @@ let CanonicalizeFilename filename =
String.capitalize (try FileSystemUtils.chopExtension basic with _ -> basic)
let IsScript filename =
let lower = String.lowercase filename
FSharpScriptFileSuffixes |> List.exists (FileSystemUtils.checkSuffix lower)
FSharpScriptFileSuffixes |> List.exists (FileSystemUtils.checkSuffix filename)
// Give a unique name to the different kinds of inputs. Used to correlate signature and implementation files
// QualFileNameOfModuleName - files with a single module declaration or an anonymous module
......@@ -115,8 +114,7 @@ let PostParseModuleImpl (_i, defaultNamespace, isLastCompiland, filename, impl)
| ParsedImplFileFragment.AnonModule (defs, m)->
let isLast, isExe = isLastCompiland
let lower = String.lowercase filename
if not (isLast && isExe) && not (doNotRequireNamespaceOrModuleSuffixes |> List.exists (FileSystemUtils.checkSuffix lower)) then
if not (isLast && isExe) && not (doNotRequireNamespaceOrModuleSuffixes |> List.exists (FileSystemUtils.checkSuffix filename)) then
match defs with
| SynModuleDecl.NestedModule _ :: _ -> errorR(Error(FSComp.SR.noEqualSignAfterModule(), trimRangeToLine m))
| _ -> errorR(Error(FSComp.SR.buildMultiFileRequiresNamespaceOrModule(), trimRangeToLine m))
......@@ -145,8 +143,7 @@ let PostParseModuleSpec (_i, defaultNamespace, isLastCompiland, filename, intf)
| ParsedSigFileFragment.AnonModule (defs, m) ->
let isLast, isExe = isLastCompiland
let lower = String.lowercase filename
if not (isLast && isExe) && not (doNotRequireNamespaceOrModuleSuffixes |> List.exists (FileSystemUtils.checkSuffix lower)) then
if not (isLast && isExe) && not (doNotRequireNamespaceOrModuleSuffixes |> List.exists (FileSystemUtils.checkSuffix filename)) then
match defs with
| SynModuleSigDecl.NestedModule _ :: _ -> errorR(Error(FSComp.SR.noEqualSignAfterModule(), m))
| _ -> errorR(Error(FSComp.SR.buildMultiFileRequiresNamespaceOrModule(), m))
......@@ -273,7 +270,6 @@ let ParseInput (lexer, diagnosticOptions:FSharpDiagnosticOptions, errorLogger: E
// # 1000 "Line01.fs"
// then it also asserts. But these are edge cases that can be fixed later, e.g. in bug 4651.
//System.Diagnostics.Debug.Assert(System.IO.Path.IsPathRooted filename, sprintf "should be absolute: '%s'" filename)
let lower = String.lowercase filename
// Delay sending errors and warnings until after the file is parsed. This gives us a chance to scrape the
// #nowarn declarations for the file
......@@ -284,18 +280,18 @@ let ParseInput (lexer, diagnosticOptions:FSharpDiagnosticOptions, errorLogger: E
let mutable scopedPragmas = []
try
let input =
if mlCompatSuffixes |> List.exists (FileSystemUtils.checkSuffix lower) then
if mlCompatSuffixes |> List.exists (FileSystemUtils.checkSuffix filename) then
if lexbuf.SupportsFeature LanguageFeature.MLCompatRevisions then
errorR(Error(FSComp.SR.buildInvalidSourceFileExtensionML filename, rangeStartup))
else
mlCompatWarning (FSComp.SR.buildCompilingExtensionIsForML()) rangeStartup
// Call the appropriate parser - for signature files or implementation files
if FSharpImplFileSuffixes |> List.exists (FileSystemUtils.checkSuffix lower) then
if FSharpImplFileSuffixes |> List.exists (FileSystemUtils.checkSuffix filename) then
let impl = Parser.implementationFile lexer lexbuf
let tripleSlashComments = LexbufLocalXmlDocStore.ReportInvalidXmlDocPositions(lexbuf)
PostParseModuleImpls (defaultNamespace, filename, isLastCompiland, impl, lexbuf, tripleSlashComments)
elif FSharpSigFileSuffixes |> List.exists (FileSystemUtils.checkSuffix lower) then
elif FSharpSigFileSuffixes |> List.exists (FileSystemUtils.checkSuffix filename) then
let intfs = Parser.signatureFile lexer lexbuf
let tripleSlashComments = LexbufLocalXmlDocStore.ReportInvalidXmlDocPositions(lexbuf)
PostParseModuleSpecs (defaultNamespace, filename, isLastCompiland, intfs, lexbuf, tripleSlashComments)
......@@ -350,8 +346,7 @@ let ReportParsingStatistics res =
printfn "parsing yielded %d definitions" (List.collect flattenModImpl impls).Length
let EmptyParsedInput(filename, isLastCompiland) =
let lower = String.lowercase filename
if FSharpSigFileSuffixes |> List.exists (FileSystemUtils.checkSuffix lower) then
if FSharpSigFileSuffixes |> List.exists (FileSystemUtils.checkSuffix filename) then
ParsedInput.SigFile(
ParsedSigFileInput(
filename,
......@@ -432,9 +427,7 @@ let ParseOneInputLexbuf (tcConfig: TcConfig, lexResourceManager, lexbuf, filenam
let ValidSuffixes = FSharpSigFileSuffixes@FSharpImplFileSuffixes
let checkInputFile (tcConfig: TcConfig) filename =
let lower = String.lowercase filename
if List.exists (FileSystemUtils.checkSuffix lower) ValidSuffixes then
if List.exists (FileSystemUtils.checkSuffix filename) ValidSuffixes then
if not(FileSystem.FileExistsShim filename) then
error(Error(FSComp.SR.buildCouldNotFindSourceFile filename, rangeStartup))
else
......
......@@ -80,7 +80,7 @@ module XmlDocWriter =
doModuleSig None generatedCcu.Contents
let WriteXmlDocFile (g, assemblyName, generatedCcu: CcuThunk, xmlfile) =
if not (FileSystemUtils.hasSuffixCaseInsensitive "xml" xmlfile ) then
if not (FileSystemUtils.checkSuffix xmlfile "xml" ) then
error(Error(FSComp.SR.docfileNoXmlSuffix(), Range.rangeStartup))
let mutable members = []
......
......@@ -77,6 +77,9 @@ module internal PervasiveAutoOpens =
member inline x.EndsWithOrdinal value =
x.EndsWith(value, StringComparison.Ordinal)
member inline x.EndsWithOrdinalIgnoreCase value =
x.EndsWith(value, StringComparison.OrdinalIgnoreCase)
/// Get an initialization hole
let getHole (r: _ ref) = match r.Value with None -> failwith "getHole" | Some x -> x
......
......@@ -61,6 +61,8 @@ module internal PervasiveAutoOpens =
member inline EndsWithOrdinal: value:string -> bool
member inline EndsWithOrdinalIgnoreCase: value:string -> bool
type Async with
/// Runs the computation synchronously, always starting on the current thread.
static member RunImmediate: computation: Async<'T> * ?cancellationToken: CancellationToken -> 'T
......
......@@ -266,8 +266,7 @@ let SetProcessThreadLocals tcConfigB =
let ProcessCommandLineFlags (tcConfigB: TcConfigBuilder, lcidFromCodePage, argv) =
let mutable inputFilesRef = []
let collect name =
let lower = String.lowercase name
if List.exists (FileSystemUtils.checkSuffix lower) [".resx"] then
if List.exists (FileSystemUtils.checkSuffix name) [".resx"] then
error(Error(FSComp.SR.fscResxSourceFileDeprecated name, rangeStartup))
else
inputFilesRef <- name :: inputFilesRef
......
......@@ -1643,8 +1643,7 @@ module internal ParseAndCheckFile =
member _.AnyErrors = errorCount > 0
let getLightSyntaxStatus fileName options =
let lower = String.lowercase fileName
let lightOnByDefault = List.exists (FileSystemUtils.checkSuffix lower) FSharpLightSyntaxFileSuffixes
let lightOnByDefault = List.exists (FileSystemUtils.checkSuffix fileName) FSharpLightSyntaxFileSuffixes
let lightStatus = if lightOnByDefault then (options.LightSyntax <> Some false) else (options.LightSyntax = Some true)
LightSyntaxStatus(lightStatus, true)
......
......@@ -402,8 +402,8 @@ type FSharpParseFileResults(diagnostics: FSharpDiagnostic[], input: ParsedInput,
result.IsSome
member _.IsTypeAnnotationGivenAtPosition pos =
let result =
SyntaxTraversal.Traverse(pos, input, { new SyntaxVisitorBase<_>() with
let walker =
{ new SyntaxVisitorBase<_>() with
member _.VisitExpr(_path, _traverseSynExpr, defaultTraverse, expr) =
match expr with
| SynExpr.Typed (_expr, _typeExpr, range) when Position.posEq range.Start pos ->
......@@ -416,6 +416,7 @@ type FSharpParseFileResults(diagnostics: FSharpDiagnostic[], input: ParsedInput,
| _ ->
let exprFunc pat =
match pat with
// (s: string)
| SynSimplePat.Typed (_pat, _targetExpr, range) when Position.posEq range.Start pos ->
Some range
| _ ->
......@@ -424,10 +425,18 @@ type FSharpParseFileResults(diagnostics: FSharpDiagnostic[], input: ParsedInput,
pats |> List.tryPick exprFunc
override _.VisitPat(_path, defaultTraverse, pat) =
// (s: string)
match pat with
| SynPat.Typed (_pat, _targetType, range) when Position.posEq range.Start pos ->
Some range
| _ -> defaultTraverse pat })
| _ -> defaultTraverse pat
override _.VisitBinding(_path, defaultTraverse, binding) =
// let x : int = 12
match binding with
| SynBinding(headPat = SynPat.Named (range = patRange); returnInfo = Some (SynBindingReturnInfo(typeName = SynType.LongIdent _))) -> Some patRange
| _ -> defaultTraverse binding
}
let result = SyntaxTraversal.Traverse(pos, input, walker)
result.IsSome
member _.IsBindingALambdaAtPosition pos =
......
......@@ -115,8 +115,7 @@ module IncrementalBuildSyntaxTree =
try
IncrementalBuilderEventTesting.MRU.Add(IncrementalBuilderEventTesting.IBEParsed filename)
let lower = String.lowercase filename
let canSkip = sigNameOpt.IsSome && FSharpImplFileSuffixes |> List.exists (FileSystemUtils.checkSuffix lower)
let canSkip = sigNameOpt.IsSome && FSharpImplFileSuffixes |> List.exists (FileSystemUtils.checkSuffix filename)
let input =
if canSkip then
ParsedInput.ImplFile(
......
......@@ -386,7 +386,7 @@ module internal FileSystemUtils =
for c in path do
if chars.Contains c then raise(IllegalFileNameChar(path, c)))
let checkSuffix (x:string) (y:string) = x.EndsWithOrdinal(y)
let checkSuffix (x:string) (y:string) = x.EndsWithOrdinalIgnoreCase(y)
let hasExtensionWithValidate (validate:bool) (s:string) =
if validate then (checkPathForIllegalChars s)
......@@ -416,10 +416,7 @@ module internal FileSystemUtils =
let trimQuotes (s:string) =
s.Trim( [|' '; '\"'|] )
let hasSuffixCaseInsensitive suffix filename = (* case-insensitive *)
checkSuffix (String.lowercase filename) (String.lowercase suffix)
let isDll file = hasSuffixCaseInsensitive ".dll" file
let isDll file = checkSuffix file ".dll"
[<Experimental("This FCS API/Type is experimental and subject to change.")>]
type IAssemblyLoader =
......
......@@ -106,6 +106,7 @@ module internal FileSystemUtils =
/// <c>checkSuffix f s</c> returns True if filename "f" ends in suffix "s",
/// e.g. checkSuffix "abc.fs" ".fs" returns true.
/// Disregards casing, e.g. checkSuffix "abc.Fs" ".fs" returns true.
val checkSuffix: string -> string -> bool
/// <c>chopExtension f</c> removes the extension from the given
......@@ -125,9 +126,6 @@ module internal FileSystemUtils =
/// Trim the quotes and spaces from either end of a string
val trimQuotes: string -> string
/// Checks whether filename ends in suffix, ignoring case.
val hasSuffixCaseInsensitive: string -> string -> bool
/// Checks whether file is dll (ends in .dll)
val isDll: string -> bool
......
......@@ -1506,6 +1506,15 @@ let (x, y: string) = (12, "hello")
Assert.IsFalse(parseFileResults.IsTypeAnnotationGivenAtPosition (mkPos 2 5), "Expected no annotation for argument 'x'")
Assert.IsTrue(parseFileResults.IsTypeAnnotationGivenAtPosition (mkPos 2 8), "Expected annotation for argument 'y'")
[<Test>]
let ``IsTypeAnnotationGivenAtPosition - binding - second value annotated``() =
let source = """
let x: int = 12
"""
let parseFileResults, _ = getParseAndCheckResults source
Assert.IsTrue(parseFileResults.IsTypeAnnotationGivenAtPosition (mkPos 2 5), "Expected annotation for argument 'x'")
module LambdaRecognition =
[<Test>]
let ``IsBindingALambdaAtPosition - recognize a lambda``() =
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册