Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 12 additions & 9 deletions src/fsharp/ParseAndCheckInputs.fs
Original file line number Diff line number Diff line change
Expand Up @@ -170,9 +170,12 @@ let GetScopedPragmasForHashDirective hd =
[ match hd with
| ParsedHashDirective("nowarn", numbers, m) ->
for s in numbers do
match GetWarningNumber(m, s) with
| None -> ()
| Some n -> yield ScopedPragma.WarningOff(m, n)
match s with
| ParsedHashDirectiveArgument.SourceIdentifier _ -> ()
| ParsedHashDirectiveArgument.String (s, _, _) ->
match GetWarningNumber(m, s) with
| None -> ()
| Some n -> yield ScopedPragma.WarningOff(m, n)
| _ -> () ]

let PostParseModuleImpls (defaultNamespace, filename, isLastCompiland, ParsedImplFile (hashDirectives, impls)) =
Expand Down Expand Up @@ -512,7 +515,7 @@ let ProcessMetaCommandsFromInput
let mutable matchedm = range0
try
match hash with
| ParsedHashDirective("I", args, m) ->
| ParsedHashDirective("I", ParsedHashDirectiveArguments args, m) ->
if not canHaveScriptMetaCommands then
errorR(HashIncludeNotAllowedInNonScript m)
match args with
Expand All @@ -523,18 +526,18 @@ let ProcessMetaCommandsFromInput
| _ ->
errorR(Error(FSComp.SR.buildInvalidHashIDirective(), m))
state
| ParsedHashDirective("nowarn",numbers,m) ->
| ParsedHashDirective("nowarn", ParsedHashDirectiveArguments numbers,m) ->
List.fold (fun state d -> nowarnF state (m,d)) state numbers

| ParsedHashDirective(("reference" | "r"), args, m) ->
| ParsedHashDirective(("reference" | "r"), ParsedHashDirectiveArguments args, m) ->
matchedm<-m
ProcessDependencyManagerDirective Directive.Resolution args m state

| ParsedHashDirective(("i"), args, m) ->
| ParsedHashDirective(("i"), ParsedHashDirectiveArguments args, m) ->
matchedm<-m
ProcessDependencyManagerDirective Directive.Include args m state

| ParsedHashDirective("load", args, m) ->
| ParsedHashDirective("load", ParsedHashDirectiveArguments args, m) ->
if not canHaveScriptMetaCommands then
errorR(HashDirectiveNotAllowedInNonScript m)
match args with
Expand All @@ -544,7 +547,7 @@ let ProcessMetaCommandsFromInput
| _ ->
errorR(Error(FSComp.SR.buildInvalidHashloadDirective(), m))
state
| ParsedHashDirective("time", args, m) ->
| ParsedHashDirective("time", ParsedHashDirectiveArguments args, m) ->
if not canHaveScriptMetaCommands then
errorR(HashDirectiveNotAllowedInNonScript m)
match args with
Expand Down
12 changes: 11 additions & 1 deletion src/fsharp/SyntaxTree.fs
Original file line number Diff line number Diff line change
Expand Up @@ -1826,11 +1826,21 @@ type SynModuleOrNamespaceSig =
match this with
| SynModuleOrNamespaceSig (range=m) -> m

[<NoEquality; NoComparison>]
type ParsedHashDirectiveArgument =
| String of value: string * stringKind: SynStringKind * range: Range
| SourceIdentifier of constant: string * value: string * range: Range

member this.Range =
match this with
| ParsedHashDirectiveArgument.String (range=m)
| ParsedHashDirectiveArgument.SourceIdentifier (range=m) -> m

[<NoEquality; NoComparison>]
type ParsedHashDirective =
| ParsedHashDirective of
ident: string *
args: string list *
args: ParsedHashDirectiveArgument list *
range: range

[<NoEquality; NoComparison; RequireQualifiedAccess>]
Expand Down
11 changes: 10 additions & 1 deletion src/fsharp/SyntaxTree.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -2014,12 +2014,21 @@ type SynModuleOrNamespaceSig =
/// Gets the syntax range of this construct
member Range: range

/// Represents a parsed hash directive argument
[<NoEquality; NoComparison>]
type ParsedHashDirectiveArgument =
| String of value: string * stringKind: SynStringKind * range: Range
| SourceIdentifier of constant: string * value: string * range: Range

/// Gets the syntax range of this construct
member Range: range

/// Represents a parsed hash directive
[<NoEquality; NoComparison>]
type ParsedHashDirective =
| ParsedHashDirective of
ident: string *
args: string list *
args: ParsedHashDirectiveArgument list *
range: range

/// Represents the syntax tree for the contents of a parsed implementation file
Expand Down
7 changes: 7 additions & 0 deletions src/fsharp/SyntaxTreeOps.fs
Original file line number Diff line number Diff line change
Expand Up @@ -747,3 +747,10 @@ let rec synExprContainsError inpExpr =
| SynInterpolatedStringPart.FillExpr (x, _) -> Some x))

walkExpr inpExpr

let (|ParsedHashDirectiveArguments|) (input: ParsedHashDirectiveArgument list) =
List.map
(function
| ParsedHashDirectiveArgument.String (s, _, _) -> s
| ParsedHashDirectiveArgument.SourceIdentifier (_, v, _) -> v)
input
2 changes: 2 additions & 0 deletions src/fsharp/SyntaxTreeOps.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -266,3 +266,5 @@ val inferredTyparDecls: SynValTyparDecls
val noInferredTypars: SynValTyparDecls

val synExprContainsError: inpExpr:SynExpr -> bool

val ( |ParsedHashDirectiveArguments| ) : ParsedHashDirectiveArgument list -> string list
18 changes: 9 additions & 9 deletions src/fsharp/fsi/fsi.fs
Original file line number Diff line number Diff line change
Expand Up @@ -2223,26 +2223,26 @@ type internal FsiInteractionProcessor
let istate = fsiDynamicCompiler.CommitDependencyManagerText(ctok, istate, lexResourceManager, errorLogger)
fsiDynamicCompiler.EvalParsedDefinitions (ctok, errorLogger, istate, true, false, defs)

| ParsedScriptInteraction.HashDirective (ParsedHashDirective("load", sourceFiles, m), _) ->
| ParsedScriptInteraction.HashDirective (ParsedHashDirective("load", ParsedHashDirectiveArguments sourceFiles, m), _) ->
let istate = fsiDynamicCompiler.CommitDependencyManagerText(ctok, istate, lexResourceManager, errorLogger)
fsiDynamicCompiler.EvalSourceFiles (ctok, istate, m, sourceFiles, lexResourceManager, errorLogger),Completed None

| ParsedScriptInteraction.HashDirective (ParsedHashDirective(("reference" | "r"), [path], m), _) ->
| ParsedScriptInteraction.HashDirective (ParsedHashDirective(("reference" | "r"), ParsedHashDirectiveArguments [path], m), _) ->
packageManagerDirective Directive.Resolution path m

| ParsedScriptInteraction.HashDirective (ParsedHashDirective("i", [path], m), _) ->
| ParsedScriptInteraction.HashDirective (ParsedHashDirective("i", ParsedHashDirectiveArguments [path], m), _) ->
packageManagerDirective Directive.Include path m

| ParsedScriptInteraction.HashDirective (ParsedHashDirective("I", [path], m), _) ->
| ParsedScriptInteraction.HashDirective (ParsedHashDirective("I", ParsedHashDirectiveArguments [path], m), _) ->
tcConfigB.AddIncludePath (m, path, tcConfig.implicitIncludeDir)
fsiConsoleOutput.uprintnfnn "%s" (FSIstrings.SR.fsiDidAHashI(tcConfig.MakePathAbsolute path))
istate, Completed None

| ParsedScriptInteraction.HashDirective (ParsedHashDirective("cd", [path], m), _) ->
| ParsedScriptInteraction.HashDirective (ParsedHashDirective("cd", ParsedHashDirectiveArguments [path], m), _) ->
ChangeDirectory path m
istate, Completed None

| ParsedScriptInteraction.HashDirective (ParsedHashDirective("silentCd", [path], m), _) ->
| ParsedScriptInteraction.HashDirective (ParsedHashDirective("silentCd", ParsedHashDirectiveArguments [path], m), _) ->
ChangeDirectory path m
fsiConsolePrompt.SkipNext() (* "silent" directive *)
istate, Completed None
Expand All @@ -2257,14 +2257,14 @@ type internal FsiInteractionProcessor
fsiConsoleOutput.uprintnfnn "%s" (FSIstrings.SR.fsiTurnedTimingOn())
{istate with timing = not istate.timing}, Completed None

| ParsedScriptInteraction.HashDirective (ParsedHashDirective("time", [("on" | "off") as v], _), _) ->
| ParsedScriptInteraction.HashDirective (ParsedHashDirective("time", ParsedHashDirectiveArguments [("on" | "off") as v], _), _) ->
if v <> "on" then
fsiConsoleOutput.uprintnfnn "%s" (FSIstrings.SR.fsiTurnedTimingOff())
else
fsiConsoleOutput.uprintnfnn "%s" (FSIstrings.SR.fsiTurnedTimingOn())
{istate with timing = (v = "on")}, Completed None

| ParsedScriptInteraction.HashDirective (ParsedHashDirective("nowarn", numbers, m), _) ->
| ParsedScriptInteraction.HashDirective (ParsedHashDirective("nowarn", ParsedHashDirectiveArguments numbers, m), _) ->
List.iter (fun (d:string) -> tcConfigB.TurnWarningOff(m, d)) numbers
istate, Completed None

Expand Down Expand Up @@ -2293,7 +2293,7 @@ type internal FsiInteractionProcessor
fsiOptions.ShowHelp(m)
istate, Completed None

| ParsedScriptInteraction.HashDirective (ParsedHashDirective(c, arg, m), _) ->
| ParsedScriptInteraction.HashDirective (ParsedHashDirective(c, ParsedHashDirectiveArguments arg, m), _) ->
warning(Error((FSComp.SR.fsiInvalidDirective(c, String.concat " " arg)), m))
istate, Completed None
)
Expand Down
11 changes: 7 additions & 4 deletions src/fsharp/pars.fsy
Original file line number Diff line number Diff line change
Expand Up @@ -649,11 +649,14 @@ hashDirectiveArgs:


/* One argument to a #directive */
hashDirectiveArg:
hashDirectiveArg:
| string
{ let s, _ = $1
s }

{ let s, kind = $1
ParsedHashDirectiveArgument.String (s, kind, lhs parseState) }
| sourceIdentifier
{ let c,v = $1
ParsedHashDirectiveArgument.SourceIdentifier (c, v, lhs parseState) }


/*--------------------------------------------------------------------------*/
/* F# Language Proper - signature files */
Expand Down
35 changes: 32 additions & 3 deletions tests/FSharp.Compiler.Service.Tests/SurfaceArea.netstandard.fs
Original file line number Diff line number Diff line change
Expand Up @@ -5353,16 +5353,45 @@ FSharp.Compiler.Syntax.LongIdentWithDots: Microsoft.FSharp.Collections.FSharpLis
FSharp.Compiler.Syntax.LongIdentWithDots: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Text.Range] get_dotRanges()
FSharp.Compiler.Syntax.LongIdentWithDots: System.String ToString()
FSharp.Compiler.Syntax.ParsedHashDirective
FSharp.Compiler.Syntax.ParsedHashDirective: FSharp.Compiler.Syntax.ParsedHashDirective NewParsedHashDirective(System.String, Microsoft.FSharp.Collections.FSharpList`1[System.String], FSharp.Compiler.Text.Range)
FSharp.Compiler.Syntax.ParsedHashDirective: FSharp.Compiler.Syntax.ParsedHashDirective NewParsedHashDirective(System.String, Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.ParsedHashDirectiveArgument], FSharp.Compiler.Text.Range)
FSharp.Compiler.Syntax.ParsedHashDirective: FSharp.Compiler.Text.Range get_range()
FSharp.Compiler.Syntax.ParsedHashDirective: FSharp.Compiler.Text.Range range
FSharp.Compiler.Syntax.ParsedHashDirective: Int32 Tag
FSharp.Compiler.Syntax.ParsedHashDirective: Int32 get_Tag()
FSharp.Compiler.Syntax.ParsedHashDirective: Microsoft.FSharp.Collections.FSharpList`1[System.String] args
FSharp.Compiler.Syntax.ParsedHashDirective: Microsoft.FSharp.Collections.FSharpList`1[System.String] get_args()
FSharp.Compiler.Syntax.ParsedHashDirective: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.ParsedHashDirectiveArgument] args
FSharp.Compiler.Syntax.ParsedHashDirective: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.ParsedHashDirectiveArgument] get_args()
FSharp.Compiler.Syntax.ParsedHashDirective: System.String ToString()
FSharp.Compiler.Syntax.ParsedHashDirective: System.String get_ident()
FSharp.Compiler.Syntax.ParsedHashDirective: System.String ident
FSharp.Compiler.Syntax.ParsedHashDirectiveArgument
FSharp.Compiler.Syntax.ParsedHashDirectiveArgument+SourceIdentifier: FSharp.Compiler.Text.Range get_range()
FSharp.Compiler.Syntax.ParsedHashDirectiveArgument+SourceIdentifier: FSharp.Compiler.Text.Range range
FSharp.Compiler.Syntax.ParsedHashDirectiveArgument+SourceIdentifier: System.String constant
FSharp.Compiler.Syntax.ParsedHashDirectiveArgument+SourceIdentifier: System.String get_constant()
FSharp.Compiler.Syntax.ParsedHashDirectiveArgument+SourceIdentifier: System.String get_value()
FSharp.Compiler.Syntax.ParsedHashDirectiveArgument+SourceIdentifier: System.String value
FSharp.Compiler.Syntax.ParsedHashDirectiveArgument+String: FSharp.Compiler.Syntax.SynStringKind get_stringKind()
FSharp.Compiler.Syntax.ParsedHashDirectiveArgument+String: FSharp.Compiler.Syntax.SynStringKind stringKind
FSharp.Compiler.Syntax.ParsedHashDirectiveArgument+String: FSharp.Compiler.Text.Range get_range()
FSharp.Compiler.Syntax.ParsedHashDirectiveArgument+String: FSharp.Compiler.Text.Range range
FSharp.Compiler.Syntax.ParsedHashDirectiveArgument+String: System.String get_value()
FSharp.Compiler.Syntax.ParsedHashDirectiveArgument+String: System.String value
FSharp.Compiler.Syntax.ParsedHashDirectiveArgument+Tags: Int32 SourceIdentifier
FSharp.Compiler.Syntax.ParsedHashDirectiveArgument+Tags: Int32 String
FSharp.Compiler.Syntax.ParsedHashDirectiveArgument: Boolean IsSourceIdentifier
FSharp.Compiler.Syntax.ParsedHashDirectiveArgument: Boolean IsString
FSharp.Compiler.Syntax.ParsedHashDirectiveArgument: Boolean get_IsSourceIdentifier()
FSharp.Compiler.Syntax.ParsedHashDirectiveArgument: Boolean get_IsString()
FSharp.Compiler.Syntax.ParsedHashDirectiveArgument: FSharp.Compiler.Syntax.ParsedHashDirectiveArgument NewSourceIdentifier(System.String, System.String, FSharp.Compiler.Text.Range)
FSharp.Compiler.Syntax.ParsedHashDirectiveArgument: FSharp.Compiler.Syntax.ParsedHashDirectiveArgument NewString(System.String, FSharp.Compiler.Syntax.SynStringKind, FSharp.Compiler.Text.Range)
FSharp.Compiler.Syntax.ParsedHashDirectiveArgument: FSharp.Compiler.Syntax.ParsedHashDirectiveArgument+SourceIdentifier
FSharp.Compiler.Syntax.ParsedHashDirectiveArgument: FSharp.Compiler.Syntax.ParsedHashDirectiveArgument+String
FSharp.Compiler.Syntax.ParsedHashDirectiveArgument: FSharp.Compiler.Syntax.ParsedHashDirectiveArgument+Tags
FSharp.Compiler.Syntax.ParsedHashDirectiveArgument: FSharp.Compiler.Text.Range Range
FSharp.Compiler.Syntax.ParsedHashDirectiveArgument: FSharp.Compiler.Text.Range get_Range()
FSharp.Compiler.Syntax.ParsedHashDirectiveArgument: Int32 Tag
FSharp.Compiler.Syntax.ParsedHashDirectiveArgument: Int32 get_Tag()
FSharp.Compiler.Syntax.ParsedHashDirectiveArgument: System.String ToString()
FSharp.Compiler.Syntax.ParsedImplFile
FSharp.Compiler.Syntax.ParsedImplFile: FSharp.Compiler.Syntax.ParsedImplFile NewParsedImplFile(Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.ParsedHashDirective], Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.ParsedImplFileFragment])
FSharp.Compiler.Syntax.ParsedImplFile: Int32 Tag
Expand Down
57 changes: 57 additions & 0 deletions tests/service/Symbols.fs
Original file line number Diff line number Diff line change
Expand Up @@ -1153,4 +1153,61 @@ type Bird =
assertRange (3, 4) (6, 50) getter.Range
assertRange (3, 4) (6, 23) mb2
assertRange (3, 4) (6, 50) setter.Range
| _ -> Assert.Fail "Could not get valid AST"

module ParsedHashDirective =
[<Test>]
let ``SourceIdentifier as ParsedHashDirectiveArgument`` () =
let parseResults =
getParseResults
"#I __SOURCE_DIRECTORY__"

match parseResults with
| ParsedInput.ImplFile (ParsedImplFileInput (modules = [ SynModuleOrNamespace.SynModuleOrNamespace(decls = [
SynModuleDecl.HashDirective(ParsedHashDirective("I", [ ParsedHashDirectiveArgument.SourceIdentifier(c,_,m) ] , _), _)
]) ])) ->
Assert.AreEqual("__SOURCE_DIRECTORY__", c)
assertRange (1, 3) (1, 23) m
| _ -> Assert.Fail "Could not get valid AST"

[<Test>]
let ``Regular String as ParsedHashDirectiveArgument`` () =
let parseResults =
getParseResults
"#I \"/tmp\""

match parseResults with
| ParsedInput.ImplFile (ParsedImplFileInput (modules = [ SynModuleOrNamespace.SynModuleOrNamespace(decls = [
SynModuleDecl.HashDirective(ParsedHashDirective("I", [ ParsedHashDirectiveArgument.String(v, SynStringKind.Regular, m) ] , _), _)
]) ])) ->
Assert.AreEqual("/tmp", v)
assertRange (1, 3) (1, 9) m
| _ -> Assert.Fail "Could not get valid AST"

[<Test>]
let ``Verbatim String as ParsedHashDirectiveArgument`` () =
let parseResults =
getParseResults
"#I @\"C:\\Temp\""

match parseResults with
| ParsedInput.ImplFile (ParsedImplFileInput (modules = [ SynModuleOrNamespace.SynModuleOrNamespace(decls = [
SynModuleDecl.HashDirective(ParsedHashDirective("I", [ ParsedHashDirectiveArgument.String(v, SynStringKind.Verbatim, m) ] , _), _)
]) ])) ->
Assert.AreEqual("C:\\Temp", v)
assertRange (1, 3) (1, 13) m
| _ -> Assert.Fail "Could not get valid AST"

[<Test>]
let ``Triple quote String as ParsedHashDirectiveArgument`` () =
let parseResults =
getParseResults
"#nowarn \"\"\"40\"\"\""

match parseResults with
| ParsedInput.ImplFile (ParsedImplFileInput (modules = [ SynModuleOrNamespace.SynModuleOrNamespace(decls = [
SynModuleDecl.HashDirective(ParsedHashDirective("nowarn", [ ParsedHashDirectiveArgument.String(v, SynStringKind.TripleQuote, m) ] , _), _)
]) ])) ->
Assert.AreEqual("40", v)
assertRange (1, 8) (1, 16) m
| _ -> Assert.Fail "Could not get valid AST"