Hacktoberfest 2026: những issue maintainer đã đánh dấu cho tháng Mười, đang mở và phù hợp người mới. Xem issue Hacktoberfest

Transparent Compiler: check a single file using only its dependency subgraph

Đang mở
#20,850 0 bình luận 0 reaction 0 người được giao Xem trên GitHub

Maintainer thường phản hồi trong vòng 3 ngày

Chưa có ai nhận issue này.

Đánh giá

Độ khó
5/5
Thời gian dự kiến
Hơn một tuần
Mức phù hợp với người mới
35/100
Loại issue
Tính năng
Độ rõ ràng
Khá rõ ràng
Mức độ hoạt động
Sôi nổi
Công nghệ
fsharp
Lĩnh vực
compilers

Hướng nghiên cứu

Start with ComputeDependencyGraphForFile in src/Compiler/Service/TransparentCompiler.fs and the Transparent Compiler tests in tests/FSharp.Compiler.ComponentTests/FSharpChecker/TransparentCompiler.fs; the issue links the relevant code and test cases. First investigate why dependency-subgraph checking and the cache tests were disabled, including the TODO about complete versus minimal checking. Done means an opt-in single-file check uses its dependency subgraph while the full check remains the default, with correctness and cache behavior covered by tests.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Mô tả

Needs-Triage

Is your feature request related to a problem? Please describe.

When the Transparent Compiler checks a single file, it type checks every file before it. It does not limit itself to the files that file depends on in the graph.

ComputeDependencyGraphForFile builds the graph for all prior files. The line that would trim it to the target file is commented out:

let ComputeDependencyGraphForFile (tcConfig: TcConfig) (priorSnapshot: ProjectSnapshotBase<FSharpParsedFile>) =
    let key = priorSnapshot.SourceFiles.Key(DependencyGraphType.File)
    //let lastFileIndex = (parsedInputs |> Array.length) - 1
    //caches.DependencyGraph.Get(key, computeDependencyGraph parsedInputs (Graph.subGraphFor lastFileIndex))
    caches.DependencyGraph.Get(
        key,
        computeDependencyGraph
            tcConfig
            (priorSnapshot.SourceFiles |> Seq.map (fun f -> f.ParsedInput))
            (removeImplFilesThatHaveSignatures true priorSnapshot)
    )

processGraphAsync then runs every node. So the graph only decides what can run in parallel, not what gets checked.

Our use case

Telplin generates signature files from the typed tree. A common request is to generate the signature of a single file: telplin MyProject.fsproj --files Api.fs. For that we only need the FSharpCheckFileResults of Api.fs with correct types. The types of a file depend only on the files it references, so the dependency subgraph would be enough. Today, generating the signature of a file near the end of a large project costs nearly as much as checking the whole project.

Telplin is switching to the Transparent Compiler, partly to help dogfood it. Without the subgraph, a single file gains only from the parallelism.

Measurements

FCS 43.12.401, FSharpChecker.ParseAndCheckFileInProject (options overload), a new checker for each check. The synthetic project has 30 independent files (F01.fs to F30.fs, about 750 declarations each) and a Last.fs that only uses F01:

module Lib.Last

let value = Lib.F01.f1 1
File checked BackgroundCompiler TransparentCompiler
F01.fs (first file) 732 ms 720 ms
F02.fs 1429 ms 953 ms
Last.fs (depends on F01 only) 20145 ms 12186 ms

With the subgraph, Last.fs would cost about as much as F02.fs, roughly 1 s instead of 12 s.

History

As far as I could trace it:

  • In the experiment branches of #15179 the subgraph was active. It was replaced by removeImplFilesThatHaveSignaturesExceptLastOne in 0101/fsharp@0a35243068ff179a6d8445aa1951b4f7840b1ffd (2023-07-24, commit message "stuff"). That commit gives no reason.
  • 0101/fsharp@0b2897d6582648e7fe3bfae9994a7fbad35b3ccf (2023-11-15, "test todos") disabled We don't check files that are not depended on and the two Files that are not depended on don't invalidate cache tests with TODO: differentiate complete and minimal checking requests.
  • #17966 re-enabled the first test, but its key assertion is still commented out: // check "FileSecond.fs" [] // TODO: assert does not hold.. The two cache tests are still skipped.

Questions

  1. Why was the subgraph commented out? I'm guessing that "complete vs minimal" refers to check results that need the full TcEnv of every prior file. For example, completion in the target file should list modules from files it does not reference yet. Is that the reason, or was there a correctness problem (for example one found by the Giraffe fuzzing test, which the same July commit re-enabled with a fixed seed)?
  2. Would you accept an opt-in "minimal" check of a single file, where only the target's dependency subgraph is type checked? For example a parameter on ParseAndCheckFileInProject or on the snapshot API, or a checker option. Tools like Telplin, analyzers and code generators only need the target file's own typed tree.

Describe the solution you'd like

A way to ask the Transparent Compiler to check one file using only its dependency subgraph, with the full check staying the default.

Describe alternatives you've considered

  • Building a trimmed FSharpProjectOptions ourselves that lists only the target's dependencies. That means reimplementing the dependency resolution of graph-based checking, which is internal.
  • Checking the whole project, which is what we do now.
Ngôn ngữ chính
F#
Star
4.3k
Fork
882
Merge trung bình
4 ngày 13 giờ
Pull request đã merge (30 ngày)
138

Chuẩn bị môi trường

Mở trong Codespaces

Khởi chạy dev container của dự án ngay trên trình duyệt, bằng tài khoản GitHub của bạn.

Bắt đầu từ đâu

  1. Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
  2. Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
  3. Fork repository và làm thay đổi trên một nhánh.
  4. Mở pull request có tham chiếu số hiệu của issue.

Issue khác của dotnet/fsharp

Tất cả issue của dotnet/fsharp

Issue tương tự

Thêm issue về Compilers

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.