Skip to content

Feature/shared jdt compilation environment#153

Merged
RadikalJin merged 8 commits into
mainfrom
feature/shared-jdt-compilation-environment
Jun 10, 2026
Merged

Feature/shared jdt compilation environment#153
RadikalJin merged 8 commits into
mainfrom
feature/shared-jdt-compilation-environment

Conversation

@RadikalJin

@RadikalJin RadikalJin commented Jun 10, 2026

Copy link
Copy Markdown
Member

ASTParser.setEnvironment() triggers full classpath scanning (JAR index loading,
type-environment initialisation) on every invocation. With the previous per-file
parse loop each file paid that cost independently, making it O(N) in the number
of files even when the classpath never changes between files.

This change replaces the per-file createAST() calls inside runOperations() with a
single ASTParser.createASTs() batch call that sets up the JDT LookupEnvironment
exactly once for the entire run. Files are collected and content-prefiltered on
the main thread before the batch parse; the resulting CompilationUnit objects are
then dispatched to the existing parallel ExecutorService for concurrent operation
application — so the classpath-amortisation benefit composes cleanly with the
parallel-processing feature.

Key design decisions:

  • AstraUtils.createBatchParser() encapsulates the shared-environment parser setup
    (mirrors createParser() but omits per-file settings: setSource, setUnitName,
    setKind, which are invalid / ignored in batch mode).
  • batchParseFiles() in AstraCore calls createASTs() via FileASTRequestor and
    returns an absolute-path → CompilationUnit map; the environment is initialised
    once regardless of how many files are in the batch.
  • applyOperationsAndSaveWithPreParsedCU() applies operations on the already-parsed
    CU without any additional setEnvironment() call, then runs import cleanup.
  • Content-prefiltered files have no-op futures submitted so they still count toward
    the progress denominator, preserving existing progress-reporting behaviour.
  • Files that could not be read before batch parsing surface as RuntimeException
    futures, matching the existing per-file error-surfacing contract.
  • Thread safety: createASTs() resolves all bindings eagerly during the sequential
    parse phase; by the time worker threads read those bindings the LookupEnvironment
    is no longer being written, so concurrent reads are safe.

RadikalJin and others added 8 commits June 1, 2026 10:50
…ment

ASTParser.setEnvironment() triggers full classpath scanning (JAR index loading,
type-environment initialisation) on every invocation.  With the previous per-file
parse loop each file paid that cost independently, making it O(N) in the number
of files even when the classpath never changes between files.

This change replaces the per-file createAST() calls inside runOperations() with a
single ASTParser.createASTs() batch call that sets up the JDT LookupEnvironment
exactly once for the entire run.  Files are collected and content-prefiltered on
the main thread before the batch parse; the resulting CompilationUnit objects are
then dispatched to the existing parallel ExecutorService for concurrent operation
application — so the classpath-amortisation benefit composes cleanly with the
parallel-processing feature.

Key design decisions:
- AstraUtils.createBatchParser() encapsulates the shared-environment parser setup
  (mirrors createParser() but omits per-file settings: setSource, setUnitName,
  setKind, which are invalid / ignored in batch mode).
- batchParseFiles() in AstraCore calls createASTs() via FileASTRequestor and
  returns an absolute-path → CompilationUnit map; the environment is initialised
  once regardless of how many files are in the batch.
- applyOperationsAndSaveWithPreParsedCU() applies operations on the already-parsed
  CU without any additional setEnvironment() call, then runs import cleanup.
- Content-prefiltered files have no-op futures submitted so they still count toward
  the progress denominator, preserving existing progress-reporting behaviour.
- Files that could not be read before batch parsing surface as RuntimeException
  futures, matching the existing per-file error-surfacing contract.
- Thread safety: createASTs() resolves all bindings eagerly during the sequential
  parse phase; by the time worker threads read those bindings the LookupEnvironment
  is no longer being written, so concurrent reads are safe.

Adds TestAstraCoreSharedEnvironment covering: all-files visited, binding resolution
correctness, content-prefiltering integration, parallel + batch composability, and
per-file error isolation.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…aVersion()

AST.JLS17 and the hardcoded JavaCore.VERSION_17 are both deprecated in JDT 3.45.0
(the latest available release).  The recommended replacements are:

  AST.getJLSLatest()             — currently returns JLS25 (Java 25)
  JavaCore.latestSupportedJavaVersion() — currently returns "25"

Switching to these dynamic accessors means:
- The @SuppressWarnings("deprecation") annotations and their cause are removed.
- Astra can parse Java 18–25 source syntax (records, sealed classes, pattern
  matching for switch, virtual threads, etc.) that JLS17 would reject or silently
  misparse.
- When JDT is updated to support future JLS levels the parser and compliance
  options automatically follow without any code change.

No behaviour change for existing Java 17 (or earlier) source trees: JLS25 is a
strict superset of all earlier JLS levels.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ment

ASTParser.setEnvironment() triggers full classpath scanning (JAR index loading,
type-environment initialisation) on every invocation.  With the previous per-file
parse loop each file paid that cost independently, making it O(N) in the number
of files even when the classpath never changes between files.

This change replaces the per-file createAST() calls inside runOperations() with a
single ASTParser.createASTs() batch call that sets up the JDT LookupEnvironment
exactly once for the entire run.  Files are collected and content-prefiltered on
the main thread before the batch parse; the resulting CompilationUnit objects are
then dispatched to the existing parallel ExecutorService for concurrent operation
application — so the classpath-amortisation benefit composes cleanly with the
parallel-processing feature.

Key design decisions:
- AstraUtils.createBatchParser() encapsulates the shared-environment parser setup
  (mirrors createParser() but omits per-file settings: setSource, setUnitName,
  setKind, which are invalid / ignored in batch mode).
- batchParseFiles() in AstraCore calls createASTs() via FileASTRequestor and
  returns an absolute-path → CompilationUnit map; the environment is initialised
  once regardless of how many files are in the batch.
- applyOperationsAndSaveWithPreParsedCU() applies operations on the already-parsed
  CU without any additional setEnvironment() call, then runs import cleanup.
- Content-prefiltered files have no-op futures submitted so they still count toward
  the progress denominator, preserving existing progress-reporting behaviour.
- Files that could not be read before batch parsing surface as RuntimeException
  futures, matching the existing per-file error-surfacing contract.
- Thread safety: createASTs() resolves all bindings eagerly during the sequential
  parse phase; by the time worker threads read those bindings the LookupEnvironment
  is no longer being written, so concurrent reads are safe.

Adds TestAstraCoreSharedEnvironment covering: all-files visited, binding resolution
correctness, content-prefiltering integration, parallel + batch composability, and
per-file error isolation.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@RadikalJin RadikalJin merged commit df41e59 into main Jun 10, 2026
2 checks passed
@RadikalJin RadikalJin deleted the feature/shared-jdt-compilation-environment branch June 10, 2026 10:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant