Skip to content

Commit

Permalink
Dependent signature files (#3769)
Browse files Browse the repository at this point in the history
* Log dependent files of script.

* Ensure a type is not exported when it is hidden by a signature file.

* Use signature file to determine dependent files in compileFileToJavaScript.

* Don't wait indefinitely to build plugin.

* Add changelog entries.
  • Loading branch information
nojaf authored Feb 26, 2024
1 parent c209b64 commit f490275
Show file tree
Hide file tree
Showing 10 changed files with 97 additions and 12 deletions.
10 changes: 10 additions & 0 deletions src/Fable.Cli/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## Unreleased

### Fixed

#### All

* [GH-3769](https://github.com/fable-compiler/Fable/pull/3769) Local plugin build does not run indefinably. (by @nojaf)

#### JavaScript

* [GH-3769](https://github.com/fable-compiler/Fable/pull/3769) Types hidden by signature files should not be exported. (by @nojaf)

## 4.13.0 - 2024-02-13

### Added
Expand Down
5 changes: 5 additions & 0 deletions src/Fable.Compiler/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## Unreleased

### Fixed

* [GH-3769](https://github.com/fable-compiler/Fable/pull/3769) The dependent files of the current file should be detected for the signature file if there is one present. (by @nojaf)
* [GH-3769](https://github.com/fable-compiler/Fable/pull/3769) Local plugin build does not run indefinably. (by @nojaf)

## 4.0.0-alpha-007 - 2024-02-20

### Added
Expand Down
17 changes: 16 additions & 1 deletion src/Fable.Compiler/Library.fs
Original file line number Diff line number Diff line change
Expand Up @@ -260,8 +260,23 @@ module CodeServices =
: Async<CompileResult>
=
async {
let signatureFile =
crackerResponse.ProjectOptions.SourceFiles
|> Array.tryFind (fun f -> f = String.Concat(currentFile, "i"))

let! dependentFiles =
checker.GetDependentFiles(currentFile, crackerResponse.ProjectOptions.SourceFiles, sourceReader)
match signatureFile with
| None ->
checker.GetDependentFiles(currentFile, crackerResponse.ProjectOptions.SourceFiles, sourceReader)
| Some signatureFile ->
checker.GetDependentFiles(signatureFile, crackerResponse.ProjectOptions.SourceFiles, sourceReader)

Log.info (
sprintf
"Dependent files for %s are:\n%s"
(Option.defaultValue currentFile signatureFile)
(String.concat "\n" dependentFiles)
)

let lastFile =
if Array.isEmpty dependentFiles then
Expand Down
4 changes: 3 additions & 1 deletion src/Fable.Compiler/Util.fs
Original file line number Diff line number Diff line change
Expand Up @@ -460,7 +460,9 @@ module Process =

let runSyncWithOutput workingDir exePath args =
let p = startProcess true [] workingDir exePath args
p.WaitForExit()
// Don't wait indefinitely to run process
// This call is used to build local plugins, if the binary is used by another process this process will never end.
p.WaitForExit 7000 |> ignore
p.StandardOutput.ReadToEnd()

[<RequireQualifiedAccess>]
Expand Down
30 changes: 22 additions & 8 deletions src/Fable.Transforms/FSharp2Fable.Util.fs
Original file line number Diff line number Diff line change
Expand Up @@ -466,8 +466,12 @@ type FsEnt(maybeAbbrevEnt: FSharpEntity) =
member _.UnionCases =
ent.UnionCases |> Seq.mapToList (fun x -> FsUnionCase(x) :> Fable.UnionCase)

member _.IsPublic = not ent.Accessibility.IsPrivate
member _.IsPrivate = ent.Accessibility.IsPrivate
member _.IsPublic =
not (ent.Accessibility.IsPrivate || Helpers.typeIsHiddenBySignatureFile ent)

member _.IsPrivate =
ent.Accessibility.IsPrivate || Helpers.typeIsHiddenBySignatureFile ent

member _.IsInternal = ent.Accessibility.IsInternal
member _.IsAbstractClass = ent.IsAbstractClass
member _.IsNamespace = ent.IsNamespace
Expand Down Expand Up @@ -822,14 +826,24 @@ module Helpers =
| FSharpInlineAnnotation.AlwaysInline
| FSharpInlineAnnotation.AggressiveInline -> true

let parentHasSignatureFile (declaringEntity: FSharpEntity option) =
declaringEntity
|> Option.bind (fun p -> p.SignatureLocation)
|> Option.map (fun m -> m.FileName.EndsWith(".fsi", StringComparison.Ordinal))
|> Option.defaultValue false

let topLevelBindingHiddenBySignatureFile (v: FSharpMemberOrFunctionOrValue) =
let parentHasSignatureFile () =
v.DeclaringEntity
|> Option.bind (fun p -> p.SignatureLocation)
|> Option.map (fun m -> m.FileName.EndsWith(".fsi", StringComparison.Ordinal))
|> Option.defaultValue false
v.IsModuleValueOrMember
&& not v.HasSignatureFile
&& parentHasSignatureFile v.DeclaringEntity

let typeIsHiddenBySignatureFile (ent: FSharpEntity) : bool =
let hasOwnSignatureFile =
match ent.SignatureLocation with
| None -> false
| Some m -> m.FileName.EndsWith(".fsi", StringComparison.Ordinal)

v.IsModuleValueOrMember && not v.HasSignatureFile && parentHasSignatureFile ()
not hasOwnSignatureFile && parentHasSignatureFile ent.DeclaringEntity

let isNotPrivate (memb: FSharpMemberOrFunctionOrValue) =
if memb.IsCompilerGenerated then
Expand Down
4 changes: 2 additions & 2 deletions tests/Integration/Integration/CompilationTests.fs
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ let tests =
for expected in Directory.GetFileSystemEntries(testCaseDir, "*.expected") do
let actual = Path.ChangeExtension(expected, ".actual")
Expect.isTrue (File.Exists actual) $"No actual file was produced for {expected}"
let expectedContent = File.ReadAllText expected
let actualContent = File.ReadAllText actual
let expectedContent = File.ReadAllText expected |> _.ReplaceLineEndings()
let actualContent = File.ReadAllText actual |> _.ReplaceLineEndings()
Expect.equal actualContent expectedContent "The expected content differs from the actual content"

return ()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
module HideType

open Fable.Core

/// This type should be hidden by the signature file
type public Foobar =
| Foo of int
| Bar of string

let someFunction () =
JS.console.log "meh"
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module HideType

val someFunction: unit -> unit
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { Union } from "./fable_modules/fable-library-js.4.13.0/Types.js";
import { union_type, string_type, int32_type } from "./fable_modules/fable-library-js.4.13.0/Reflection.js";
import { some } from "./fable_modules/fable-library-js.4.13.0/Option.js";

class Foobar extends Union {
constructor(tag, fields) {
super();
this.tag = tag;
this.fields = fields;
}
cases() {
return ["Foo", "Bar"];
}
}

function Foobar_$reflection() {
return union_type("HideType.Foobar", [], Foobar, () => [[["Item", int32_type]], [["Item", string_type]]]);
}

export function someFunction() {
console.log(some("meh"));
}

Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
<ItemGroup>
<Compile Include="Library.fsi" />
<Compile Include="Library.fs" />
<Compile Include="HideType.fsi" />
<Compile Include="HideType.fs" />
</ItemGroup>

<ItemGroup>
Expand Down

0 comments on commit f490275

Please sign in to comment.