Feature/shared jdt compilation environment#153
Merged
Conversation
…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>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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:
(mirrors createParser() but omits per-file settings: setSource, setUnitName,
setKind, which are invalid / ignored in batch mode).
returns an absolute-path → CompilationUnit map; the environment is initialised
once regardless of how many files are in the batch.
CU without any additional setEnvironment() call, then runs import cleanup.
the progress denominator, preserving existing progress-reporting behaviour.
futures, matching the existing per-file error-surfacing contract.
parse phase; by the time worker threads read those bindings the LookupEnvironment
is no longer being written, so concurrent reads are safe.