diff --git a/docs/release-notes/.FSharp.Compiler.Service/10.0.100.md b/docs/release-notes/.FSharp.Compiler.Service/10.0.100.md index 89afb46101b..4bf329bedd2 100644 --- a/docs/release-notes/.FSharp.Compiler.Service/10.0.100.md +++ b/docs/release-notes/.FSharp.Compiler.Service/10.0.100.md @@ -7,6 +7,7 @@ * Diagnostics: add extended data for 'No constructors' error ([PR #18863](https://github.com/dotnet/fsharp/pull/18863)) * FSharpType.Format: support top-level prefix generic types style. ([PR #18897](https://github.com/dotnet/fsharp/pull/18897)) * FCS: allow getting captured types ([PR $18878](https://github.com/dotnet/fsharp/pull/18878)) +* Allow open declarations in expression scope. ([Suggestion](https://github.com/fsharp/fslang-suggestions/issues/96), [PR #18814](https://github.com/dotnet/fsharp/pull/18814)) ### Fixed diff --git a/docs/release-notes/.Language/preview.md b/docs/release-notes/.Language/preview.md index fcec4b8170e..2f82f8744f4 100644 --- a/docs/release-notes/.Language/preview.md +++ b/docs/release-notes/.Language/preview.md @@ -11,6 +11,7 @@ * Allow `let!`, `use!`, `and!` type annotations without requiring parentheses (([PR #18508](https://github.com/dotnet/fsharp/pull/18508) and [PR #18682](https://github.com/dotnet/fsharp/pull/18682))) * Exception names are now validated for illegal characters using the same mechanism as types/modules/namespaces ([Issue #18763](https://github.com/dotnet/fsharp/issues/18763)) * Support tail calls in computation expressions ([PR #18804](https://github.com/dotnet/fsharp/pull/18804)) +* Allow open declarations in expression scope. ([Suggestion](https://github.com/fsharp/fslang-suggestions/issues/96), [PR #18814](https://github.com/dotnet/fsharp/pull/18814)) ### Fixed diff --git a/src/Compiler/Checking/CheckBasics.fs b/src/Compiler/Checking/CheckBasics.fs index 7cbca970cc3..8ef29dd7400 100644 --- a/src/Compiler/Checking/CheckBasics.fs +++ b/src/Compiler/Checking/CheckBasics.fs @@ -379,3 +379,93 @@ type TcFileState = } override _.ToString() = "" + +open FSharp.Compiler.AttributeChecking +open FSharp.Compiler.Syntax.PrettyNaming +open FSharp.Compiler.Text.Range +open FSharp.Compiler.TypedTreeBasics + +let CheckNamespaceModuleOrTypeName (g: TcGlobals) (id: Ident) = + // type names '[]' etc. are used in fslib + if not g.compilingFSharpCore && id.idText.IndexOfAny IllegalCharactersInTypeAndNamespaceNames <> -1 then + errorR(Error(FSComp.SR.tcInvalidNamespaceModuleTypeUnionName(), id.idRange)) + +/// Adjust the TcEnv to account for opening the set of modules or namespaces implied by an `open` declaration +let OpenModuleOrNamespaceRefs tcSink g amap scopem root env mvvs openDeclaration = + let env = + if isNil mvvs then env else + { env with eNameResEnv = AddModuleOrNamespaceRefsContentsToNameEnv g amap env.eAccessRights scopem root env.eNameResEnv mvvs } + CallEnvSink tcSink (scopem, env.NameEnv, env.eAccessRights) + CallOpenDeclarationSink tcSink openDeclaration + env + +//------------------------------------------------------------------------- +// Bind 'open' declarations +//------------------------------------------------------------------------- + +let TcOpenLidAndPermitAutoResolve tcSink (env: TcEnv) amap (longId : Ident list) = + let ad = env.AccessRights + match longId with + | [] -> [] + | id :: rest -> + let m = longId |> List.map (fun id -> id.idRange) |> List.reduce unionRanges + match ResolveLongIdentAsModuleOrNamespace tcSink amap m true OpenQualified env.NameEnv ad id rest true ShouldNotifySink.Yes with + | Result res -> res + | Exception err -> + errorR(err); [] + +let TcOpenModuleOrNamespaceDecl tcSink g amap scopem env (longId, m) = + match TcOpenLidAndPermitAutoResolve tcSink env amap longId with + | [] -> env, [] + | modrefs -> + + // validate opened namespace names + for id in longId do + if id.idText <> MangledGlobalName then + CheckNamespaceModuleOrTypeName g id + + let IsPartiallyQualifiedNamespace (modref: ModuleOrNamespaceRef) = + let (CompPath(_, _, p)) = modref.CompilationPath + // Bug FSharp 1.0 3274: FSI paths don't count when determining this warning + let p = + match p with + | [] -> [] + | (h, _) :: t -> if h.StartsWithOrdinal FsiDynamicModulePrefix then t else p + + // See https://fslang.uservoice.com/forums/245727-f-language/suggestions/6107641-make-microsoft-prefix-optional-when-using-core-f + let isFSharpCoreSpecialCase = + match ccuOfTyconRef modref with + | None -> false + | Some ccu -> + ccuEq ccu g.fslibCcu && + // Check if we're using a reference one string shorter than what we expect. + // + // "p" is the fully qualified path _containing_ the thing we're opening, e.g. "Microsoft.FSharp" when opening "Microsoft.FSharp.Data" + // "longId" is the text being used, e.g. "FSharp.Data" + // Length of thing being opened = p.Length + 1 + // Length of reference = longId.Length + // So the reference is a "shortened" reference if (p.Length + 1) - 1 = longId.Length + (p.Length + 1) - 1 = longId.Length && + fst p[0] = "Microsoft" + + modref.IsNamespace && + p.Length >= longId.Length && + not isFSharpCoreSpecialCase + // Allow "open Foo" for "Microsoft.Foo" from FSharp.Core + + modrefs |> List.iter (fun (_, modref, _) -> + if modref.IsModule && HasFSharpAttribute g g.attrib_RequireQualifiedAccessAttribute modref.Attribs then + errorR(Error(FSComp.SR.tcModuleRequiresQualifiedAccess(fullDisplayTextOfModRef modref), m))) + + // Bug FSharp 1.0 3133: 'open Lexing'. Skip this warning if we successfully resolved to at least a module name + if not (modrefs |> List.exists (fun (_, modref, _) -> modref.IsModule && not (HasFSharpAttribute g g.attrib_RequireQualifiedAccessAttribute modref.Attribs))) then + modrefs |> List.iter (fun (_, modref, _) -> + if IsPartiallyQualifiedNamespace modref then + errorR(Error(FSComp.SR.tcOpenUsedWithPartiallyQualifiedPath(fullDisplayTextOfModRef modref), m))) + + let modrefs = List.map p23 modrefs + modrefs |> List.iter (fun modref -> CheckEntityAttributes g modref m |> CommitOperationResult) + + let openDecl = OpenDeclaration.Create (SynOpenDeclTarget.ModuleOrNamespace (SynLongIdent(longId, [], []), m), modrefs, [], scopem, false) + let env = OpenModuleOrNamespaceRefs tcSink g amap scopem false env modrefs openDecl + env, [openDecl] diff --git a/src/Compiler/Checking/CheckBasics.fsi b/src/Compiler/Checking/CheckBasics.fsi index 179752c394c..8d26dfd18dd 100644 --- a/src/Compiler/Checking/CheckBasics.fsi +++ b/src/Compiler/Checking/CheckBasics.fsi @@ -358,3 +358,12 @@ type TcFileState = -> range * Expr * TType * SynExpr -> Expr * UnscopedTyparEnv) -> TcFileState + +val TcOpenModuleOrNamespaceDecl: + tcSink: TcResultsSink -> + g: TcGlobals -> + amap: Import.ImportMap -> + scopem: range -> + env: TcEnv -> + longId: LongIdent * m: range -> + TcEnv * OpenDeclaration list diff --git a/src/Compiler/Checking/CheckDeclarations.fs b/src/Compiler/Checking/CheckDeclarations.fs index cbf79fbdfb3..184f901c157 100644 --- a/src/Compiler/Checking/CheckDeclarations.fs +++ b/src/Compiler/Checking/CheckDeclarations.fs @@ -294,14 +294,6 @@ let OpenModuleOrNamespaceRefs tcSink g amap scopem root env mvvs openDeclaration CallOpenDeclarationSink tcSink openDeclaration env -/// Adjust the TcEnv to account for opening a type implied by an `open type` declaration -let OpenTypeContent tcSink g amap scopem env (ty: TType) openDeclaration = - let env = - { env with eNameResEnv = AddTypeContentsToNameEnv g amap env.eAccessRights scopem env.eNameResEnv ty } - CallEnvSink tcSink (scopem, env.NameEnv, env.eAccessRights) - CallOpenDeclarationSink tcSink openDeclaration - env - /// Adjust the TcEnv to account for a new root Ccu being available, e.g. a referenced assembly let AddRootModuleOrNamespaceRefs g amap m env modrefs = if isNil modrefs then env else @@ -681,99 +673,9 @@ let TcTyconMemberSpecs cenv env containerInfo declKind tpenv augSpfn = // Bind 'open' declarations //------------------------------------------------------------------------- -let TcOpenLidAndPermitAutoResolve tcSink (env: TcEnv) amap (longId : Ident list) = - let ad = env.AccessRights - match longId with - | [] -> [] - | id :: rest -> - let m = longId |> List.map (fun id -> id.idRange) |> List.reduce unionRanges - match ResolveLongIdentAsModuleOrNamespace tcSink amap m true OpenQualified env.NameEnv ad id rest true ShouldNotifySink.Yes with - | Result res -> res - | Exception err -> - errorR(err); [] - let TcOpenModuleOrNamespaceDecl tcSink g amap scopem env (longId, m) = - match TcOpenLidAndPermitAutoResolve tcSink env amap longId with - | [] -> env, [] - | modrefs -> - - // validate opened namespace names - for id in longId do - if id.idText <> MangledGlobalName then - CheckNamespaceModuleOrTypeName g id - - let IsPartiallyQualifiedNamespace (modref: ModuleOrNamespaceRef) = - let (CompPath(_, _, p)) = modref.CompilationPath - // Bug FSharp 1.0 3274: FSI paths don't count when determining this warning - let p = - match p with - | [] -> [] - | (h, _) :: t -> if h.StartsWithOrdinal FsiDynamicModulePrefix then t else p - - // See https://fslang.uservoice.com/forums/245727-f-language/suggestions/6107641-make-microsoft-prefix-optional-when-using-core-f - let isFSharpCoreSpecialCase = - match ccuOfTyconRef modref with - | None -> false - | Some ccu -> - ccuEq ccu g.fslibCcu && - // Check if we're using a reference one string shorter than what we expect. - // - // "p" is the fully qualified path _containing_ the thing we're opening, e.g. "Microsoft.FSharp" when opening "Microsoft.FSharp.Data" - // "longId" is the text being used, e.g. "FSharp.Data" - // Length of thing being opened = p.Length + 1 - // Length of reference = longId.Length - // So the reference is a "shortened" reference if (p.Length + 1) - 1 = longId.Length - (p.Length + 1) - 1 = longId.Length && - fst p[0] = "Microsoft" - - modref.IsNamespace && - p.Length >= longId.Length && - not isFSharpCoreSpecialCase - // Allow "open Foo" for "Microsoft.Foo" from FSharp.Core - - modrefs |> List.iter (fun (_, modref, _) -> - if modref.IsModule && HasFSharpAttribute g g.attrib_RequireQualifiedAccessAttribute modref.Attribs then - errorR(Error(FSComp.SR.tcModuleRequiresQualifiedAccess(fullDisplayTextOfModRef modref), m))) - - // Bug FSharp 1.0 3133: 'open Lexing'. Skip this warning if we successfully resolved to at least a module name - if not (modrefs |> List.exists (fun (_, modref, _) -> modref.IsModule && not (HasFSharpAttribute g g.attrib_RequireQualifiedAccessAttribute modref.Attribs))) then - modrefs |> List.iter (fun (_, modref, _) -> - if IsPartiallyQualifiedNamespace modref then - errorR(Error(FSComp.SR.tcOpenUsedWithPartiallyQualifiedPath(fullDisplayTextOfModRef modref), m))) - - let modrefs = List.map p23 modrefs - modrefs |> List.iter (fun modref -> CheckEntityAttributes g modref m |> CommitOperationResult) - - let openDecl = OpenDeclaration.Create (SynOpenDeclTarget.ModuleOrNamespace (SynLongIdent(longId, [], []), m), modrefs, [], scopem, false) - let env = OpenModuleOrNamespaceRefs tcSink g amap scopem false env modrefs openDecl - env, [openDecl] - -let TcOpenTypeDecl (cenv: cenv) mOpenDecl scopem env (synType: SynType, m) = - let g = cenv.g - - checkLanguageFeatureError g.langVersion LanguageFeature.OpenTypeDeclaration mOpenDecl - - let ty, _tpenv = TcType cenv NoNewTypars CheckCxs ItemOccurrence.Open WarnOnIWSAM.Yes env emptyUnscopedTyparEnv synType - - if not (isAppTy g ty) then - errorR(Error(FSComp.SR.tcNamedTypeRequired("open type"), m)) - - if isByrefTy g ty then - errorR(Error(FSComp.SR.tcIllegalByrefsInOpenTypeDeclaration(), m)) - - let openDecl = OpenDeclaration.Create (SynOpenDeclTarget.Type (synType, m), [], [ty], scopem, false) - let env = OpenTypeContent cenv.tcSink g cenv.amap scopem env ty openDecl - env, [openDecl] - -let TcOpenDecl (cenv: cenv) mOpenDecl scopem env target = - let g = cenv.g - match target with - | SynOpenDeclTarget.ModuleOrNamespace (longId, m) -> - TcOpenModuleOrNamespaceDecl cenv.tcSink g cenv.amap scopem env (longId.LongIdent, m) - - | SynOpenDeclTarget.Type (synType, m) -> - TcOpenTypeDecl cenv mOpenDecl scopem env (synType, m) - + CheckBasics.TcOpenModuleOrNamespaceDecl tcSink g amap scopem env (longId, m) + let MakeSafeInitField (cenv: cenv) env m isStatic = let id = // Ensure that we have an g.CompilerGlobalState diff --git a/src/Compiler/Checking/Expressions/CheckComputationExpressions.fs b/src/Compiler/Checking/Expressions/CheckComputationExpressions.fs index 1f31414599d..c28de1af7be 100644 --- a/src/Compiler/Checking/Expressions/CheckComputationExpressions.fs +++ b/src/Compiler/Checking/Expressions/CheckComputationExpressions.fs @@ -2324,6 +2324,10 @@ let rec TryTranslateComputationExpression Some(translatedCtxt yieldOrReturnCall) + | SynExpr.Open(target, mOpen, m, body) -> + let body = TranslateComputationExpressionNoQueryOps ceenv body + Some(translatedCtxt (SynExpr.Open(target, mOpen, m, body))) + | _ -> None and ConsumeCustomOpClauses diff --git a/src/Compiler/Checking/Expressions/CheckExpressions.fs b/src/Compiler/Checking/Expressions/CheckExpressions.fs index 6979f20f0e0..ba89477ee67 100644 --- a/src/Compiler/Checking/Expressions/CheckExpressions.fs +++ b/src/Compiler/Checking/Expressions/CheckExpressions.fs @@ -4054,6 +4054,14 @@ type ImplicitlyBoundTyparsAllowed = | NewTyparsOK | NoNewTypars +/// Adjust the TcEnv to account for opening a type implied by an `open type` declaration +let OpenTypeContent tcSink g amap scopem env (ty: TType) openDeclaration = + let env = + { env with eNameResEnv = AddTypeContentsToNameEnv g amap env.eAccessRights scopem env.eNameResEnv ty } + CallEnvSink tcSink (scopem, env.NameEnv, env.eAccessRights) + CallOpenDeclarationSink tcSink openDeclaration + env + //------------------------------------------------------------------------- // Checking types and type constraints //------------------------------------------------------------------------- @@ -6087,6 +6095,11 @@ and TcExprUndelayed (cenv: cenv) (overallTy: OverallTy) env tpenv (synExpr: SynE | SynExpr.IndexRange (range=m) -> error(Error(FSComp.SR.tcInvalidIndexerExpression(), m)) + | SynExpr.Open (target, mOpen, _m, body) -> + checkLanguageFeatureAndRecover g.langVersion LanguageFeature.OpensInExpressionScope mOpen + let env, _openDecls = TcOpenDecl cenv mOpen body.Range env target + TcExprThatCanBeCtorBody cenv overallTy env tpenv body + and TcExprMatch (cenv: cenv) overallTy env tpenv synInputExpr spMatch synClauses = let inputExpr, inputTy, tpenv = let env = { env with eIsControlFlow = false } @@ -9210,6 +9223,7 @@ and TcImplicitOpItemThen (cenv: cenv) overallTy env id sln tpenv mItem delayed = | SynExpr.TraitCall _ | SynExpr.IndexFromEnd _ | SynExpr.IndexRange _ + | SynExpr.Open _ -> false // Propagate the known application structure into function types @@ -12847,6 +12861,32 @@ and TcLetrecBindings overridesOK (cenv: cenv) env tpenv (binds, bindsm, scopem) let envbody = AddLocalVals g cenv.tcSink scopem prelimRecValues env binds, envbody, tpenv +and TcOpenTypeDecl (cenv: cenv) mOpenDecl scopem env (synType: SynType, m) = + let g = cenv.g + + checkLanguageFeatureError g.langVersion LanguageFeature.OpenTypeDeclaration mOpenDecl + + let ty, _tpenv = TcType cenv NoNewTypars CheckCxs ItemOccurrence.Open WarnOnIWSAM.Yes env emptyUnscopedTyparEnv synType + + if not (isAppTy g ty) then + errorR(Error(FSComp.SR.tcNamedTypeRequired("open type"), m)) + + if isByrefTy g ty then + errorR(Error(FSComp.SR.tcIllegalByrefsInOpenTypeDeclaration(), m)) + + let openDecl = OpenDeclaration.Create (SynOpenDeclTarget.Type (synType, m), [], [ty], scopem, false) + let env = OpenTypeContent cenv.tcSink g cenv.amap scopem env ty openDecl + env, [openDecl] + +and TcOpenDecl (cenv: cenv) mOpenDecl scopem env target = + let g = cenv.g + match target with + | SynOpenDeclTarget.ModuleOrNamespace (longId, m) -> + TcOpenModuleOrNamespaceDecl cenv.tcSink g cenv.amap scopem env (longId.LongIdent, m) + + | SynOpenDeclTarget.Type (synType, m) -> + TcOpenTypeDecl cenv mOpenDecl scopem env (synType, m) + //------------------------------------------------------------------------- // Bind specifications of values //------------------------------------------------------------------------- diff --git a/src/Compiler/Checking/Expressions/CheckExpressions.fsi b/src/Compiler/Checking/Expressions/CheckExpressions.fsi index 9e3014896c8..ef05183d9dc 100644 --- a/src/Compiler/Checking/Expressions/CheckExpressions.fsi +++ b/src/Compiler/Checking/Expressions/CheckExpressions.fsi @@ -883,6 +883,14 @@ val TcRuntimeTypeTest: srcTy: TType -> unit +val TcOpenDecl: + cenv: TcFileState -> + mOpenDecl: range -> + scopem: range -> + env: TcEnv -> + target: SynOpenDeclTarget -> + TcEnv * OpenDeclaration list + /// Allow the inference of structness from the known type, e.g. /// let (x: struct (int * int)) = (3,4) val UnifyTupleTypeAndInferCharacteristics: diff --git a/src/Compiler/Driver/GraphChecking/FileContentMapping.fs b/src/Compiler/Driver/GraphChecking/FileContentMapping.fs index efa1b935fc8..bafc44dff97 100644 --- a/src/Compiler/Driver/GraphChecking/FileContentMapping.fs +++ b/src/Compiler/Driver/GraphChecking/FileContentMapping.fs @@ -559,6 +559,7 @@ let visitSynExpr (e: SynExpr) : FileContentEntry list = | SynExpr.Dynamic(funcExpr, _, argExpr, _) -> let continuations = List.map visit [ funcExpr; argExpr ] Continuation.concatenate continuations continuation + | SynExpr.Open(body = body) -> visit body continuation visit e id diff --git a/src/Compiler/FSComp.txt b/src/Compiler/FSComp.txt index 512e9b4dca7..8afeaa7e491 100644 --- a/src/Compiler/FSComp.txt +++ b/src/Compiler/FSComp.txt @@ -1814,3 +1814,4 @@ featureAllowLetOrUseBangTypeAnnotationWithoutParens,"Allow let! and use! type an 3877,lexLineDirectiveMappingIsNotUnique,"The file '%s' was also pointed to in a line directive in '%s'. Proper warn directive application may not be possible." 3878,tcAttributeIsNotValidForUnionCaseWithFields,"This attribute is not valid for use on union cases with fields." featureReturnFromFinal,"Support for ReturnFromFinal/YieldFromFinal in computation expressions to enable tailcall optimization when available on the builder." +featureOpensInExpressionScope,"'open' declarations in expression scopes" \ No newline at end of file diff --git a/src/Compiler/Facilities/LanguageFeatures.fs b/src/Compiler/Facilities/LanguageFeatures.fs index 4b032db713f..7df2783a903 100644 --- a/src/Compiler/Facilities/LanguageFeatures.fs +++ b/src/Compiler/Facilities/LanguageFeatures.fs @@ -105,6 +105,7 @@ type LanguageFeature = | ErrorOnInvalidDeclsInTypeDefinitions | AllowTypedLetUseAndBang | ReturnFromFinal + | OpensInExpressionScope /// LanguageVersion management type LanguageVersion(versionText) = @@ -245,6 +246,7 @@ type LanguageVersion(versionText) = // F# preview (still preview in 10.0) LanguageFeature.FromEndSlicing, previewVersion // Unfinished features --- needs work + LanguageFeature.OpensInExpressionScope, previewVersion ] static let defaultLanguageVersion = LanguageVersion("default") @@ -415,6 +417,7 @@ type LanguageVersion(versionText) = | LanguageFeature.ErrorOnInvalidDeclsInTypeDefinitions -> FSComp.SR.featureErrorOnInvalidDeclsInTypeDefinitions () | LanguageFeature.AllowTypedLetUseAndBang -> FSComp.SR.featureAllowLetOrUseBangTypeAnnotationWithoutParens () | LanguageFeature.ReturnFromFinal -> FSComp.SR.featureReturnFromFinal () + | LanguageFeature.OpensInExpressionScope -> FSComp.SR.featureOpensInExpressionScope () /// Get a version string associated with the given feature. static member GetFeatureVersionString feature = diff --git a/src/Compiler/Facilities/LanguageFeatures.fsi b/src/Compiler/Facilities/LanguageFeatures.fsi index 1217b83baf6..33dcfaf01c7 100644 --- a/src/Compiler/Facilities/LanguageFeatures.fsi +++ b/src/Compiler/Facilities/LanguageFeatures.fsi @@ -96,6 +96,7 @@ type LanguageFeature = | ErrorOnInvalidDeclsInTypeDefinitions | AllowTypedLetUseAndBang | ReturnFromFinal + | OpensInExpressionScope /// LanguageVersion management type LanguageVersion = diff --git a/src/Compiler/Service/FSharpParseFileResults.fs b/src/Compiler/Service/FSharpParseFileResults.fs index f5c1d978447..b4e43ee5e63 100644 --- a/src/Compiler/Service/FSharpParseFileResults.fs +++ b/src/Compiler/Service/FSharpParseFileResults.fs @@ -762,6 +762,7 @@ type FSharpParseFileResults(diagnostics: FSharpDiagnostic[], input: ParsedInput, yield! walkExpr false e2 yield! walkExpr false e3 + | SynExpr.Open(body = bodyExpr) -> yield! walkExpr true bodyExpr ] // Process a class declaration or F# type declaration diff --git a/src/Compiler/Service/ServiceParseTreeWalk.fs b/src/Compiler/Service/ServiceParseTreeWalk.fs index f280df1b237..1c556cea46c 100644 --- a/src/Compiler/Service/ServiceParseTreeWalk.fs +++ b/src/Compiler/Service/ServiceParseTreeWalk.fs @@ -423,7 +423,8 @@ module SyntaxTraversal = | SynExpr.TypeApp(expr = synExpr) | SynExpr.DotLambda(expr = synExpr) | SynExpr.Quote(quotedExpr = synExpr) - | SynExpr.Paren(expr = synExpr) -> traverseSynExpr synExpr + | SynExpr.Paren(expr = synExpr) + | SynExpr.Open(body = synExpr) -> traverseSynExpr synExpr | SynExpr.InterpolatedString(contents = parts) -> [ diff --git a/src/Compiler/Service/ServiceParsedInputOps.fs b/src/Compiler/Service/ServiceParsedInputOps.fs index 583c7c0f992..abf679b8dae 100644 --- a/src/Compiler/Service/ServiceParsedInputOps.fs +++ b/src/Compiler/Service/ServiceParsedInputOps.fs @@ -1440,6 +1440,25 @@ module ParsedInput = None | _ -> None + let tryMakeOpenDeclarationCtx target m (pos: pos) = + // in theory, this means we're "in an open" + // in practice, because the parse tree/visitors do not handle attributes well yet, need extra check below to ensure not e.g. $here$ + // open System + // [ true + | SynOpenDeclTarget.ModuleOrNamespace _ -> false + + Some(CompletionContext.OpenDeclaration isOpenType) + else + None + /// Try to determine completion context for the given pair (row, columns) let TryGetCompletionContext (pos, parsedInput: ParsedInput, lineStr: string) : CompletionContext option = @@ -1492,6 +1511,8 @@ module ParsedInput = -> Some(CompletionContext.Inherit(InheritanceContext.Unknown, ([], None))) + | SynExpr.Open(target, mOpen, _, _) -> tryMakeOpenDeclarationCtx target mOpen pos + | _ -> defaultTraverse expr member _.VisitRecordField(path, copyOpt, field) = @@ -1760,24 +1781,7 @@ module ParsedInput = member _.VisitModuleDecl(_, defaultTraverse, decl) = match decl with - | SynModuleDecl.Open(target, m) -> - // in theory, this means we're "in an open" - // in practice, because the parse tree/visitors do not handle attributes well yet, need extra check below to ensure not e.g. $here$ - // open System - // [ true - | SynOpenDeclTarget.ModuleOrNamespace _ -> false - - Some(CompletionContext.OpenDeclaration isOpenType) - else - None + | SynModuleDecl.Open(target, m) -> tryMakeOpenDeclarationCtx target m pos // module Namespace.Top // module Nested diff --git a/src/Compiler/SyntaxTree/LexFilter.fs b/src/Compiler/SyntaxTree/LexFilter.fs index e74f514f812..4349ebec067 100644 --- a/src/Compiler/SyntaxTree/LexFilter.fs +++ b/src/Compiler/SyntaxTree/LexFilter.fs @@ -66,6 +66,8 @@ type Context = // Indicates we're processing the second part of a match, after the 'with' // First bool indicates "was this 'with' followed immediately by a '|'"? | CtxtMatchClauses of bool * Position + // Used to avoid early inserting OBLOCKEND in `open type ...` + | CtxtOpen of Position member c.StartPos = match c with @@ -74,6 +76,7 @@ type Context = | CtxtWithAsLet p | CtxtWithAsAugment p | CtxtMatchClauses (_, p) | CtxtIf p | CtxtMatch p | CtxtFor p | CtxtWhile p | CtxtWhen p | CtxtFunction p | CtxtFun p | CtxtTry p | CtxtThen p | CtxtElse p | CtxtVanilla (p, _) + | CtxtOpen p | CtxtSeqBlock (_, p, _) -> p member c.StartCol = c.StartPos.Column @@ -109,6 +112,7 @@ type Context = | CtxtThen _ -> "then" | CtxtElse p -> sprintf "else(%s)" (stringOfPos p) | CtxtVanilla (p, _) -> sprintf "vanilla(%s)" (stringOfPos p) + | CtxtOpen _ -> "open" and AddBlockEnd = AddBlockEnd | NoAddBlockEnd | AddOneSidedBlockEnd and FirstInSequence = FirstInSeqBlock | NotFirstInSeqBlock @@ -971,7 +975,7 @@ type LexFilterImpl ( // These contexts all require indentation by at least one space - | _, (CtxtInterfaceHead _ | CtxtNamespaceHead _ | CtxtModuleHead _ | CtxtException _ | CtxtModuleBody (_, false) | CtxtIf _ | CtxtWithAsLet _ | CtxtLetDecl _ | CtxtMemberHead _ | CtxtMemberBody _ as limitCtxt :: _) + | _, (CtxtInterfaceHead _ | CtxtNamespaceHead _ | CtxtModuleHead _ | CtxtException _ | CtxtModuleBody (_, false) | CtxtIf _ | CtxtWithAsLet _ | CtxtLetDecl _ | CtxtMemberHead _ | CtxtMemberBody _ | CtxtOpen _ as limitCtxt :: _) -> PositionWithColumn(limitCtxt.StartPos, limitCtxt.StartCol + 1) // These contexts can have their contents exactly aligning @@ -2567,6 +2571,29 @@ type LexFilterImpl ( pushCtxtSeqBlock tokenTup AddBlockEnd returnToken tokenLexbufState token + // The expression/type-scoped `open type ...` case, + // prevent early inserting OBLOCKEND by `insertComingSoonTokens` + | OPEN, head :: _ when peekNextToken().IsTYPE && + isSameLine() && // `open` and `type` should be on the same line. If them can be on different lines, + // the `type` keyword can have same indentation as `open`. + (match head with // Follow the checks in `insertComingSoonTokens` + // open-parens of sorts + | CtxtParen(TokenLExprParen, _) -> true + // seq blocks + | CtxtSeqBlock _ -> true + // vanillas + | CtxtVanilla _ -> true + | _ -> false) -> + pushCtxt tokenTup (CtxtOpen tokenStartPos) + if debug then dprintf "pushing CtxtOpen at tokenStartPos = %a\n" outputPos tokenStartPos + returnToken tokenLexbufState token + + // The expression/type-scoped `open type ...` case + | TYPE, CtxtOpen _ :: _ -> + if debug then dprintf "--> because TYPE is coming, popping CtxtOpen\n" + popCtxt() + returnToken tokenLexbufState token + | TYPE, _ -> // Check if this type definition is inappropriately nested in another type checkForInvalidDeclsInTypeDefn "TYPE" diff --git a/src/Compiler/SyntaxTree/SyntaxTree.fs b/src/Compiler/SyntaxTree/SyntaxTree.fs index c41e483e27a..df2d4a7e3de 100644 --- a/src/Compiler/SyntaxTree/SyntaxTree.fs +++ b/src/Compiler/SyntaxTree/SyntaxTree.fs @@ -770,6 +770,8 @@ type SynExpr = | Dynamic of funcExpr: SynExpr * qmark: range * argExpr: SynExpr * range: range + | Open of target: SynOpenDeclTarget * openDeclRange: range * range: range * body: SynExpr + member e.Range = match e with | SynExpr.Paren(range = m) @@ -839,7 +841,8 @@ type SynExpr = | SynExpr.InterpolatedString(range = m) | SynExpr.Dynamic(range = m) -> m | SynExpr.Ident id -> id.idRange - | SynExpr.Typar(range = m) -> m + | SynExpr.Typar(range = m) + | SynExpr.Open(range = m) -> m | SynExpr.DebugPoint(_, _, innerExpr) -> innerExpr.Range member e.RangeWithoutAnyExtraDot = diff --git a/src/Compiler/SyntaxTree/SyntaxTree.fsi b/src/Compiler/SyntaxTree/SyntaxTree.fsi index 819b0b384f2..11f53b6980d 100644 --- a/src/Compiler/SyntaxTree/SyntaxTree.fsi +++ b/src/Compiler/SyntaxTree/SyntaxTree.fsi @@ -958,6 +958,10 @@ type SynExpr = /// F# syntax: f?x | Dynamic of funcExpr: SynExpr * qmark: range * argExpr: SynExpr * range: range + /// An 'open' definition within an expr + /// let open System in ... + | Open of target: SynOpenDeclTarget * openDeclRange: range * range: range * body: SynExpr + /// Gets the syntax range of this construct member Range: range diff --git a/src/Compiler/SyntaxTree/SyntaxTreeOps.fs b/src/Compiler/SyntaxTree/SyntaxTreeOps.fs index 5669b0cd087..b1079f02fba 100644 --- a/src/Compiler/SyntaxTree/SyntaxTreeOps.fs +++ b/src/Compiler/SyntaxTree/SyntaxTreeOps.fs @@ -990,6 +990,8 @@ let rec synExprContainsError inpExpr = | SynInterpolatedStringPart.FillExpr(x, _) -> Some x) |> walkExprs + | SynExpr.Open(body = e) -> walkExpr e + walkExpr inpExpr let longIdentToString (ident: SynLongIdent) = diff --git a/src/Compiler/pars.fsy b/src/Compiler/pars.fsy index 172bd9683e3..82fe4d85fb9 100644 --- a/src/Compiler/pars.fsy +++ b/src/Compiler/pars.fsy @@ -2128,7 +2128,7 @@ classDefnMember: assert (match declPat with SynPatForConstructorDecl _ -> true | _ -> false) let synBindingTrivia: SynBindingTrivia = { LeadingKeyword = SynLeadingKeyword.New mNew; InlineKeyword = None; EqualsRange = None } [ SynMemberDefn.Member(SynBinding(None, SynBindingKind.Normal, false, false, $1, xmlDoc, valSynData, declPat, None, expr, m, DebugPointAtBinding.NoneAtInvisible, synBindingTrivia), m) ] } - + | opt_attributes opt_access NEW atomicPattern optAsSpec OBLOCKSEP { reportParseErrorAt (rhs parseState 5) (FSComp.SR.parsMissingMemberBody ()) let mNew = rhs parseState 3 @@ -2160,7 +2160,6 @@ classDefnMember: let leadingKeyword = SynTypeDefnLeadingKeyword.StaticType(rhs parseState 3, rhs parseState 4) [ SynMemberDefn.NestedType($5 leadingKeyword, None, rhs2 parseState 1 5) ] } - /* A 'val' definition in an object type definition */ valDefnDecl: | VAL opt_mutable opt_access ident COLON typ @@ -4217,6 +4216,11 @@ declExpr: { let (BindingSetPreAttrs(_, _, _, _, m)), e = $1 SynExpr.Do(e, unionRanges (rhs parseState 1).StartRange e.Range) } + | openDecl seps typedSequentialExprBlock + { let target, mOpenDecl = $1 + let mWhole = unionRanges mOpenDecl $3.Range + SynExpr.Open(target, mOpenDecl, mWhole, $3) } + | anonMatchingExpr %prec expr_function { $1 } diff --git a/src/Compiler/xlf/FSComp.txt.cs.xlf b/src/Compiler/xlf/FSComp.txt.cs.xlf index 244be90e142..735e3d0c7ba 100644 --- a/src/Compiler/xlf/FSComp.txt.cs.xlf +++ b/src/Compiler/xlf/FSComp.txt.cs.xlf @@ -537,6 +537,11 @@ Otevřít deklaraci typu + + 'open' declarations in expression scopes + 'open' declarations in expression scopes + + overloads for custom operations přetížení pro vlastní operace diff --git a/src/Compiler/xlf/FSComp.txt.de.xlf b/src/Compiler/xlf/FSComp.txt.de.xlf index d1b1782d093..1cbc8db5ae8 100644 --- a/src/Compiler/xlf/FSComp.txt.de.xlf +++ b/src/Compiler/xlf/FSComp.txt.de.xlf @@ -537,6 +537,11 @@ Deklaration für offene Typen + + 'open' declarations in expression scopes + 'open' declarations in expression scopes + + overloads for custom operations Überladungen für benutzerdefinierte Vorgänge diff --git a/src/Compiler/xlf/FSComp.txt.es.xlf b/src/Compiler/xlf/FSComp.txt.es.xlf index cd311cc7fc5..21277a7b406 100644 --- a/src/Compiler/xlf/FSComp.txt.es.xlf +++ b/src/Compiler/xlf/FSComp.txt.es.xlf @@ -537,6 +537,11 @@ declaración de tipo abierto + + 'open' declarations in expression scopes + 'open' declarations in expression scopes + + overloads for custom operations sobrecargas para operaciones personalizadas diff --git a/src/Compiler/xlf/FSComp.txt.fr.xlf b/src/Compiler/xlf/FSComp.txt.fr.xlf index e05e9ecdf6c..be5d5ed27b2 100644 --- a/src/Compiler/xlf/FSComp.txt.fr.xlf +++ b/src/Compiler/xlf/FSComp.txt.fr.xlf @@ -537,6 +537,11 @@ déclaration de type ouverte + + 'open' declarations in expression scopes + 'open' declarations in expression scopes + + overloads for custom operations surcharges pour les opérations personnalisées diff --git a/src/Compiler/xlf/FSComp.txt.it.xlf b/src/Compiler/xlf/FSComp.txt.it.xlf index a25fd816046..6df60d5d9de 100644 --- a/src/Compiler/xlf/FSComp.txt.it.xlf +++ b/src/Compiler/xlf/FSComp.txt.it.xlf @@ -537,6 +537,11 @@ dichiarazione di tipo aperto + + 'open' declarations in expression scopes + 'open' declarations in expression scopes + + overloads for custom operations overload per le operazioni personalizzate diff --git a/src/Compiler/xlf/FSComp.txt.ja.xlf b/src/Compiler/xlf/FSComp.txt.ja.xlf index 87b7d40df1e..c1462653c00 100644 --- a/src/Compiler/xlf/FSComp.txt.ja.xlf +++ b/src/Compiler/xlf/FSComp.txt.ja.xlf @@ -537,6 +537,11 @@ オープン型宣言 + + 'open' declarations in expression scopes + 'open' declarations in expression scopes + + overloads for custom operations カスタム操作のオーバーロード diff --git a/src/Compiler/xlf/FSComp.txt.ko.xlf b/src/Compiler/xlf/FSComp.txt.ko.xlf index f2fe6e20f97..0ababfea5c6 100644 --- a/src/Compiler/xlf/FSComp.txt.ko.xlf +++ b/src/Compiler/xlf/FSComp.txt.ko.xlf @@ -537,6 +537,11 @@ 개방형 형식 선언 + + 'open' declarations in expression scopes + 'open' declarations in expression scopes + + overloads for custom operations 사용자 지정 작업의 오버로드 diff --git a/src/Compiler/xlf/FSComp.txt.pl.xlf b/src/Compiler/xlf/FSComp.txt.pl.xlf index 23a194ff258..6fa6cee2dd4 100644 --- a/src/Compiler/xlf/FSComp.txt.pl.xlf +++ b/src/Compiler/xlf/FSComp.txt.pl.xlf @@ -537,6 +537,11 @@ deklaracja typu otwartego + + 'open' declarations in expression scopes + 'open' declarations in expression scopes + + overloads for custom operations przeciążenia dla operacji niestandardowych diff --git a/src/Compiler/xlf/FSComp.txt.pt-BR.xlf b/src/Compiler/xlf/FSComp.txt.pt-BR.xlf index 503fc0f073f..0849e0581a0 100644 --- a/src/Compiler/xlf/FSComp.txt.pt-BR.xlf +++ b/src/Compiler/xlf/FSComp.txt.pt-BR.xlf @@ -537,6 +537,11 @@ declaração de tipo aberto + + 'open' declarations in expression scopes + 'open' declarations in expression scopes + + overloads for custom operations sobrecargas para operações personalizadas diff --git a/src/Compiler/xlf/FSComp.txt.ru.xlf b/src/Compiler/xlf/FSComp.txt.ru.xlf index 7013fb0bc83..8b423e35d08 100644 --- a/src/Compiler/xlf/FSComp.txt.ru.xlf +++ b/src/Compiler/xlf/FSComp.txt.ru.xlf @@ -537,6 +537,11 @@ объявление открытого типа + + 'open' declarations in expression scopes + 'open' declarations in expression scopes + + overloads for custom operations перегрузки для настраиваемых операций diff --git a/src/Compiler/xlf/FSComp.txt.tr.xlf b/src/Compiler/xlf/FSComp.txt.tr.xlf index 49d2a295b45..2ec122682c4 100644 --- a/src/Compiler/xlf/FSComp.txt.tr.xlf +++ b/src/Compiler/xlf/FSComp.txt.tr.xlf @@ -537,6 +537,11 @@ açık tür bildirimi + + 'open' declarations in expression scopes + 'open' declarations in expression scopes + + overloads for custom operations özel işlemler için aşırı yüklemeler diff --git a/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf b/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf index 3fc65eebc96..086fb870919 100644 --- a/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf +++ b/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf @@ -537,6 +537,11 @@ 开放类型声明 + + 'open' declarations in expression scopes + 'open' declarations in expression scopes + + overloads for custom operations 自定义操作的重载 diff --git a/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf b/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf index 07fea0efd23..ca30e0a3acb 100644 --- a/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf +++ b/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf @@ -537,6 +537,11 @@ 開放式類型宣告 + + 'open' declarations in expression scopes + 'open' declarations in expression scopes + + overloads for custom operations 為自訂作業多載 diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/ImportDeclarations/E_openModInFun.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/ImportDeclarations/E_openModInFun.fs deleted file mode 100644 index bf3f835744a..00000000000 --- a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/ImportDeclarations/E_openModInFun.fs +++ /dev/null @@ -1,24 +0,0 @@ -// #Regression #Conformance #DeclarationElements #Import -//Unexpected keyword 'open' in binding\. Expected incomplete structured construct at or before this point or other token\.$ -//Unexpected keyword 'open' in binding$ -//Unexpected keyword 'open' in expression$ - -let f x y = - let result = x + y - Console.WriteLine(result.ToString()) - open System - Console.WriteLine(result.ToString()) - - -let top x y = - let r1 = x + y - let r2 = x * y - let nested x y = - open System - Console.WriteLine(result.ToString()) - nested r1 r2 - -type Foo() = - member public this.PrintHello() = - open System - Console.WriteLine("Hello!") diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/ImportDeclarations/ImportDeclarations.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/ImportDeclarations/ImportDeclarations.fs index b8e86960969..8288c728b38 100644 --- a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/ImportDeclarations/ImportDeclarations.fs +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/ImportDeclarations/ImportDeclarations.fs @@ -64,19 +64,13 @@ module ImportDeclarations = (Error 10, Line 7, Col 5, Line 7, Col 9, "Unexpected keyword 'open' in member definition") ] - // SOURCE=E_openModInFun.fs SCFLAGS="--test:ErrorRanges" # E_openModInFun.fs - [] - let ``E_openModInFun_fs`` compilation = + // SOURCE=openModInFun.fs # openModInFun.fs + [] + let ``openModInFun_fs`` compilation = compilation - |> verifyCompile - |> shouldFail - |> withDiagnostics [ - (Error 10, Line 9, Col 5, Line 9, Col 9, "Unexpected keyword 'open' in binding. Expected incomplete structured construct at or before this point or other token.") - (Error 10, Line 17, Col 9, Line 17, Col 13, "Unexpected keyword 'open' in binding") - (Error 58, Line 23, Col 9, Line 23, Col 13, "'open' declarations must appear at module level, not inside types.") - (Error 10, Line 23, Col 9, Line 23, Col 13, "Unexpected keyword 'open' in expression") - (Error 3567, Line 23, Col 9, Line 23, Col 13, "Expecting member body") - ] + |> withLangVersionPreview + |> typecheck + |> shouldSucceed // SOURCE=OpenNestedModule01.fs # OpenNestedModule01.fs [] diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/ImportDeclarations/openModInFun.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/ImportDeclarations/openModInFun.fs new file mode 100644 index 00000000000..38e95c7ded1 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/ImportDeclarations/openModInFun.fs @@ -0,0 +1,93 @@ +// #Regression #Conformance #DeclarationElements #Import +module openModInFun + +let f x y = + let result = x + y + open System + Console.WriteLine(result.ToString()) + + open type Console + WriteLine(result.ToString()) + +let top x y = + let r1 = x + y + let r2 = x * y + let nested x y = + open System + Console.WriteLine(r1.ToString()) + nested r1 r2 + +type Foo() = + do + open System + open type Console + WriteLine 123 + member public this.PrintHello() = + open System + Console.WriteLine("Hello!") + + +( + open type + System.Console + WriteLine() +) + + +// In `match` +match Some 1 with +| Some 1 when open System; Int32.MinValue < 0 -> + open type System.Console + WriteLine "Is 1" +| _ -> () + +// In `for` +for _ in open System.Linq; Enumerable.Range(0, 10) do + open type System.Console + WriteLine "Hello, World!" + +// In `while` +while + (open type System.Int32 + MaxValue < 0) do + open type System.Console + WriteLine "MaxValue is negative" + +// In `if` +if (open type System.Int32; MaxValue <> MinValue) then + open type System.Console + WriteLine "MaxValue is not equal to MinValue" +elif (open type System.Int32; MaxValue < 0) then + open type System.Console + WriteLine "MaxValue is negative" +else + open type System.Console + WriteLine "MaxValue is positive" + +// In `try` +try + open type System.Int32 + open Checked + ignore(MaxValue + 1) +with | exn -> open type System.Console; WriteLine exn.Message + +// In lambdas +let fun1 = fun x -> open System; x + 1 +let fun2 = function x -> open type System.Int32; x + MinValue + +// In computation expressions +let res = async { + open System + Console.WriteLine("Hello, World!") + let! x = Async.Sleep 1000 + return x +} + +// In `query` +let q = + query { + open type System.Linq.Enumerable + for i in Range(1, 10) do + open type int + yield MinValue + i + } |> Seq.toArray diff --git a/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.bsl b/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.bsl index 9ac1302be02..e21e8688338 100644 --- a/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.bsl +++ b/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.bsl @@ -7367,6 +7367,14 @@ FSharp.Compiler.Syntax.SynExpr+ObjExpr: Microsoft.FSharp.Core.FSharpOption`1[FSh FSharp.Compiler.Syntax.SynExpr+ObjExpr: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range] withKeyword FSharp.Compiler.Syntax.SynExpr+ObjExpr: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`2[FSharp.Compiler.Syntax.SynExpr,Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Syntax.Ident]]] argOptions FSharp.Compiler.Syntax.SynExpr+ObjExpr: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`2[FSharp.Compiler.Syntax.SynExpr,Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Syntax.Ident]]] get_argOptions() +FSharp.Compiler.Syntax.SynExpr+Open: FSharp.Compiler.Syntax.SynExpr body +FSharp.Compiler.Syntax.SynExpr+Open: FSharp.Compiler.Syntax.SynExpr get_body() +FSharp.Compiler.Syntax.SynExpr+Open: FSharp.Compiler.Syntax.SynOpenDeclTarget get_target() +FSharp.Compiler.Syntax.SynExpr+Open: FSharp.Compiler.Syntax.SynOpenDeclTarget target +FSharp.Compiler.Syntax.SynExpr+Open: FSharp.Compiler.Text.Range get_openDeclRange() +FSharp.Compiler.Syntax.SynExpr+Open: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynExpr+Open: FSharp.Compiler.Text.Range openDeclRange +FSharp.Compiler.Syntax.SynExpr+Open: FSharp.Compiler.Text.Range range FSharp.Compiler.Syntax.SynExpr+Paren: FSharp.Compiler.Syntax.SynExpr expr FSharp.Compiler.Syntax.SynExpr+Paren: FSharp.Compiler.Syntax.SynExpr get_expr() FSharp.Compiler.Syntax.SynExpr+Paren: FSharp.Compiler.Text.Range get_leftParenRange() @@ -7471,6 +7479,7 @@ FSharp.Compiler.Syntax.SynExpr+Tags: Int32 NamedIndexedPropertySet FSharp.Compiler.Syntax.SynExpr+Tags: Int32 New FSharp.Compiler.Syntax.SynExpr+Tags: Int32 Null FSharp.Compiler.Syntax.SynExpr+Tags: Int32 ObjExpr +FSharp.Compiler.Syntax.SynExpr+Tags: Int32 Open FSharp.Compiler.Syntax.SynExpr+Tags: Int32 Paren FSharp.Compiler.Syntax.SynExpr+Tags: Int32 Quote FSharp.Compiler.Syntax.SynExpr+Tags: Int32 Record @@ -7649,6 +7658,7 @@ FSharp.Compiler.Syntax.SynExpr: Boolean IsNamedIndexedPropertySet FSharp.Compiler.Syntax.SynExpr: Boolean IsNew FSharp.Compiler.Syntax.SynExpr: Boolean IsNull FSharp.Compiler.Syntax.SynExpr: Boolean IsObjExpr +FSharp.Compiler.Syntax.SynExpr: Boolean IsOpen FSharp.Compiler.Syntax.SynExpr: Boolean IsParen FSharp.Compiler.Syntax.SynExpr: Boolean IsQuote FSharp.Compiler.Syntax.SynExpr: Boolean IsRecord @@ -7719,6 +7729,7 @@ FSharp.Compiler.Syntax.SynExpr: Boolean get_IsNamedIndexedPropertySet() FSharp.Compiler.Syntax.SynExpr: Boolean get_IsNew() FSharp.Compiler.Syntax.SynExpr: Boolean get_IsNull() FSharp.Compiler.Syntax.SynExpr: Boolean get_IsObjExpr() +FSharp.Compiler.Syntax.SynExpr: Boolean get_IsOpen() FSharp.Compiler.Syntax.SynExpr: Boolean get_IsParen() FSharp.Compiler.Syntax.SynExpr: Boolean get_IsQuote() FSharp.Compiler.Syntax.SynExpr: Boolean get_IsRecord() @@ -7788,6 +7799,7 @@ FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewNamedIndexedPr FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewNew(Boolean, FSharp.Compiler.Syntax.SynType, FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Text.Range) FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewNull(FSharp.Compiler.Text.Range) FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewObjExpr(FSharp.Compiler.Syntax.SynType, Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`2[FSharp.Compiler.Syntax.SynExpr,Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Syntax.Ident]]], Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range], Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynBinding], Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynMemberDefn], Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynInterfaceImpl], FSharp.Compiler.Text.Range, FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewOpen(FSharp.Compiler.Syntax.SynOpenDeclTarget, FSharp.Compiler.Text.Range, FSharp.Compiler.Text.Range, FSharp.Compiler.Syntax.SynExpr) FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewParen(FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Text.Range, Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range], FSharp.Compiler.Text.Range) FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewQuote(FSharp.Compiler.Syntax.SynExpr, Boolean, FSharp.Compiler.Syntax.SynExpr, Boolean, FSharp.Compiler.Text.Range) FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewRecord(Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`5[FSharp.Compiler.Syntax.SynType,FSharp.Compiler.Syntax.SynExpr,FSharp.Compiler.Text.Range,Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`2[FSharp.Compiler.Text.Range,Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Position]]],FSharp.Compiler.Text.Range]], Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`2[FSharp.Compiler.Syntax.SynExpr,System.Tuple`2[FSharp.Compiler.Text.Range,Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Position]]]], Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynExprRecordField], FSharp.Compiler.Text.Range) @@ -7857,6 +7869,7 @@ FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr+NamedIndexedPrope FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr+New FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr+Null FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr+ObjExpr +FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr+Open FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr+Paren FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr+Quote FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr+Record diff --git a/tests/service/data/SyntaxTree/OpenDeclaration/InExp_ce.fs b/tests/service/data/SyntaxTree/OpenDeclaration/InExp_ce.fs new file mode 100644 index 00000000000..555f5c9c4d5 --- /dev/null +++ b/tests/service/data/SyntaxTree/OpenDeclaration/InExp_ce.fs @@ -0,0 +1,6 @@ +let res = async { + open System + Console.WriteLine("Hello, World!") + let! x = Async.Sleep 1000 + return x +} \ No newline at end of file diff --git a/tests/service/data/SyntaxTree/OpenDeclaration/InExp_ce.fs.bsl b/tests/service/data/SyntaxTree/OpenDeclaration/InExp_ce.fs.bsl new file mode 100644 index 00000000000..283138192ba --- /dev/null +++ b/tests/service/data/SyntaxTree/OpenDeclaration/InExp_ce.fs.bsl @@ -0,0 +1,67 @@ +ImplFile + (ParsedImplFileInput + ("/root/OpenDeclaration/InExp_ce.fs", false, QualifiedNameOfFile InExp_ce, + [], + [SynModuleOrNamespace + ([InExp_ce], false, AnonModule, + [Let + (false, + [SynBinding + (None, Normal, false, false, [], + PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), + SynValData + (None, SynValInfo ([], SynArgInfo ([], false, None)), None), + Named (SynIdent (res, None), false, None, (1,4--1,7)), None, + App + (NonAtomic, false, Ident async, + ComputationExpr + (false, + Open + (ModuleOrNamespace + (SynLongIdent ([System], [], [None]), (2,9--2,15)), + (2,4--2,15), (2,4--5,12), + Sequential + (SuppressNeither, true, + App + (Atomic, false, + LongIdent + (false, + SynLongIdent + ([Console; WriteLine], [(3,11--3,12)], + [None; None]), None, (3,4--3,21)), + Paren + (Const + (String + ("Hello, World!", Regular, (3,22--3,37)), + (3,22--3,37)), (3,21--3,22), + Some (3,37--3,38), (3,21--3,38)), + (3,4--3,38)), + LetOrUseBang + (Yes (4,4--4,29), false, true, + Named + (SynIdent (x, None), false, None, (4,9--4,10)), + App + (NonAtomic, false, + LongIdent + (false, + SynLongIdent + ([Async; Sleep], [(4,18--4,19)], + [None; None]), None, (4,13--4,24)), + Const (Int32 1000, (4,25--4,29)), + (4,13--4,29)), [], + YieldOrReturn + ((false, true), Ident x, (5,4--5,12), + { YieldOrReturnKeyword = (5,4--5,10) }), + (4,4--5,12), + { LetOrUseKeyword = (4,4--4,8) + InKeyword = None + EqualsRange = Some (4,11--4,12) }), + (3,4--5,12), { SeparatorRange = None })), + (1,16--6,1)), (1,10--6,1)), (1,4--1,7), NoneAtLet, + { LeadingKeyword = Let (1,0--1,3) + InlineKeyword = None + EqualsRange = Some (1,8--1,9) })], (1,0--6,1))], + PreXmlDocEmpty, [], None, (1,0--6,1), { LeadingKeyword = None })], + (true, true), { ConditionalDirectives = [] + WarnDirectives = [] + CodeComments = [] }, set [])) diff --git a/tests/service/data/SyntaxTree/OpenDeclaration/InExp_ce2.fs b/tests/service/data/SyntaxTree/OpenDeclaration/InExp_ce2.fs new file mode 100644 index 00000000000..c60327445e9 --- /dev/null +++ b/tests/service/data/SyntaxTree/OpenDeclaration/InExp_ce2.fs @@ -0,0 +1,7 @@ +let q = + query { + open type System.Linq.Enumerable + for i in Range(1, 10) do + open type int + yield MinValue + i + } |> Seq.toArray diff --git a/tests/service/data/SyntaxTree/OpenDeclaration/InExp_ce2.fs.bsl b/tests/service/data/SyntaxTree/OpenDeclaration/InExp_ce2.fs.bsl new file mode 100644 index 00000000000..00d49e26eae --- /dev/null +++ b/tests/service/data/SyntaxTree/OpenDeclaration/InExp_ce2.fs.bsl @@ -0,0 +1,88 @@ +ImplFile + (ParsedImplFileInput + ("/root/OpenDeclaration/InExp_ce2.fs", false, QualifiedNameOfFile InExp_ce2, + [], + [SynModuleOrNamespace + ([InExp_ce2], false, AnonModule, + [Let + (false, + [SynBinding + (None, Normal, false, false, [], + PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), + SynValData + (None, SynValInfo ([], SynArgInfo ([], false, None)), None), + Named (SynIdent (q, None), false, None, (1,4--1,5)), None, + App + (NonAtomic, false, + App + (NonAtomic, true, + LongIdent + (false, + SynLongIdent + ([op_PipeRight], [], [Some (OriginalNotation "|>")]), + None, (7,6--7,8)), + App + (NonAtomic, false, Ident query, + ComputationExpr + (false, + Open + (Type + (LongIdent + (SynLongIdent + ([System; Linq; Enumerable], + [(3,24--3,25); (3,29--3,30)], + [None; None; None])), (3,18--3,40)), + (3,8--3,40), (3,8--6,30), + ForEach + (Yes (4,8--4,11), Yes (4,14--4,16), + SeqExprOnly false, true, + Named + (SynIdent (i, None), false, None, + (4,12--4,13)), + App + (Atomic, false, Ident Range, + Paren + (Tuple + (false, + [Const (Int32 1, (4,23--4,24)); + Const (Int32 10, (4,26--4,28))], + [(4,24--4,25)], (4,23--4,28)), + (4,22--4,23), Some (4,28--4,29), + (4,22--4,29)), (4,17--4,29)), + Open + (Type + (LongIdent + (SynLongIdent ([int], [], [None])), + (5,22--5,25)), (5,12--5,25), + (5,12--6,30), + YieldOrReturn + ((true, false), + App + (NonAtomic, false, + App + (NonAtomic, true, + LongIdent + (false, + SynLongIdent + ([op_Addition], [], + [Some + (OriginalNotation "+")]), + None, (6,27--6,28)), + Ident MinValue, (6,18--6,28)), + Ident i, (6,18--6,30)), + (6,12--6,30), + { YieldOrReturnKeyword = (6,12--6,17) })), + (4,8--6,30))), (2,10--7,5)), (2,4--7,5)), + (2,4--7,8)), + LongIdent + (false, + SynLongIdent + ([Seq; toArray], [(7,12--7,13)], [None; None]), None, + (7,9--7,20)), (2,4--7,20)), (1,4--1,5), NoneAtLet, + { LeadingKeyword = Let (1,0--1,3) + InlineKeyword = None + EqualsRange = Some (1,6--1,7) })], (1,0--7,20))], + PreXmlDocEmpty, [], None, (1,0--8,0), { LeadingKeyword = None })], + (true, true), { ConditionalDirectives = [] + WarnDirectives = [] + CodeComments = [] }, set [])) diff --git a/tests/service/data/SyntaxTree/OpenDeclaration/InExp_dot_lambda.fs b/tests/service/data/SyntaxTree/OpenDeclaration/InExp_dot_lambda.fs new file mode 100644 index 00000000000..9175cec5bf1 --- /dev/null +++ b/tests/service/data/SyntaxTree/OpenDeclaration/InExp_dot_lambda.fs @@ -0,0 +1 @@ +1 |> _.(open Checked; fun x -> x + 1) \ No newline at end of file diff --git a/tests/service/data/SyntaxTree/OpenDeclaration/InExp_dot_lambda.fs.bsl b/tests/service/data/SyntaxTree/OpenDeclaration/InExp_dot_lambda.fs.bsl new file mode 100644 index 00000000000..71f6ffba31d --- /dev/null +++ b/tests/service/data/SyntaxTree/OpenDeclaration/InExp_dot_lambda.fs.bsl @@ -0,0 +1,62 @@ +ImplFile + (ParsedImplFileInput + ("/root/OpenDeclaration/InExp_dot_lambda.fs", false, + QualifiedNameOfFile InExp_dot_lambda, [], + [SynModuleOrNamespace + ([InExp_dot_lambda], false, AnonModule, + [Expr + (App + (NonAtomic, false, + App + (NonAtomic, true, + LongIdent + (false, + SynLongIdent + ([op_PipeRight], [], [Some (OriginalNotation "|>")]), + None, (1,2--1,4)), Const (Int32 1, (1,0--1,1)), + (1,0--1,4)), + DotLambda + (Paren + (Open + (ModuleOrNamespace + (SynLongIdent ([Checked], [], [None]), (1,13--1,20)), + (1,8--1,20), (1,8--1,36), + Lambda + (false, false, + SimplePats + ([Id (x, None, false, false, false, (1,26--1,27))], + [], (1,26--1,27)), + App + (NonAtomic, false, + App + (NonAtomic, true, + LongIdent + (false, + SynLongIdent + ([op_Addition], [], + [Some (OriginalNotation "+")]), None, + (1,33--1,34)), Ident x, (1,31--1,34)), + Const (Int32 1, (1,35--1,36)), (1,31--1,36)), + Some + ([Named + (SynIdent (x, None), false, None, + (1,26--1,27))], + App + (NonAtomic, false, + App + (NonAtomic, true, + LongIdent + (false, + SynLongIdent + ([op_Addition], [], + [Some (OriginalNotation "+")]), None, + (1,33--1,34)), Ident x, (1,31--1,34)), + Const (Int32 1, (1,35--1,36)), (1,31--1,36))), + (1,22--1,36), { ArrowRange = Some (1,28--1,30) })), + (1,7--1,8), Some (1,36--1,37), (1,7--1,37)), (1,5--1,37), + { UnderscoreRange = (1,5--1,6) + DotRange = (1,6--1,7) }), (1,0--1,37)), (1,0--1,37))], + PreXmlDocEmpty, [], None, (1,0--1,37), { LeadingKeyword = None })], + (true, true), { ConditionalDirectives = [] + WarnDirectives = [] + CodeComments = [] }, set [])) diff --git a/tests/service/data/SyntaxTree/OpenDeclaration/InExp_for.fs b/tests/service/data/SyntaxTree/OpenDeclaration/InExp_for.fs new file mode 100644 index 00000000000..172ac0fc907 --- /dev/null +++ b/tests/service/data/SyntaxTree/OpenDeclaration/InExp_for.fs @@ -0,0 +1,3 @@ +for _ in open System.Linq; Enumerable.Range(0, 10) do + open type System.Console + WriteLine "Hello, World!" diff --git a/tests/service/data/SyntaxTree/OpenDeclaration/InExp_for.fs.bsl b/tests/service/data/SyntaxTree/OpenDeclaration/InExp_for.fs.bsl new file mode 100644 index 00000000000..3edfbf4ded0 --- /dev/null +++ b/tests/service/data/SyntaxTree/OpenDeclaration/InExp_for.fs.bsl @@ -0,0 +1,45 @@ +ImplFile + (ParsedImplFileInput + ("/root/OpenDeclaration/InExp_for.fs", false, QualifiedNameOfFile InExp_for, + [], + [SynModuleOrNamespace + ([InExp_for], false, AnonModule, + [Expr + (ForEach + (Yes (1,0--1,3), Yes (1,6--1,8), SeqExprOnly false, true, + Wild (1,4--1,5), + Open + (ModuleOrNamespace + (SynLongIdent + ([System; Linq], [(1,20--1,21)], [None; None]), + (1,14--1,25)), (1,9--1,25), (1,9--1,50), + App + (Atomic, false, + LongIdent + (false, + SynLongIdent + ([Enumerable; Range], [(1,37--1,38)], [None; None]), + None, (1,27--1,43)), + Paren + (Tuple + (false, + [Const (Int32 0, (1,44--1,45)); + Const (Int32 10, (1,47--1,49))], [(1,45--1,46)], + (1,44--1,49)), (1,43--1,44), Some (1,49--1,50), + (1,43--1,50)), (1,27--1,50))), + Open + (Type + (LongIdent + (SynLongIdent + ([System; Console], [(2,20--2,21)], [None; None])), + (2,14--2,28)), (2,4--2,28), (2,4--3,29), + App + (NonAtomic, false, Ident WriteLine, + Const + (String ("Hello, World!", Regular, (3,14--3,29)), + (3,14--3,29)), (3,4--3,29))), (1,0--3,29)), + (1,0--3,29))], PreXmlDocEmpty, [], None, (1,0--4,0), + { LeadingKeyword = None })], (true, true), + { ConditionalDirectives = [] + WarnDirectives = [] + CodeComments = [] }, set [])) diff --git a/tests/service/data/SyntaxTree/OpenDeclaration/InExp_fun.fs b/tests/service/data/SyntaxTree/OpenDeclaration/InExp_fun.fs new file mode 100644 index 00000000000..f883dc3b2c2 --- /dev/null +++ b/tests/service/data/SyntaxTree/OpenDeclaration/InExp_fun.fs @@ -0,0 +1 @@ +let fun1 = fun x -> open System; x + 1 \ No newline at end of file diff --git a/tests/service/data/SyntaxTree/OpenDeclaration/InExp_fun.fs.bsl b/tests/service/data/SyntaxTree/OpenDeclaration/InExp_fun.fs.bsl new file mode 100644 index 00000000000..7ca76ee812f --- /dev/null +++ b/tests/service/data/SyntaxTree/OpenDeclaration/InExp_fun.fs.bsl @@ -0,0 +1,63 @@ +ImplFile + (ParsedImplFileInput + ("/root/OpenDeclaration/InExp_fun.fs", false, QualifiedNameOfFile InExp_fun, + [], + [SynModuleOrNamespace + ([InExp_fun], false, AnonModule, + [Let + (false, + [SynBinding + (None, Normal, false, false, [], + PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), + SynValData + (None, + SynValInfo + ([[SynArgInfo ([], false, Some x)]], + SynArgInfo ([], false, None)), None), + Named (SynIdent (fun1, None), false, None, (1,4--1,8)), None, + Lambda + (false, false, + SimplePats + ([Id (x, None, false, false, false, (1,15--1,16))], [], + (1,15--1,16)), + Open + (ModuleOrNamespace + (SynLongIdent ([System], [], [None]), (1,25--1,31)), + (1,20--1,31), (1,20--1,38), + App + (NonAtomic, false, + App + (NonAtomic, true, + LongIdent + (false, + SynLongIdent + ([op_Addition], [], + [Some (OriginalNotation "+")]), None, + (1,35--1,36)), Ident x, (1,33--1,36)), + Const (Int32 1, (1,37--1,38)), (1,33--1,38))), + Some + ([Named (SynIdent (x, None), false, None, (1,15--1,16))], + Open + (ModuleOrNamespace + (SynLongIdent ([System], [], [None]), (1,25--1,31)), + (1,20--1,31), (1,20--1,38), + App + (NonAtomic, false, + App + (NonAtomic, true, + LongIdent + (false, + SynLongIdent + ([op_Addition], [], + [Some (OriginalNotation "+")]), None, + (1,35--1,36)), Ident x, (1,33--1,36)), + Const (Int32 1, (1,37--1,38)), (1,33--1,38)))), + (1,11--1,38), { ArrowRange = Some (1,17--1,19) }), + (1,4--1,8), NoneAtLet, { LeadingKeyword = Let (1,0--1,3) + InlineKeyword = None + EqualsRange = Some (1,9--1,10) })], + (1,0--1,38))], PreXmlDocEmpty, [], None, (1,0--1,38), + { LeadingKeyword = None })], (true, true), + { ConditionalDirectives = [] + WarnDirectives = [] + CodeComments = [] }, set [])) diff --git a/tests/service/data/SyntaxTree/OpenDeclaration/InExp_function.fs b/tests/service/data/SyntaxTree/OpenDeclaration/InExp_function.fs new file mode 100644 index 00000000000..86a6b49be50 --- /dev/null +++ b/tests/service/data/SyntaxTree/OpenDeclaration/InExp_function.fs @@ -0,0 +1 @@ +let fun2 = function x -> open type System.Int32; x + MinValue \ No newline at end of file diff --git a/tests/service/data/SyntaxTree/OpenDeclaration/InExp_function.fs.bsl b/tests/service/data/SyntaxTree/OpenDeclaration/InExp_function.fs.bsl new file mode 100644 index 00000000000..95fd66562ae --- /dev/null +++ b/tests/service/data/SyntaxTree/OpenDeclaration/InExp_function.fs.bsl @@ -0,0 +1,47 @@ +ImplFile + (ParsedImplFileInput + ("/root/OpenDeclaration/InExp_function.fs", false, + QualifiedNameOfFile InExp_function, [], + [SynModuleOrNamespace + ([InExp_function], false, AnonModule, + [Let + (false, + [SynBinding + (None, Normal, false, false, [], + PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), + SynValData + (None, SynValInfo ([], SynArgInfo ([], false, None)), None), + Named (SynIdent (fun2, None), false, None, (1,4--1,8)), None, + MatchLambda + (false, (1,11--1,19), + [SynMatchClause + (Named (SynIdent (x, None), false, None, (1,20--1,21)), + None, + Open + (Type + (LongIdent + (SynLongIdent + ([System; Int32], [(1,41--1,42)], + [None; None])), (1,35--1,47)), (1,25--1,47), + (1,25--1,61), + App + (NonAtomic, false, + App + (NonAtomic, true, + LongIdent + (false, + SynLongIdent + ([op_Addition], [], + [Some (OriginalNotation "+")]), None, + (1,51--1,52)), Ident x, (1,49--1,52)), + Ident MinValue, (1,49--1,61))), (1,20--1,61), Yes, + { ArrowRange = Some (1,22--1,24) + BarRange = None })], NoneAtInvisible, (1,11--1,61)), + (1,4--1,8), NoneAtLet, { LeadingKeyword = Let (1,0--1,3) + InlineKeyword = None + EqualsRange = Some (1,9--1,10) })], + (1,0--1,61))], PreXmlDocEmpty, [], None, (1,0--1,61), + { LeadingKeyword = None })], (true, true), + { ConditionalDirectives = [] + WarnDirectives = [] + CodeComments = [] }, set [])) diff --git a/tests/service/data/SyntaxTree/OpenDeclaration/InExp_if_elif.fs b/tests/service/data/SyntaxTree/OpenDeclaration/InExp_if_elif.fs new file mode 100644 index 00000000000..8724ef79f71 --- /dev/null +++ b/tests/service/data/SyntaxTree/OpenDeclaration/InExp_if_elif.fs @@ -0,0 +1,9 @@ +if (open type System.Int32; MaxValue <> MinValue) then + open type System.Console + WriteLine "MaxValue is not equal to MinValue" +elif (open type System.Int32; MaxValue < 0) then + open type System.Console + WriteLine "MaxValue is negative" +else + open type System.Console + WriteLine "MaxValue is positive" diff --git a/tests/service/data/SyntaxTree/OpenDeclaration/InExp_if_elif.fs.bsl b/tests/service/data/SyntaxTree/OpenDeclaration/InExp_if_elif.fs.bsl new file mode 100644 index 00000000000..c129c99b1cd --- /dev/null +++ b/tests/service/data/SyntaxTree/OpenDeclaration/InExp_if_elif.fs.bsl @@ -0,0 +1,104 @@ +ImplFile + (ParsedImplFileInput + ("/root/OpenDeclaration/InExp_if_elif.fs", false, + QualifiedNameOfFile InExp_if_elif, [], + [SynModuleOrNamespace + ([InExp_if_elif], false, AnonModule, + [Expr + (IfThenElse + (Paren + (Open + (Type + (LongIdent + (SynLongIdent + ([System; Int32], [(1,20--1,21)], [None; None])), + (1,14--1,26)), (1,4--1,26), (1,4--1,48), + App + (NonAtomic, false, + App + (NonAtomic, true, + LongIdent + (false, + SynLongIdent + ([op_Inequality], [], + [Some (OriginalNotation "<>")]), None, + (1,37--1,39)), Ident MaxValue, (1,28--1,39)), + Ident MinValue, (1,28--1,48))), (1,3--1,4), + Some (1,48--1,49), (1,3--1,49)), + Open + (Type + (LongIdent + (SynLongIdent + ([System; Console], [(2,20--2,21)], [None; None])), + (2,14--2,28)), (2,4--2,28), (2,4--3,49), + App + (NonAtomic, false, Ident WriteLine, + Const + (String + ("MaxValue is not equal to MinValue", Regular, + (3,14--3,49)), (3,14--3,49)), (3,4--3,49))), + Some + (IfThenElse + (Paren + (Open + (Type + (LongIdent + (SynLongIdent + ([System; Int32], [(4,22--4,23)], + [None; None])), (4,16--4,28)), (4,6--4,28), + (4,6--4,42), + App + (NonAtomic, false, + App + (NonAtomic, true, + LongIdent + (false, + SynLongIdent + ([op_LessThan], [], + [Some (OriginalNotation "<")]), None, + (4,39--4,40)), Ident MaxValue, + (4,30--4,40)), Const (Int32 0, (4,41--4,42)), + (4,30--4,42))), (4,5--4,6), Some (4,42--4,43), + (4,5--4,43)), + Open + (Type + (LongIdent + (SynLongIdent + ([System; Console], [(5,20--5,21)], + [None; None])), (5,14--5,28)), (5,4--5,28), + (5,4--6,36), + App + (NonAtomic, false, Ident WriteLine, + Const + (String + ("MaxValue is negative", Regular, (6,14--6,36)), + (6,14--6,36)), (6,4--6,36))), + Some + (Open + (Type + (LongIdent + (SynLongIdent + ([System; Console], [(8,20--8,21)], + [None; None])), (8,14--8,28)), (8,4--8,28), + (8,4--9,36), + App + (NonAtomic, false, Ident WriteLine, + Const + (String + ("MaxValue is positive", Regular, + (9,14--9,36)), (9,14--9,36)), (9,4--9,36)))), + Yes (4,0--4,48), false, (4,0--9,36), + { IfKeyword = (4,0--4,4) + IsElif = true + ThenKeyword = (4,44--4,48) + ElseKeyword = Some (7,0--7,4) + IfToThenRange = (4,0--4,48) })), Yes (1,0--1,54), false, + (1,0--9,36), { IfKeyword = (1,0--1,2) + IsElif = false + ThenKeyword = (1,50--1,54) + ElseKeyword = None + IfToThenRange = (1,0--1,54) }), (1,0--9,36))], + PreXmlDocEmpty, [], None, (1,0--10,0), { LeadingKeyword = None })], + (true, true), { ConditionalDirectives = [] + WarnDirectives = [] + CodeComments = [] }, set [])) diff --git a/tests/service/data/SyntaxTree/OpenDeclaration/InExp_match.fs b/tests/service/data/SyntaxTree/OpenDeclaration/InExp_match.fs new file mode 100644 index 00000000000..324ea3b8e8a --- /dev/null +++ b/tests/service/data/SyntaxTree/OpenDeclaration/InExp_match.fs @@ -0,0 +1,5 @@ +match Some 1 with +| Some 1 when open System; Int32.MinValue < 0 -> + open type System.Console + WriteLine "Is 1" +| _ -> () diff --git a/tests/service/data/SyntaxTree/OpenDeclaration/InExp_match.fs.bsl b/tests/service/data/SyntaxTree/OpenDeclaration/InExp_match.fs.bsl new file mode 100644 index 00000000000..80f9d9e9591 --- /dev/null +++ b/tests/service/data/SyntaxTree/OpenDeclaration/InExp_match.fs.bsl @@ -0,0 +1,61 @@ +ImplFile + (ParsedImplFileInput + ("/root/OpenDeclaration/InExp_match.fs", false, + QualifiedNameOfFile InExp_match, [], + [SynModuleOrNamespace + ([InExp_match], false, AnonModule, + [Expr + (Match + (Yes (1,0--1,17), + App + (NonAtomic, false, Ident Some, Const (Int32 1, (1,11--1,12)), + (1,6--1,12)), + [SynMatchClause + (LongIdent + (SynLongIdent ([Some], [], [None]), None, None, + Pats [Const (Int32 1, (2,7--2,8))], None, (2,2--2,8)), + Some + (Open + (ModuleOrNamespace + (SynLongIdent ([System], [], [None]), (2,19--2,25)), + (2,14--2,25), (2,14--2,45), + App + (NonAtomic, false, + App + (NonAtomic, true, + LongIdent + (false, + SynLongIdent + ([op_LessThan], [], + [Some (OriginalNotation "<")]), None, + (2,42--2,43)), + LongIdent + (false, + SynLongIdent + ([Int32; MinValue], [(2,32--2,33)], + [None; None]), None, (2,27--2,41)), + (2,27--2,43)), Const (Int32 0, (2,44--2,45)), + (2,27--2,45)))), + Open + (Type + (LongIdent + (SynLongIdent + ([System; Console], [(3,20--3,21)], [None; None])), + (3,14--3,28)), (3,4--3,28), (3,4--4,20), + App + (NonAtomic, false, Ident WriteLine, + Const + (String ("Is 1", Regular, (4,14--4,20)), + (4,14--4,20)), (4,4--4,20))), (2,2--4,20), Yes, + { ArrowRange = Some (2,46--2,48) + BarRange = Some (2,0--2,1) }); + SynMatchClause + (Wild (5,2--5,3), None, Const (Unit, (5,7--5,9)), (5,2--5,9), + Yes, { ArrowRange = Some (5,4--5,6) + BarRange = Some (5,0--5,1) })], (1,0--5,9), + { MatchKeyword = (1,0--1,5) + WithKeyword = (1,13--1,17) }), (1,0--5,9))], PreXmlDocEmpty, + [], None, (1,0--6,0), { LeadingKeyword = None })], (true, true), + { ConditionalDirectives = [] + WarnDirectives = [] + CodeComments = [] }, set [])) diff --git a/tests/service/data/SyntaxTree/OpenDeclaration/InExp_parenthesis.fs b/tests/service/data/SyntaxTree/OpenDeclaration/InExp_parenthesis.fs new file mode 100644 index 00000000000..a28003a378c --- /dev/null +++ b/tests/service/data/SyntaxTree/OpenDeclaration/InExp_parenthesis.fs @@ -0,0 +1,5 @@ +( + open type + System.Console + WriteLine() +) \ No newline at end of file diff --git a/tests/service/data/SyntaxTree/OpenDeclaration/InExp_parenthesis.fs.bsl b/tests/service/data/SyntaxTree/OpenDeclaration/InExp_parenthesis.fs.bsl new file mode 100644 index 00000000000..2e3d7d8840c --- /dev/null +++ b/tests/service/data/SyntaxTree/OpenDeclaration/InExp_parenthesis.fs.bsl @@ -0,0 +1,22 @@ +ImplFile + (ParsedImplFileInput + ("/root/OpenDeclaration/InExp_parenthesis.fs", false, + QualifiedNameOfFile InExp_parenthesis, [], + [SynModuleOrNamespace + ([InExp_parenthesis], false, AnonModule, + [Expr + (Paren + (Open + (Type + (LongIdent + (SynLongIdent + ([System; Console], [(3,14--3,15)], [None; None])), + (3,8--3,22)), (2,4--3,22), (2,4--4,15), + App + (Atomic, false, Ident WriteLine, + Const (Unit, (4,13--4,15)), (4,4--4,15))), (1,0--1,1), + Some (5,0--5,1), (1,0--5,1)), (1,0--5,1))], PreXmlDocEmpty, [], + None, (1,0--5,1), { LeadingKeyword = None })], (true, true), + { ConditionalDirectives = [] + WarnDirectives = [] + CodeComments = [] }, set [])) diff --git a/tests/service/data/SyntaxTree/OpenDeclaration/InExp_parenthesis2.fs b/tests/service/data/SyntaxTree/OpenDeclaration/InExp_parenthesis2.fs new file mode 100644 index 00000000000..7cd11dd966b --- /dev/null +++ b/tests/service/data/SyntaxTree/OpenDeclaration/InExp_parenthesis2.fs @@ -0,0 +1,5 @@ +( + open + System + Console.WriteLine() +) \ No newline at end of file diff --git a/tests/service/data/SyntaxTree/OpenDeclaration/InExp_parenthesis2.fs.bsl b/tests/service/data/SyntaxTree/OpenDeclaration/InExp_parenthesis2.fs.bsl new file mode 100644 index 00000000000..46de96310a9 --- /dev/null +++ b/tests/service/data/SyntaxTree/OpenDeclaration/InExp_parenthesis2.fs.bsl @@ -0,0 +1,25 @@ +ImplFile + (ParsedImplFileInput + ("/root/OpenDeclaration/InExp_parenthesis2.fs", false, + QualifiedNameOfFile InExp_parenthesis2, [], + [SynModuleOrNamespace + ([InExp_parenthesis2], false, AnonModule, + [Expr + (Paren + (Open + (ModuleOrNamespace + (SynLongIdent ([System], [], [None]), (3,8--3,14)), + (2,4--3,14), (2,4--4,23), + App + (Atomic, false, + LongIdent + (false, + SynLongIdent + ([Console; WriteLine], [(4,11--4,12)], [None; None]), + None, (4,4--4,21)), Const (Unit, (4,21--4,23)), + (4,4--4,23))), (1,0--1,1), Some (5,0--5,1), (1,0--5,1)), + (1,0--5,1))], PreXmlDocEmpty, [], None, (1,0--5,1), + { LeadingKeyword = None })], (true, true), + { ConditionalDirectives = [] + WarnDirectives = [] + CodeComments = [] }, set [])) diff --git a/tests/service/data/SyntaxTree/OpenDeclaration/InExp_try_with.fs b/tests/service/data/SyntaxTree/OpenDeclaration/InExp_try_with.fs new file mode 100644 index 00000000000..7b54a395123 --- /dev/null +++ b/tests/service/data/SyntaxTree/OpenDeclaration/InExp_try_with.fs @@ -0,0 +1,5 @@ +while + (open type System.Int32 + MaxValue < 0) do + open type System.Console + WriteLine "MaxValue is negative" diff --git a/tests/service/data/SyntaxTree/OpenDeclaration/InExp_try_with.fs.bsl b/tests/service/data/SyntaxTree/OpenDeclaration/InExp_try_with.fs.bsl new file mode 100644 index 00000000000..6c88c67eba3 --- /dev/null +++ b/tests/service/data/SyntaxTree/OpenDeclaration/InExp_try_with.fs.bsl @@ -0,0 +1,44 @@ +ImplFile + (ParsedImplFileInput + ("/root/OpenDeclaration/InExp_try_with.fs", false, + QualifiedNameOfFile InExp_try_with, [], + [SynModuleOrNamespace + ([InExp_try_with], false, AnonModule, + [Expr + (While + (Yes (1,0--3,18), + Paren + (Open + (Type + (LongIdent + (SynLongIdent + ([System; Int32], [(2,21--2,22)], [None; None])), + (2,15--2,27)), (2,5--2,27), (2,5--3,17), + App + (NonAtomic, false, + App + (NonAtomic, true, + LongIdent + (false, + SynLongIdent + ([op_LessThan], [], + [Some (OriginalNotation "<")]), None, + (3,14--3,15)), Ident MaxValue, (3,5--3,15)), + Const (Int32 0, (3,16--3,17)), (3,5--3,17))), + (2,4--2,5), Some (3,17--3,18), (2,4--3,18)), + Open + (Type + (LongIdent + (SynLongIdent + ([System; Console], [(4,20--4,21)], [None; None])), + (4,14--4,28)), (4,4--4,28), (4,4--5,36), + App + (NonAtomic, false, Ident WriteLine, + Const + (String ("MaxValue is negative", Regular, (5,14--5,36)), + (5,14--5,36)), (5,4--5,36))), (1,0--5,36)), + (1,0--5,36))], PreXmlDocEmpty, [], None, (1,0--6,0), + { LeadingKeyword = None })], (true, true), + { ConditionalDirectives = [] + WarnDirectives = [] + CodeComments = [] }, set [])) diff --git a/tests/service/data/SyntaxTree/OpenDeclaration/InExp_type_do.fs b/tests/service/data/SyntaxTree/OpenDeclaration/InExp_type_do.fs new file mode 100644 index 00000000000..3738f1bd763 --- /dev/null +++ b/tests/service/data/SyntaxTree/OpenDeclaration/InExp_type_do.fs @@ -0,0 +1,5 @@ +type Foo() = + do + open System + open type Console + WriteLine 123 \ No newline at end of file diff --git a/tests/service/data/SyntaxTree/OpenDeclaration/InExp_type_do.fs.bsl b/tests/service/data/SyntaxTree/OpenDeclaration/InExp_type_do.fs.bsl new file mode 100644 index 00000000000..a5bc43b7012 --- /dev/null +++ b/tests/service/data/SyntaxTree/OpenDeclaration/InExp_type_do.fs.bsl @@ -0,0 +1,54 @@ +ImplFile + (ParsedImplFileInput + ("/root/OpenDeclaration/InExp_type_do.fs", false, + QualifiedNameOfFile InExp_type_do, [], + [SynModuleOrNamespace + ([InExp_type_do], false, AnonModule, + [Types + ([SynTypeDefn + (SynComponentInfo + ([], None, [], [Foo], + PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), + false, None, (1,5--1,8)), + ObjectModel + (Unspecified, + [ImplicitCtor + (None, [], Const (Unit, (1,8--1,10)), None, + PreXmlDoc ((1,8), FSharp.Compiler.Xml.XmlDocCollector), + (1,5--1,8), { AsKeyword = None }); + LetBindings + ([SynBinding + (None, Do, false, false, [], PreXmlDocEmpty, + SynValData + (None, + SynValInfo ([], SynArgInfo ([], false, None)), + None), Const (Unit, (2,4--5,21)), None, + Open + (ModuleOrNamespace + (SynLongIdent ([System], [], [None]), + (3,13--3,19)), (3,8--3,19), (3,8--5,21), + Open + (Type + (LongIdent + (SynLongIdent ([Console], [], [None])), + (4,18--4,25)), (4,8--4,25), (4,8--5,21), + App + (NonAtomic, false, Ident WriteLine, + Const (Int32 123, (5,18--5,21)), + (5,8--5,21)))), (2,4--5,21), NoneAtDo, + { LeadingKeyword = Do (2,4--2,6) + InlineKeyword = None + EqualsRange = None })], false, false, (2,4--5,21))], + (2,4--5,21)), [], + Some + (ImplicitCtor + (None, [], Const (Unit, (1,8--1,10)), None, + PreXmlDoc ((1,8), FSharp.Compiler.Xml.XmlDocCollector), + (1,5--1,8), { AsKeyword = None })), (1,5--5,21), + { LeadingKeyword = Type (1,0--1,4) + EqualsRange = Some (1,11--1,12) + WithKeyword = None })], (1,0--5,21))], PreXmlDocEmpty, [], + None, (1,0--5,21), { LeadingKeyword = None })], (true, true), + { ConditionalDirectives = [] + WarnDirectives = [] + CodeComments = [] }, set [])) diff --git a/tests/service/data/SyntaxTree/OpenDeclaration/InExp_type_let.fs b/tests/service/data/SyntaxTree/OpenDeclaration/InExp_type_let.fs new file mode 100644 index 00000000000..d3386c2fdcb --- /dev/null +++ b/tests/service/data/SyntaxTree/OpenDeclaration/InExp_type_let.fs @@ -0,0 +1,5 @@ +type Foo() = + let _ = + open System + open type Console + WriteLine 123 \ No newline at end of file diff --git a/tests/service/data/SyntaxTree/OpenDeclaration/InExp_type_let.fs.bsl b/tests/service/data/SyntaxTree/OpenDeclaration/InExp_type_let.fs.bsl new file mode 100644 index 00000000000..d037f58a9af --- /dev/null +++ b/tests/service/data/SyntaxTree/OpenDeclaration/InExp_type_let.fs.bsl @@ -0,0 +1,56 @@ +ImplFile + (ParsedImplFileInput + ("/root/OpenDeclaration/InExp_type_let.fs", false, + QualifiedNameOfFile InExp_type_let, [], + [SynModuleOrNamespace + ([InExp_type_let], false, AnonModule, + [Types + ([SynTypeDefn + (SynComponentInfo + ([], None, [], [Foo], + PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), + false, None, (1,5--1,8)), + ObjectModel + (Unspecified, + [ImplicitCtor + (None, [], Const (Unit, (1,8--1,10)), None, + PreXmlDoc ((1,8), FSharp.Compiler.Xml.XmlDocCollector), + (1,5--1,8), { AsKeyword = None }); + LetBindings + ([SynBinding + (None, Normal, false, false, [], + PreXmlDoc ((2,4), FSharp.Compiler.Xml.XmlDocCollector), + SynValData + (None, + SynValInfo ([], SynArgInfo ([], false, None)), + None), Wild (2,8--2,9), None, + Open + (ModuleOrNamespace + (SynLongIdent ([System], [], [None]), + (3,13--3,19)), (3,8--3,19), (3,8--5,21), + Open + (Type + (LongIdent + (SynLongIdent ([Console], [], [None])), + (4,18--4,25)), (4,8--4,25), (4,8--5,21), + App + (NonAtomic, false, Ident WriteLine, + Const (Int32 123, (5,18--5,21)), + (5,8--5,21)))), (2,8--2,9), + Yes (2,4--5,21), + { LeadingKeyword = Let (2,4--2,7) + InlineKeyword = None + EqualsRange = Some (2,10--2,11) })], false, false, + (2,4--5,21))], (2,4--5,21)), [], + Some + (ImplicitCtor + (None, [], Const (Unit, (1,8--1,10)), None, + PreXmlDoc ((1,8), FSharp.Compiler.Xml.XmlDocCollector), + (1,5--1,8), { AsKeyword = None })), (1,5--5,21), + { LeadingKeyword = Type (1,0--1,4) + EqualsRange = Some (1,11--1,12) + WithKeyword = None })], (1,0--5,21))], PreXmlDocEmpty, [], + None, (1,0--5,21), { LeadingKeyword = None })], (true, true), + { ConditionalDirectives = [] + WarnDirectives = [] + CodeComments = [] }, set [])) diff --git a/tests/service/data/SyntaxTree/OpenDeclaration/InExp_type_member.fs b/tests/service/data/SyntaxTree/OpenDeclaration/InExp_type_member.fs new file mode 100644 index 00000000000..8687ba3faf0 --- /dev/null +++ b/tests/service/data/SyntaxTree/OpenDeclaration/InExp_type_member.fs @@ -0,0 +1,4 @@ +type Foo() = + member public this.PrintHello() = + open System + Console.WriteLine("Hello!") \ No newline at end of file diff --git a/tests/service/data/SyntaxTree/OpenDeclaration/InExp_type_member.fs.bsl b/tests/service/data/SyntaxTree/OpenDeclaration/InExp_type_member.fs.bsl new file mode 100644 index 00000000000..aae34b60b99 --- /dev/null +++ b/tests/service/data/SyntaxTree/OpenDeclaration/InExp_type_member.fs.bsl @@ -0,0 +1,73 @@ +ImplFile + (ParsedImplFileInput + ("/root/OpenDeclaration/InExp_type_member.fs", false, + QualifiedNameOfFile InExp_type_member, [], + [SynModuleOrNamespace + ([InExp_type_member], false, AnonModule, + [Types + ([SynTypeDefn + (SynComponentInfo + ([], None, [], [Foo], + PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), + false, None, (1,5--1,8)), + ObjectModel + (Unspecified, + [ImplicitCtor + (None, [], Const (Unit, (1,8--1,10)), None, + PreXmlDoc ((1,8), FSharp.Compiler.Xml.XmlDocCollector), + (1,5--1,8), { AsKeyword = None }); + Member + (SynBinding + (None, Normal, false, false, [], + PreXmlDoc ((2,4), FSharp.Compiler.Xml.XmlDocCollector), + SynValData + (Some { IsInstance = true + IsDispatchSlot = false + IsOverrideOrExplicitImpl = false + IsFinal = false + GetterOrSetterIsCompilerGenerated = false + MemberKind = Member }, + SynValInfo + ([[SynArgInfo ([], false, None)]; []], + SynArgInfo ([], false, None)), None), + LongIdent + (SynLongIdent + ([this; PrintHello], [(2,22--2,23)], + [None; None]), None, None, + Pats + [Paren + (Const (Unit, (2,33--2,35)), (2,33--2,35))], + Some (Public (2,11--2,17)), (2,11--2,35)), None, + Open + (ModuleOrNamespace + (SynLongIdent ([System], [], [None]), + (3,13--3,19)), (3,8--3,19), (3,8--4,35), + App + (Atomic, false, + LongIdent + (false, + SynLongIdent + ([Console; WriteLine], [(4,15--4,16)], + [None; None]), None, (4,8--4,25)), + Paren + (Const + (String ("Hello!", Regular, (4,26--4,34)), + (4,26--4,34)), (4,25--4,26), + Some (4,34--4,35), (4,25--4,35)), + (4,8--4,35))), (2,11--2,35), NoneAtInvisible, + { LeadingKeyword = Member (2,4--2,10) + InlineKeyword = None + EqualsRange = Some (2,36--2,37) }), (2,4--4,35))], + (2,4--4,35)), [], + Some + (ImplicitCtor + (None, [], Const (Unit, (1,8--1,10)), None, + PreXmlDoc ((1,8), FSharp.Compiler.Xml.XmlDocCollector), + (1,5--1,8), { AsKeyword = None })), (1,5--4,35), + { LeadingKeyword = Type (1,0--1,4) + EqualsRange = Some (1,11--1,12) + WithKeyword = None })], (1,0--4,35))], PreXmlDocEmpty, [], + None, (1,0--4,35), { LeadingKeyword = None })], (true, true), + { ConditionalDirectives = [] + WarnDirectives = [] + CodeComments = [] }, set [])) diff --git a/tests/service/data/SyntaxTree/OpenDeclaration/InExp_type_member2.fs b/tests/service/data/SyntaxTree/OpenDeclaration/InExp_type_member2.fs new file mode 100644 index 00000000000..60ee722abe1 --- /dev/null +++ b/tests/service/data/SyntaxTree/OpenDeclaration/InExp_type_member2.fs @@ -0,0 +1,2 @@ +type Foo() = + member val MinValue: int = (open type System.Int32; MinValue) with get, set diff --git a/tests/service/data/SyntaxTree/OpenDeclaration/InExp_type_member2.fs.bsl b/tests/service/data/SyntaxTree/OpenDeclaration/InExp_type_member2.fs.bsl new file mode 100644 index 00000000000..f8727cc3011 --- /dev/null +++ b/tests/service/data/SyntaxTree/OpenDeclaration/InExp_type_member2.fs.bsl @@ -0,0 +1,65 @@ +ImplFile + (ParsedImplFileInput + ("/root/OpenDeclaration/InExp_type_member2.fs", false, + QualifiedNameOfFile InExp_type_member2, [], + [SynModuleOrNamespace + ([InExp_type_member2], false, AnonModule, + [Types + ([SynTypeDefn + (SynComponentInfo + ([], None, [], [Foo], + PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), + false, None, (1,5--1,8)), + ObjectModel + (Unspecified, + [ImplicitCtor + (None, [], Const (Unit, (1,8--1,10)), None, + PreXmlDoc ((1,8), FSharp.Compiler.Xml.XmlDocCollector), + (1,5--1,8), { AsKeyword = None }); + AutoProperty + ([], false, MinValue, + Some (LongIdent (SynLongIdent ([int], [], [None]))), + PropertyGetSet, + { IsInstance = true + IsDispatchSlot = false + IsOverrideOrExplicitImpl = false + IsFinal = false + GetterOrSetterIsCompilerGenerated = false + MemberKind = Member }, + { IsInstance = true + IsDispatchSlot = false + IsOverrideOrExplicitImpl = false + IsFinal = false + GetterOrSetterIsCompilerGenerated = false + MemberKind = PropertySet }, + PreXmlDoc ((2,4), FSharp.Compiler.Xml.XmlDocCollector), + GetSet (None, None, None), + Paren + (Open + (Type + (LongIdent + (SynLongIdent + ([System; Int32], [(2,48--2,49)], + [None; None])), (2,42--2,54)), + (2,32--2,54), (2,32--2,64), Ident MinValue), + (2,31--2,32), Some (2,64--2,65), (2,31--2,65)), + (2,4--2,79), + { LeadingKeyword = + MemberVal ((2,4--2,10), (2,11--2,14)) + WithKeyword = Some (2,66--2,70) + EqualsRange = Some (2,29--2,30) + GetSetKeywords = + Some (GetSet ((2,71--2,74), (2,76--2,79))) })], + (2,4--2,79)), [], + Some + (ImplicitCtor + (None, [], Const (Unit, (1,8--1,10)), None, + PreXmlDoc ((1,8), FSharp.Compiler.Xml.XmlDocCollector), + (1,5--1,8), { AsKeyword = None })), (1,5--2,79), + { LeadingKeyword = Type (1,0--1,4) + EqualsRange = Some (1,11--1,12) + WithKeyword = None })], (1,0--2,79))], PreXmlDocEmpty, [], + None, (1,0--3,0), { LeadingKeyword = None })], (true, true), + { ConditionalDirectives = [] + WarnDirectives = [] + CodeComments = [] }, set [])) diff --git a/tests/service/data/SyntaxTree/OpenDeclaration/InExp_type_member3.fs b/tests/service/data/SyntaxTree/OpenDeclaration/InExp_type_member3.fs new file mode 100644 index 00000000000..0b47d23b956 --- /dev/null +++ b/tests/service/data/SyntaxTree/OpenDeclaration/InExp_type_member3.fs @@ -0,0 +1,2 @@ +type Foo() = + member _.MinValue with get() = open type System.Int32; MinValue and set (_: int) = () diff --git a/tests/service/data/SyntaxTree/OpenDeclaration/InExp_type_member3.fs.bsl b/tests/service/data/SyntaxTree/OpenDeclaration/InExp_type_member3.fs.bsl new file mode 100644 index 00000000000..2df9383a59b --- /dev/null +++ b/tests/service/data/SyntaxTree/OpenDeclaration/InExp_type_member3.fs.bsl @@ -0,0 +1,106 @@ +ImplFile + (ParsedImplFileInput + ("/root/OpenDeclaration/InExp_type_member3.fs", false, + QualifiedNameOfFile InExp_type_member3, [], + [SynModuleOrNamespace + ([InExp_type_member3], false, AnonModule, + [Types + ([SynTypeDefn + (SynComponentInfo + ([], None, [], [Foo], + PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), + false, None, (1,5--1,8)), + ObjectModel + (Unspecified, + [ImplicitCtor + (None, [], Const (Unit, (1,8--1,10)), None, + PreXmlDoc ((1,8), FSharp.Compiler.Xml.XmlDocCollector), + (1,5--1,8), { AsKeyword = None }); + GetSetMember + (Some + (SynBinding + (None, Normal, false, false, [], + PreXmlMerge + (PreXmlDoc ((2,4), FSharp.Compiler.Xml.XmlDocCollector), PreXmlDocEmpty), + SynValData + (Some + { IsInstance = true + IsDispatchSlot = false + IsOverrideOrExplicitImpl = false + IsFinal = false + GetterOrSetterIsCompilerGenerated = false + MemberKind = PropertyGet }, + SynValInfo + ([[SynArgInfo ([], false, None)]; []], + SynArgInfo ([], false, None)), None), + LongIdent + (SynLongIdent + ([_; MinValue], [(2,12--2,13)], [None; None]), + Some get, None, + Pats + [Paren + (Const (Unit, (2,30--2,32)), (2,30--2,32))], + None, (2,27--2,32)), None, + Open + (Type + (LongIdent + (SynLongIdent + ([System; Int32], [(2,51--2,52)], + [None; None])), (2,45--2,57)), + (2,35--2,57), (2,35--2,67), Ident MinValue), + (2,27--2,32), NoneAtInvisible, + { LeadingKeyword = Member (2,4--2,10) + InlineKeyword = None + EqualsRange = Some (2,33--2,34) })), + Some + (SynBinding + (None, Normal, false, false, [], + PreXmlMerge + (PreXmlDoc ((2,4), FSharp.Compiler.Xml.XmlDocCollector), PreXmlDocEmpty), + SynValData + (Some + { IsInstance = true + IsDispatchSlot = false + IsOverrideOrExplicitImpl = false + IsFinal = false + GetterOrSetterIsCompilerGenerated = false + MemberKind = PropertySet }, + SynValInfo + ([[SynArgInfo ([], false, None)]; + [SynArgInfo ([], false, None)]], + SynArgInfo ([], false, None)), None), + LongIdent + (SynLongIdent + ([_; MinValue], [(2,12--2,13)], [None; None]), + Some set, None, + Pats + [Paren + (Typed + (Wild (2,77--2,78), + LongIdent + (SynLongIdent ([int], [], [None])), + (2,77--2,83)), (2,76--2,84))], None, + (2,72--2,84)), None, + Const (Unit, (2,87--2,89)), (2,72--2,84), + NoneAtInvisible, + { LeadingKeyword = Member (2,4--2,10) + InlineKeyword = None + EqualsRange = Some (2,85--2,86) })), + (2,4--2,89), { InlineKeyword = None + WithKeyword = (2,22--2,26) + GetKeyword = Some (2,27--2,30) + AndKeyword = Some (2,68--2,71) + SetKeyword = Some (2,72--2,75) })], + (2,4--2,89)), [], + Some + (ImplicitCtor + (None, [], Const (Unit, (1,8--1,10)), None, + PreXmlDoc ((1,8), FSharp.Compiler.Xml.XmlDocCollector), + (1,5--1,8), { AsKeyword = None })), (1,5--2,89), + { LeadingKeyword = Type (1,0--1,4) + EqualsRange = Some (1,11--1,12) + WithKeyword = None })], (1,0--2,89))], PreXmlDocEmpty, [], + None, (1,0--3,0), { LeadingKeyword = None })], (true, true), + { ConditionalDirectives = [] + WarnDirectives = [] + CodeComments = [] }, set [])) diff --git a/tests/service/data/SyntaxTree/OpenDeclaration/InExp_while.fs b/tests/service/data/SyntaxTree/OpenDeclaration/InExp_while.fs new file mode 100644 index 00000000000..7b54a395123 --- /dev/null +++ b/tests/service/data/SyntaxTree/OpenDeclaration/InExp_while.fs @@ -0,0 +1,5 @@ +while + (open type System.Int32 + MaxValue < 0) do + open type System.Console + WriteLine "MaxValue is negative" diff --git a/tests/service/data/SyntaxTree/OpenDeclaration/InExp_while.fs.bsl b/tests/service/data/SyntaxTree/OpenDeclaration/InExp_while.fs.bsl new file mode 100644 index 00000000000..b47a35f6fa6 --- /dev/null +++ b/tests/service/data/SyntaxTree/OpenDeclaration/InExp_while.fs.bsl @@ -0,0 +1,44 @@ +ImplFile + (ParsedImplFileInput + ("/root/OpenDeclaration/InExp_while.fs", false, + QualifiedNameOfFile InExp_while, [], + [SynModuleOrNamespace + ([InExp_while], false, AnonModule, + [Expr + (While + (Yes (1,0--3,18), + Paren + (Open + (Type + (LongIdent + (SynLongIdent + ([System; Int32], [(2,21--2,22)], [None; None])), + (2,15--2,27)), (2,5--2,27), (2,5--3,17), + App + (NonAtomic, false, + App + (NonAtomic, true, + LongIdent + (false, + SynLongIdent + ([op_LessThan], [], + [Some (OriginalNotation "<")]), None, + (3,14--3,15)), Ident MaxValue, (3,5--3,15)), + Const (Int32 0, (3,16--3,17)), (3,5--3,17))), + (2,4--2,5), Some (3,17--3,18), (2,4--3,18)), + Open + (Type + (LongIdent + (SynLongIdent + ([System; Console], [(4,20--4,21)], [None; None])), + (4,14--4,28)), (4,4--4,28), (4,4--5,36), + App + (NonAtomic, false, Ident WriteLine, + Const + (String ("MaxValue is negative", Regular, (5,14--5,36)), + (5,14--5,36)), (5,4--5,36))), (1,0--5,36)), + (1,0--5,36))], PreXmlDocEmpty, [], None, (1,0--6,0), + { LeadingKeyword = None })], (true, true), + { ConditionalDirectives = [] + WarnDirectives = [] + CodeComments = [] }, set [])) diff --git a/tests/service/data/SyntaxTree/OpenDeclaration/InObjExpr.fs b/tests/service/data/SyntaxTree/OpenDeclaration/InObjExpr.fs new file mode 100644 index 00000000000..c499a980d38 --- /dev/null +++ b/tests/service/data/SyntaxTree/OpenDeclaration/InObjExpr.fs @@ -0,0 +1,4 @@ +{ new System.IDisposable with + open System + member _.F _ = 3 +} diff --git a/tests/service/data/SyntaxTree/OpenDeclaration/InObjExpr.fs.bsl b/tests/service/data/SyntaxTree/OpenDeclaration/InObjExpr.fs.bsl new file mode 100644 index 00000000000..87332d7d957 --- /dev/null +++ b/tests/service/data/SyntaxTree/OpenDeclaration/InObjExpr.fs.bsl @@ -0,0 +1,43 @@ +ImplFile + (ParsedImplFileInput + ("/root/OpenDeclaration/InObjExpr.fs", false, QualifiedNameOfFile InObjExpr, + [], + [SynModuleOrNamespace + ([InObjExpr], false, AnonModule, + [Expr + (ObjExpr + (LongIdent + (SynLongIdent + ([System; IDisposable], [(1,12--1,13)], [None; None])), + None, Some (1,25--1,29), [], + [Member + (SynBinding + (None, Normal, false, false, [], + PreXmlDoc ((3,4), FSharp.Compiler.Xml.XmlDocCollector), + SynValData + (Some { IsInstance = true + IsDispatchSlot = false + IsOverrideOrExplicitImpl = true + IsFinal = false + GetterOrSetterIsCompilerGenerated = false + MemberKind = Member }, + SynValInfo + ([[SynArgInfo ([], false, None)]; + [SynArgInfo ([], false, None)]], + SynArgInfo ([], false, None)), None), + LongIdent + (SynLongIdent ([_; F], [(3,12--3,13)], [None; None]), + None, None, Pats [Wild (3,15--3,16)], None, + (3,11--3,16)), None, Const (Int32 3, (3,19--3,20)), + (3,11--3,16), NoneAtInvisible, + { LeadingKeyword = Member (3,4--3,10) + InlineKeyword = None + EqualsRange = Some (3,17--3,18) }), (3,4--3,20))], [], + (1,2--1,24), (1,0--4,1)), (1,0--4,1))], PreXmlDocEmpty, [], + None, (1,0--4,1), { LeadingKeyword = None })], (true, true), + { ConditionalDirectives = [] + WarnDirectives = [] + CodeComments = [] }, set [])) + +(2,4)-(2,8) parse error Unexpected keyword 'open' in object expression. Expected 'member', 'override', 'static' or other token. +(2,16)-(3,4) parse error Expecting member body diff --git a/tests/service/data/SyntaxTree/OpenDeclaration/InObjExpr2.fs b/tests/service/data/SyntaxTree/OpenDeclaration/InObjExpr2.fs new file mode 100644 index 00000000000..f51664a532c --- /dev/null +++ b/tests/service/data/SyntaxTree/OpenDeclaration/InObjExpr2.fs @@ -0,0 +1,4 @@ +{ new System.IDisposable with + member _.F _ = 3 + open System +} diff --git a/tests/service/data/SyntaxTree/OpenDeclaration/InObjExpr2.fs.bsl b/tests/service/data/SyntaxTree/OpenDeclaration/InObjExpr2.fs.bsl new file mode 100644 index 00000000000..8b67bf48f1e --- /dev/null +++ b/tests/service/data/SyntaxTree/OpenDeclaration/InObjExpr2.fs.bsl @@ -0,0 +1,43 @@ +ImplFile + (ParsedImplFileInput + ("/root/OpenDeclaration/InObjExpr2.fs", false, + QualifiedNameOfFile InObjExpr2, [], + [SynModuleOrNamespace + ([InObjExpr2], false, AnonModule, + [Expr + (ObjExpr + (LongIdent + (SynLongIdent + ([System; IDisposable], [(1,12--1,13)], [None; None])), + None, Some (1,25--1,29), [], + [Member + (SynBinding + (None, Normal, false, false, [], + PreXmlDoc ((2,4), FSharp.Compiler.Xml.XmlDocCollector), + SynValData + (Some { IsInstance = true + IsDispatchSlot = false + IsOverrideOrExplicitImpl = true + IsFinal = false + GetterOrSetterIsCompilerGenerated = false + MemberKind = Member }, + SynValInfo + ([[SynArgInfo ([], false, None)]; + [SynArgInfo ([], false, None)]], + SynArgInfo ([], false, None)), None), + LongIdent + (SynLongIdent ([_; F], [(2,12--2,13)], [None; None]), + None, None, Pats [Wild (2,15--2,16)], None, + (2,11--2,16)), None, Const (Int32 3, (2,19--2,20)), + (2,11--2,16), NoneAtInvisible, + { LeadingKeyword = Member (2,4--2,10) + InlineKeyword = None + EqualsRange = Some (2,17--2,18) }), (2,4--2,20))], [], + (1,2--1,24), (1,0--4,1)), (1,0--4,1))], PreXmlDocEmpty, [], + None, (1,0--4,1), { LeadingKeyword = None })], (true, true), + { ConditionalDirectives = [] + WarnDirectives = [] + CodeComments = [] }, set [])) + +(3,4)-(3,8) parse error Unexpected keyword 'open' in object expression. Expected 'member', 'override', 'static' or other token. +(4,0)-(4,1) parse error Expecting member body diff --git a/tests/service/data/SyntaxTree/OpenDeclaration/OpenTypeNotOnSameLine.fs b/tests/service/data/SyntaxTree/OpenDeclaration/OpenTypeNotOnSameLine.fs new file mode 100644 index 00000000000..06d15f5ce9e --- /dev/null +++ b/tests/service/data/SyntaxTree/OpenDeclaration/OpenTypeNotOnSameLine.fs @@ -0,0 +1,2 @@ +open + type System.Collections.Generic \ No newline at end of file diff --git a/tests/service/data/SyntaxTree/OpenDeclaration/OpenTypeNotOnSameLine.fs.bsl b/tests/service/data/SyntaxTree/OpenDeclaration/OpenTypeNotOnSameLine.fs.bsl new file mode 100644 index 00000000000..260b28fb169 --- /dev/null +++ b/tests/service/data/SyntaxTree/OpenDeclaration/OpenTypeNotOnSameLine.fs.bsl @@ -0,0 +1,17 @@ +ImplFile + (ParsedImplFileInput + ("/root/OpenDeclaration/OpenTypeNotOnSameLine.fs", false, + QualifiedNameOfFile OpenTypeNotOnSameLine, [], + [SynModuleOrNamespace + ([OpenTypeNotOnSameLine], false, AnonModule, + [Open + (Type + (LongIdent + (SynLongIdent + ([System; Collections; Generic], + [(2,15--2,16); (2,27--2,28)], [None; None; None])), + (2,9--2,35)), (1,0--2,35))], PreXmlDocEmpty, [], None, + (1,0--2,35), { LeadingKeyword = None })], (true, true), + { ConditionalDirectives = [] + WarnDirectives = [] + CodeComments = [] }, set [])) diff --git a/tests/service/data/SyntaxTree/OpenDeclaration/OpenTypeNotOnSameLine2.fs b/tests/service/data/SyntaxTree/OpenDeclaration/OpenTypeNotOnSameLine2.fs new file mode 100644 index 00000000000..02ec76e42d8 --- /dev/null +++ b/tests/service/data/SyntaxTree/OpenDeclaration/OpenTypeNotOnSameLine2.fs @@ -0,0 +1,2 @@ +(open + type System.Collections.Generic) \ No newline at end of file diff --git a/tests/service/data/SyntaxTree/OpenDeclaration/OpenTypeNotOnSameLine2.fs.bsl b/tests/service/data/SyntaxTree/OpenDeclaration/OpenTypeNotOnSameLine2.fs.bsl new file mode 100644 index 00000000000..c32edbf565b --- /dev/null +++ b/tests/service/data/SyntaxTree/OpenDeclaration/OpenTypeNotOnSameLine2.fs.bsl @@ -0,0 +1,16 @@ +ImplFile + (ParsedImplFileInput + ("/root/OpenDeclaration/OpenTypeNotOnSameLine2.fs", false, + QualifiedNameOfFile OpenTypeNotOnSameLine2, [], + [SynModuleOrNamespace + ([OpenTypeNotOnSameLine2], false, AnonModule, + [Expr + (Paren + (ArbitraryAfterError ("parenExpr1", (1,1--1,1)), (1,0--1,1), + Some (2,35--2,36), (1,0--2,36)), (1,0--2,36))], PreXmlDocEmpty, + [], None, (1,0--2,36), { LeadingKeyword = None })], (true, true), + { ConditionalDirectives = [] + WarnDirectives = [] + CodeComments = [] }, set [])) + +(2,35)-(2,36) parse error Unexpected symbol ')' in expression. Expected ';' or other token. diff --git a/tests/service/data/SyntaxTree/OpenDeclaration/OpenTypeOnSameIndent.fs b/tests/service/data/SyntaxTree/OpenDeclaration/OpenTypeOnSameIndent.fs new file mode 100644 index 00000000000..ddd4b6f726c --- /dev/null +++ b/tests/service/data/SyntaxTree/OpenDeclaration/OpenTypeOnSameIndent.fs @@ -0,0 +1,2 @@ +open +type System \ No newline at end of file diff --git a/tests/service/data/SyntaxTree/OpenDeclaration/OpenTypeOnSameIndent.fs.bsl b/tests/service/data/SyntaxTree/OpenDeclaration/OpenTypeOnSameIndent.fs.bsl new file mode 100644 index 00000000000..445673f2c77 --- /dev/null +++ b/tests/service/data/SyntaxTree/OpenDeclaration/OpenTypeOnSameIndent.fs.bsl @@ -0,0 +1,25 @@ +ImplFile + (ParsedImplFileInput + ("/root/OpenDeclaration/OpenTypeOnSameIndent.fs", false, + QualifiedNameOfFile OpenTypeOnSameIndent, [], + [SynModuleOrNamespace + ([OpenTypeOnSameIndent], false, AnonModule, + [Open + (ModuleOrNamespace (SynLongIdent ([], [], []), (1,4--1,4)), + (1,0--1,4)); + Types + ([SynTypeDefn + (SynComponentInfo + ([], None, [], [System], + PreXmlDoc ((2,0), FSharp.Compiler.Xml.XmlDocCollector), + false, None, (2,5--2,11)), + Simple (None (2,5--2,11), (2,5--2,11)), [], None, (2,5--2,11), + { LeadingKeyword = Type (2,0--2,4) + EqualsRange = None + WithKeyword = None })], (2,0--2,11))], PreXmlDocEmpty, [], + None, (1,0--2,11), { LeadingKeyword = None })], (true, true), + { ConditionalDirectives = [] + WarnDirectives = [] + CodeComments = [] }, set [])) + +(1,5)-(2,0) parse error Incomplete structured construct at or before this point in open declaration. Expected identifier, 'global', 'type' or other token. diff --git a/tests/service/data/SyntaxTree/OpenDeclaration/OpenTypeOnSameIndent2.fs b/tests/service/data/SyntaxTree/OpenDeclaration/OpenTypeOnSameIndent2.fs new file mode 100644 index 00000000000..d5d5af6bc71 --- /dev/null +++ b/tests/service/data/SyntaxTree/OpenDeclaration/OpenTypeOnSameIndent2.fs @@ -0,0 +1,2 @@ +(open + type System) \ No newline at end of file diff --git a/tests/service/data/SyntaxTree/OpenDeclaration/OpenTypeOnSameIndent2.fs.bsl b/tests/service/data/SyntaxTree/OpenDeclaration/OpenTypeOnSameIndent2.fs.bsl new file mode 100644 index 00000000000..22f893fd43c --- /dev/null +++ b/tests/service/data/SyntaxTree/OpenDeclaration/OpenTypeOnSameIndent2.fs.bsl @@ -0,0 +1,18 @@ +ImplFile + (ParsedImplFileInput + ("/root/OpenDeclaration/OpenTypeOnSameIndent2.fs", false, + QualifiedNameOfFile OpenTypeOnSameIndent2, [], + [SynModuleOrNamespace + ([OpenTypeOnSameIndent2], false, AnonModule, + [Expr + (Paren + (Open + (ModuleOrNamespace (SynLongIdent ([], [], []), (1,5--1,5)), + (1,1--1,5), (1,1--2,12), Ident System), (1,0--1,1), + Some (2,12--2,13), (1,0--2,13)), (1,0--2,13))], PreXmlDocEmpty, + [], None, (1,0--2,13), { LeadingKeyword = None })], (true, true), + { ConditionalDirectives = [] + WarnDirectives = [] + CodeComments = [] }, set [])) + +(1,6)-(2,1) parse error Incomplete structured construct at or before this point in open declaration. Expected identifier, 'global', 'type' or other token. diff --git a/vsintegration/tests/FSharp.Editor.Tests/CodeFixes/AddMissingEqualsToTypeDefinitionTests.fs b/vsintegration/tests/FSharp.Editor.Tests/CodeFixes/AddMissingEqualsToTypeDefinitionTests.fs index c81dbe99611..716f97610d5 100644 --- a/vsintegration/tests/FSharp.Editor.Tests/CodeFixes/AddMissingEqualsToTypeDefinitionTests.fs +++ b/vsintegration/tests/FSharp.Editor.Tests/CodeFixes/AddMissingEqualsToTypeDefinitionTests.fs @@ -52,7 +52,8 @@ type Name = Name of string Assert.Equal(expected, actual) [] -[] +// [] // This case will not trigger the code fix in VS because the error message of +// // this is not related with missing equals now. [] + [] member public this.``LocationOfParams.UnmatchedParens.Bug91609.OtherCases.Open``() = this.TestParameterInfoLocationOfParams(""" let arr = Array.create 4 1 diff --git a/vsintegration/tests/UnitTests/UnusedOpensTests.fs b/vsintegration/tests/UnitTests/UnusedOpensTests.fs index b77d7e257ef..7e93c6f417c 100644 --- a/vsintegration/tests/UnitTests/UnusedOpensTests.fs +++ b/vsintegration/tests/UnitTests/UnusedOpensTests.fs @@ -851,3 +851,23 @@ printfn "%A" MyModule.Thingy.Thing """ => [6, (10, 25)] + +[] +let ``unused open C# type in expression scoped``() = + """ +let f() = + open type System.Console + printfn "%s" "Hello World" + """ + => [3, (14, 28)] + +[] +let ``expression-scoped open declaration duplication in module is unused``() = + """ +module TopModule +open System.IO +let _ = + open System.IO + File.Create "" +""" + => [ 5, (9, 18) ]