001/* 002 * Copyright (C) 2022 - 2024, the original author or authors. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package io.github.ascopes.jct.compilers; 017 018import static io.github.ascopes.jct.utils.IterableUtils.requireAtLeastOne; 019 020import io.github.ascopes.jct.ex.JctCompilerException; 021import io.github.ascopes.jct.filemanagers.AnnotationProcessorDiscovery; 022import io.github.ascopes.jct.filemanagers.LoggingMode; 023import io.github.ascopes.jct.workspaces.Workspace; 024import java.io.UncheckedIOException; 025import java.nio.charset.Charset; 026import java.nio.charset.StandardCharsets; 027import java.util.Collection; 028import java.util.List; 029import java.util.Locale; 030import java.util.Set; 031import javax.annotation.processing.Processor; 032import javax.lang.model.SourceVersion; 033import org.jspecify.annotations.Nullable; 034 035/** 036 * Base definition of a compiler that can be configured to perform a compilation run against 037 * sources. 038 * 039 * <p>JctCompiler objects are often a nexus that will manage configuring an underlying JSR-199 040 * compiler internally in a platform-agnostic way. 041 * 042 * @author Ashley Scopes 043 * @since 0.0.1 044 */ 045public interface JctCompiler { 046 047 /** 048 * Default setting for deprecation warnings ({@code true}). 049 */ 050 boolean DEFAULT_SHOW_DEPRECATION_WARNINGS = true; 051 052 /** 053 * Default setting for locale ({@link Locale#ROOT}). 054 */ 055 Locale DEFAULT_LOCALE = Locale.ROOT; 056 057 /** 058 * Default setting for preview features ({@code false}). 059 */ 060 boolean DEFAULT_PREVIEW_FEATURES = false; 061 062 /** 063 * Default setting for verbose logging ({@code false}). 064 */ 065 boolean DEFAULT_VERBOSE = false; 066 067 /** 068 * Default setting for displaying warnings ({@code true}). 069 */ 070 boolean DEFAULT_SHOW_WARNINGS = true; 071 072 /** 073 * Default setting for displaying warnings as errors ({@code false}). 074 */ 075 boolean DEFAULT_FAIL_ON_WARNINGS = false; 076 077 /** 078 * Default setting for fixing modules being placed on the classpath by mistake ({@code true}). 079 */ 080 boolean DEFAULT_FIX_JVM_MODULE_PATH_MISMATCH = true; 081 082 /** 083 * Default setting for inclusion of the current class path ({@code true}). 084 */ 085 boolean DEFAULT_INHERIT_CLASS_PATH = true; 086 087 /** 088 * Default setting for inclusion of the current module path ({@code true}). 089 */ 090 boolean DEFAULT_INHERIT_MODULE_PATH = true; 091 092 /** 093 * Default setting for inclusion of the system module path ({@code true}). 094 */ 095 boolean DEFAULT_INHERIT_SYSTEM_MODULE_PATH = true; 096 097 /** 098 * Default setting for logging file manager operations ({@link LoggingMode#DISABLED}). 099 */ 100 LoggingMode DEFAULT_FILE_MANAGER_LOGGING_MODE = LoggingMode.DISABLED; 101 102 /** 103 * Default setting for logging diagnostics ({@link LoggingMode#ENABLED}). 104 */ 105 LoggingMode DEFAULT_DIAGNOSTIC_LOGGING_MODE = LoggingMode.ENABLED; 106 107 /** 108 * Default setting for the compilation mode to use 109 * ({@link CompilationMode#COMPILATION_AND_ANNOTATION_PROCESSING}). 110 */ 111 CompilationMode DEFAULT_COMPILATION_MODE = CompilationMode.COMPILATION_AND_ANNOTATION_PROCESSING; 112 113 /** 114 * Default setting for how to apply annotation processor discovery when no processors are 115 * explicitly defined ({@link AnnotationProcessorDiscovery#INCLUDE_DEPENDENCIES}). 116 */ 117 AnnotationProcessorDiscovery DEFAULT_ANNOTATION_PROCESSOR_DISCOVERY = 118 AnnotationProcessorDiscovery.INCLUDE_DEPENDENCIES; 119 120 /** 121 * Default charset to use for compiler logs ({@link StandardCharsets#UTF_8}). 122 */ 123 Charset DEFAULT_LOG_CHARSET = StandardCharsets.UTF_8; 124 125 /** 126 * Default debugging info to include in the compilation (all possible info). 127 */ 128 Set<DebuggingInfo> DEFAULT_DEBUGGING_INFO = DebuggingInfo.all(); 129 130 /** 131 * Default preference for including reflective parameter information in compiled classes 132 * ({@code true}). 133 */ 134 boolean DEFAULT_PARAMETER_INFO_ENABLED = true; 135 136 /** 137 * Invoke the compilation and return the compilation result. 138 * 139 * <p>The actual classes to compile will be dynamically discovered. If you wish to 140 * specify the specific classes to compile, see {@link #compile(Workspace, String...)} or 141 * {@link #compile(Workspace, Collection)}. 142 * 143 * @param workspace the workspace to compile. 144 * @return the compilation result. 145 * @throws JctCompilerException if the compiler threw an unhandled exception. This should not 146 * occur for compilation failures generally. 147 * @throws IllegalStateException if no compilation units were found. 148 * @throws UncheckedIOException if an IO error occurs. 149 * @see #compile(Workspace, String...) 150 * @see #compile(Workspace, Collection) 151 */ 152 JctCompilation compile(Workspace workspace); 153 154 /** 155 * Invoke the compilation and return the compilation result. 156 * 157 * <p>Only classes matching the given class names will be compiled. 158 * 159 * <p>If you wish to let JCT determine which classes to compile dynamically, see 160 * {@link #compile(Workspace)} instead. 161 * 162 * <p>Note that nested instance/static nested classes cannot be specified individually 163 * here. To compile them, you must also compile their outer class that they are defined within. 164 * 165 * @param workspace the workspace to compile. 166 * @param classNames the class names to compile. 167 * @return the compilation result. 168 * @throws JctCompilerException if the compiler threw an unhandled exception. This should not 169 * occur for compilation failures generally. 170 * @throws NullPointerException if any class names are null, or if the array is null. 171 * @throws IllegalStateException if no compilation units were found. 172 * @throws UncheckedIOException if an IO error occurs. 173 * @see #compile(Workspace) 174 * @see #compile(Workspace, Collection) 175 */ 176 default JctCompilation compile(Workspace workspace, String... classNames) { 177 requireAtLeastOne(classNames, "classNames"); 178 return compile(workspace, List.of(classNames)); 179 } 180 181 /** 182 * Invoke the compilation and return the compilation result. 183 * 184 * <p>Only classes matching the given class names will be compiled. 185 * 186 * <p>If you wish to let JCT determine which classes to compile dynamically, see 187 * {@link #compile(Workspace)} instead. 188 * 189 * <p>Note that nested instance/static nested classes cannot be specified individually 190 * here. To compile them, you must also compile their outer class that they are defined within. 191 * 192 * @param workspace the workspace to compile. 193 * @param classNames the class names to compile. 194 * @return the compilation result. 195 * @throws JctCompilerException if the compiler threw an unhandled exception. This should not 196 * occur for compilation failures usually. 197 * @throws NullPointerException if the {@code classNames} collection contains any null values, 198 * or if the collection itself is null. 199 * @throws IllegalArgumentException if the collection is empty. 200 * @throws IllegalStateException if no compilation units were found. 201 * @throws UncheckedIOException if an IO error occurs. 202 * @see #compile(Workspace) 203 * @see #compile(Workspace, String...) 204 */ 205 JctCompilation compile(Workspace workspace, Collection<String> classNames); 206 207 /** 208 * Apply a given configurer to this compiler. 209 * 210 * <p>Configurers can be lambdas, method references, or objects. 211 * 212 * <pre><code> 213 * // Using an object configurer 214 * var werrorConfigurer = new JctCompilerConfigurer<RuntimeException>() { 215 * {@literal @Override} 216 * public void configure(JctCompiler compiler) { 217 * compiler.failOnWarnings(true); 218 * } 219 * }; 220 * compiler.configure(werrorConfigurer); 221 * 222 * // Using a lambda configurer 223 * compiler.configure(c -> c.verbose(true)); 224 * </code></pre> 225 * 226 * <p>Configurers take a type parameter that corresponds to an exception type. This 227 * is the exception type that can be thrown by the configurer, or {@link RuntimeException} if no 228 * checked exception is thrown. This mechanism allows configurers to propagate checked exceptions 229 * to their caller where needed. 230 * 231 * <pre><code> 232 * class FileFlagConfigurer implements JctCompilerConfigurer<IOException> { 233 * private final Path path; 234 * 235 * public FileFlagConfigurer(String... path) { 236 * this(Path.of(path)); 237 * } 238 * 239 * public FileFlagConfigurer(Path path) { 240 * this.path = path; 241 * } 242 * 243 * {@literal @Override} 244 * public void configure(JctCompiler compiler) throws IOException { 245 * var flags = Files.lines(path) 246 * .map(String::trim) 247 * .filter(not(String::isBlank)) 248 * .toList(); 249 * compiler.addCompilerOptions(flags); 250 * } 251 * } 252 * 253 * {@literal @Test} 254 * void testSomething() throws IOException { 255 * ... 256 * compiler.configure(new FileFlagConfigurer("src", "test", "resources", "flags.txt")); 257 * ... 258 * } 259 * </code></pre> 260 * 261 * @param <E> any exception that may be thrown. 262 * @param configurer the configurer to invoke. 263 * @return this compiler object for further call chaining. 264 * @throws E any exception that may be thrown by the configurer. If no checked exception is 265 * thrown, then this should be treated as {@link RuntimeException}. 266 */ 267 <E extends Exception> JctCompiler configure(JctCompilerConfigurer<E> configurer) throws E; 268 269 /** 270 * Get the friendly printable name of this compiler object. 271 * 272 * @return the name of the compiler. 273 */ 274 String getName(); 275 276 /** 277 * Set the friendly name of this compiler. 278 * 279 * <p>This will be used by the 280 * {@link io.github.ascopes.jct.junit.JavacCompilerTest JUnit5 support} to name unit test cases. 281 * 282 * @param name the name to set. 283 * @return this compiler object for further call chaining. 284 */ 285 JctCompiler name(String name); 286 287 /** 288 * Get an <strong>immutable snapshot view</strong> of the current annotation processor options 289 * that are set. 290 * 291 * @return the current annotation processor options that are set. 292 */ 293 List<String> getAnnotationProcessorOptions(); 294 295 /** 296 * Add options to pass to any annotation processors. 297 * 298 * @param annotationProcessorOptions the options to pass. 299 * @return this compiler object for further call chaining. 300 */ 301 JctCompiler addAnnotationProcessorOptions(Iterable<String> annotationProcessorOptions); 302 303 /** 304 * Add options to pass to any annotation processors. 305 * 306 * @param annotationProcessorOptions options to pass. 307 * @return this compiler object for further call chaining. 308 */ 309 default JctCompiler addAnnotationProcessorOptions(String... annotationProcessorOptions) { 310 return addAnnotationProcessorOptions(List.of(annotationProcessorOptions)); 311 } 312 313 /** 314 * Get an <strong>immutable snapshot view</strong> of the current annotation processors that are 315 * explicitly set to be run, in the order that they were provided to the compiler. 316 * 317 * @return the current annotation processors that are set. 318 */ 319 List<Processor> getAnnotationProcessors(); 320 321 /** 322 * Add annotation processors to invoke. 323 * 324 * <p><strong>Warning:</strong> This bypasses the discovery process of annotation processors 325 * provided in the annotation processor path and annotation processor module paths, as well as any 326 * other locations such as class paths and module paths. 327 * 328 * @param annotationProcessors the processors to invoke. 329 * @return this compiler object for further call chaining. 330 */ 331 JctCompiler addAnnotationProcessors(Iterable<? extends Processor> annotationProcessors); 332 333 /** 334 * Add annotation processors to invoke. 335 * 336 * <p><strong>Warning:</strong> This bypasses the discovery process of annotation processors 337 * provided in the annotation processor path and annotation processor module paths, as well as any 338 * other locations such as class paths and module paths. 339 * 340 * @param annotationProcessors processors to invoke. 341 * @return this compiler object for further call chaining. 342 */ 343 default JctCompiler addAnnotationProcessors(Processor... annotationProcessors) { 344 return addAnnotationProcessors(List.of(annotationProcessors)); 345 } 346 347 /** 348 * Get an <strong>immutable snapshot view</strong> of the current compiler options that are set. 349 * 350 * @return the current compiler options that are set. 351 */ 352 List<String> getCompilerOptions(); 353 354 /** 355 * Add command line options to pass to {@code javac}. 356 * 357 * @param compilerOptions the options to add. 358 * @return this compiler object for further call chaining. 359 */ 360 JctCompiler addCompilerOptions(Iterable<String> compilerOptions); 361 362 /** 363 * Add command line options to pass to {@code javac}. 364 * 365 * @param compilerOptions options to add. 366 * @return this compiler object for further call chaining. 367 */ 368 default JctCompiler addCompilerOptions(String... compilerOptions) { 369 return addCompilerOptions(List.of(compilerOptions)); 370 } 371 372 /** 373 * Determine whether verbose logging is enabled or not. 374 * 375 * <p>Unless otherwise changed or specified, implementations should default to 376 * {@link #DEFAULT_VERBOSE}. 377 * 378 * <p>Note that enabling this is compiler-specific behaviour. There is no guarantee that the 379 * output target or the format or verbosity of output will be consistent between different 380 * compiler implementations. 381 * 382 * @return whether verbose logging is enabled or not. 383 */ 384 boolean isVerbose(); 385 386 /** 387 * Set whether to use verbose output or not. 388 * 389 * <p>Unless otherwise changed or specified, implementations should default to 390 * {@link #DEFAULT_VERBOSE}. 391 * 392 * <p>Note that enabling this is compiler-specific behaviour. There is no guarantee that the 393 * output target or the format or verbosity of output will be consistent between different 394 * compiler implementations. 395 * 396 * @param enabled {@code true} for verbose output, {@code false} for normal output. 397 * @return this compiler for further call chaining. 398 */ 399 JctCompiler verbose(boolean enabled); 400 401 /** 402 * Determine whether preview features are enabled or not. 403 * 404 * <p>Unless otherwise changed or specified, implementations should default to 405 * {@link #DEFAULT_PREVIEW_FEATURES}. 406 * 407 * @return whether preview features are enabled or not. 408 */ 409 boolean isPreviewFeatures(); 410 411 /** 412 * Set whether to enable compiler preview features or not. 413 * 414 * <p>Unless otherwise changed or specified, implementations should default to 415 * {@link #DEFAULT_PREVIEW_FEATURES}. 416 * 417 * <p>Generally, this feature should be avoided if testing across multiple versions 418 * of Java, as preview features are often not finalised and may change without warning. 419 * 420 * @param enabled {@code true} to enable preview features, or {@code false} to disable them. 421 * @return this compiler object for further call chaining. 422 */ 423 JctCompiler previewFeatures(boolean enabled); 424 425 /** 426 * Determine whether warnings are enabled or not. 427 * 428 * <p>Unless otherwise changed or specified, implementations should default to 429 * {@link #DEFAULT_SHOW_WARNINGS}. 430 * 431 * @return whether warnings are enabled or not. 432 */ 433 boolean isShowWarnings(); 434 435 /** 436 * Set whether to enable displaying warnings or not. 437 * 438 * <p>Unless otherwise changed or specified, implementations should default to 439 * {@link #DEFAULT_SHOW_WARNINGS}. 440 * 441 * @param enabled {@code true} to enable warnings. {@code false} to disable them. 442 * @return this compiler object for further call chaining. 443 */ 444 JctCompiler showWarnings(boolean enabled); 445 446 /** 447 * Determine whether deprecation warnings are enabled or not. 448 * 449 * <p>Unless otherwise changed or specified, implementations should default to 450 * {@link #DEFAULT_SHOW_DEPRECATION_WARNINGS}. 451 * 452 * @return whether deprecation warnings are enabled or not. 453 */ 454 boolean isShowDeprecationWarnings(); 455 456 /** 457 * Set whether to enable deprecation warnings or not. 458 * 459 * <p>This is ignored if {@link #showWarnings(boolean)} is disabled. 460 * 461 * <p>Unless otherwise changed or specified, implementations should default to 462 * {@link #DEFAULT_SHOW_DEPRECATION_WARNINGS}. 463 * 464 * @param enabled {@code true} to enable deprecation warnings. {@code false} to disable them. 465 * @return this compiler object for further call chaining. 466 */ 467 JctCompiler showDeprecationWarnings(boolean enabled); 468 469 /** 470 * Determine whether warnings are being treated as errors or not. 471 * 472 * <p>Unless otherwise changed or specified, implementations should default to 473 * {@link #DEFAULT_FAIL_ON_WARNINGS}. 474 * 475 * @return whether warnings are being treated as errors or not. 476 */ 477 boolean isFailOnWarnings(); 478 479 /** 480 * Set whether to enable treating warnings as errors or not. 481 * 482 * <p>Some compilers may call this flag something different, such as "{@code -Werror}". 483 * 484 * <p>This is ignored if {@link #showWarnings(boolean)} is disabled. 485 * 486 * <p>Unless otherwise changed or specified, implementations should default to 487 * {@link #DEFAULT_FAIL_ON_WARNINGS}. 488 * 489 * @param enabled {@code true} to enable treating warnings as errors. {@code false} to disable 490 * them. 491 * @return this compiler object for further call chaining. 492 */ 493 JctCompiler failOnWarnings(boolean enabled); 494 495 /** 496 * Get the compilation mode that is in use. 497 * 498 * <p>Unless otherwise changed or specified, implementations should default to 499 * {@link #DEFAULT_COMPILATION_MODE}. 500 * 501 * @return the compilation mode. 502 */ 503 CompilationMode getCompilationMode(); 504 505 /** 506 * Set the compilation mode to use for this compiler. 507 * 508 * <p>This allows you to override whether sources are compiled or annotation-processed 509 * without running the full compilation process. Tuning this may provide faster test cases in some 510 * situations. 511 * 512 * <p>Unless otherwise changed or specified, implementations should default to 513 * {@link #DEFAULT_COMPILATION_MODE}. 514 * 515 * @param compilationMode the compilation mode to use. 516 * @return this compiler object for further call chaining. 517 */ 518 JctCompiler compilationMode(CompilationMode compilationMode); 519 520 /** 521 * Get the default release to use if no release or target version is specified. 522 * 523 * <p>This can <strong>not</strong> be configured generally, as it is defined by 524 * the internal compiler implementation. 525 * 526 * <p>Generally, this value will be an integer within a string. The value is 527 * represented as a string to allow supporting compilers which may use non-integer version 528 * numbers. 529 * 530 * @return the default release version to use. 531 */ 532 String getDefaultRelease(); 533 534 /** 535 * Get the effective release to use for the actual compilation. 536 * 537 * <p>Generally, this value will be an integer within a string. The value is 538 * represented as a string to allow supporting compilers which may use non-integer version 539 * numbers. 540 * 541 * <p>This may be determined from the {@link #getSource() source}, 542 * {@link #getTarget() target}, {@link #getRelease() release}, and 543 * {@link #getDefaultRelease() default release.} 544 * 545 * @return the effective release. 546 */ 547 String getEffectiveRelease(); 548 549 /** 550 * Get the current release version that is set, or {@code null} if left to the compiler to decide. 551 * default. 552 * 553 * <p>Generally, this value will be an integer within a string. The value is 554 * represented as a string to allow supporting compilers which may use non-integer version 555 * numbers. 556 * 557 * <p>Unless explicitly defined, the default setting is expected to be a sane compiler-specific 558 * default. 559 * 560 * @return the release version string, if set. 561 */ 562 @Nullable 563 String getRelease(); 564 565 /** 566 * Set the release version. 567 * 568 * <p>This will clear any source and target version that is set. 569 * 570 * <p>Generally, this value will be an integer within a string. The value is 571 * represented as a string to allow supporting compilers which may use non-integer version 572 * numbers. 573 * 574 * <p>Unless explicitly defined, the default setting is expected to be a sane compiler-specific 575 * default. 576 * 577 * @param release the version to set. 578 * @return this compiler object for further call chaining. 579 */ 580 JctCompiler release(@Nullable String release); 581 582 /** 583 * Set the release version. 584 * 585 * <p>This will clear any source and target version that is set. 586 * 587 * <p>Generally, this value will be an integer within a string. The value is 588 * represented as a string to allow supporting compilers which may use non-integer version 589 * numbers. 590 * 591 * <p>Unless explicitly defined, the default setting is expected to be a sane compiler-specific 592 * default. 593 * 594 * @param release the version to set. 595 * @return this compiler object for further call chaining. 596 * @throws IllegalArgumentException if the version is less than 0. 597 * @throws UnsupportedOperationException if the compiler does not support integer versions. 598 */ 599 default JctCompiler release(int release) { 600 if (release < 0) { 601 throw new IllegalArgumentException("Cannot provide a release version less than 0"); 602 } 603 604 return release(Integer.toString(release)); 605 } 606 607 /** 608 * Set the release version. 609 * 610 * <p>This will clear any source and target version that is set. 611 * 612 * <p>Generally, this value will be an integer within a string. The value is 613 * represented as a string to allow supporting compilers which may use non-integer version 614 * numbers. 615 * 616 * <p>Unless explicitly defined, the default setting is expected to be a sane compiler-specific 617 * default. 618 * 619 * @param release the version to set. 620 * @return this compiler object for further call chaining. 621 * @throws UnsupportedOperationException if the compiler does not support integer versions. 622 * @throws NullPointerException if the release is null. 623 */ 624 default JctCompiler release(SourceVersion release) { 625 return release(Integer.toString(release.ordinal())); 626 } 627 628 /** 629 * Request that the compiler uses a language version that corresponds to the runtime language 630 * version in use on the current JVM. 631 * 632 * <p>For example, running this on JRE 19 would set the release to "19". 633 * 634 * <p>This calls {@link #release(int)} internally. 635 * 636 * @return this compiler object for further call chaining. 637 * @throws UnsupportedOperationException if the current JVM version does not correspond to a 638 * supported Java release version in the compiler, or if the 639 * compiler does not support integral version numbers. 640 * @since 1.1.0 641 */ 642 default JctCompiler useRuntimeRelease() { 643 return release(Runtime.version().feature()); 644 } 645 646 /** 647 * Get the current source version that is set, or {@code null} if left to the compiler to decide. 648 * default. 649 * 650 * <p>Unless explicitly defined, the default setting is expected to be a sane compiler-specific 651 * default. 652 * 653 * @return the source version string, if set. 654 */ 655 @Nullable 656 String getSource(); 657 658 /** 659 * Set the source version. 660 * 661 * <p>This will clear any release version that is set. 662 * 663 * <p>Unless explicitly defined, the default setting is expected to be a sane compiler-specific 664 * default. 665 * 666 * <p>Source and target versions have mostly been replaced with the release version 667 * mechanism which controls both flags and can ensure other behaviours are consistent. This 668 * feature is still provided in case you have a specific use case that is not covered by this 669 * functionality. 670 * 671 * @param source the version to set. 672 * @return this compiler object for further call chaining. 673 */ 674 JctCompiler source(@Nullable String source); 675 676 /** 677 * Set the source version. 678 * 679 * <p>This will clear any release version that is set. 680 * 681 * <p>Unless explicitly defined, the default setting is expected to be a sane compiler-specific 682 * default. 683 * 684 * <p>Source and target versions have mostly been replaced with the release version 685 * mechanism which controls both flags and can ensure other behaviours are consistent. This 686 * feature is still provided in case you have a specific use case that is not covered by this 687 * functionality. 688 * 689 * @param source the version to set. 690 * @return this compiler object for further call chaining. 691 * @throws IllegalArgumentException if the version is less than 0. 692 * @throws UnsupportedOperationException if the compiler does not support integer versions. 693 */ 694 default JctCompiler source(int source) { 695 if (source < 0) { 696 throw new IllegalArgumentException("Cannot provide a source version less than 0"); 697 } 698 699 return source(Integer.toString(source)); 700 } 701 702 /** 703 * Set the source version. 704 * 705 * <p>This will clear any release version that is set. 706 * 707 * <p>Unless explicitly defined, the default setting is expected to be a sane compiler-specific 708 * default. 709 * 710 * <p>Source and target versions have mostly been replaced with the release version 711 * mechanism which controls both flags and can ensure other behaviours are consistent. This 712 * feature is still provided in case you have a specific use case that is not covered by this 713 * functionality. 714 * 715 * @param source the version to set. 716 * @return this compiler object for further call chaining. 717 * @throws UnsupportedOperationException if the compiler does not support integer versions. 718 * @throws NullPointerException if the source is null. 719 */ 720 default JctCompiler source(SourceVersion source) { 721 return source(Integer.toString(source.ordinal())); 722 } 723 724 /** 725 * Get the current target version that is set, or {@code null} if left to the compiler default. 726 * 727 * <p>Unless explicitly defined, the default setting is expected to be a sane compiler-specific 728 * default. 729 * 730 * @return the target version string, if set. 731 */ 732 @Nullable 733 String getTarget(); 734 735 /** 736 * Set the target version. 737 * 738 * <p>This will clear any release version that is set. 739 * 740 * <p>Unless explicitly defined, the default setting is expected to be a sane compiler-specific 741 * default. 742 * 743 * <p>Source and target versions have mostly been replaced with the release version 744 * mechanism which controls both flags and can ensure other behaviours are consistent. This 745 * feature is still provided in case you have a specific use case that is not covered by this 746 * functionality. 747 * 748 * @param target the version to set. 749 * @return this compiler object for further call chaining. 750 */ 751 JctCompiler target(@Nullable String target); 752 753 /** 754 * Set the target version. 755 * 756 * <p>This will clear any release version that is set. 757 * 758 * <p>Unless explicitly defined, the default setting is expected to be a sane compiler-specific 759 * default. 760 * 761 * <p>Source and target versions have mostly been replaced with the release version 762 * mechanism which controls both flags and can ensure other behaviours are consistent. This 763 * feature is still provided in case you have a specific use case that is not covered by this 764 * functionality. 765 * 766 * @param target the version to set. 767 * @return this compiler object for further call chaining. 768 * @throws IllegalArgumentException if the version is less than 0. 769 * @throws UnsupportedOperationException if the compiler does not support integer versions. 770 */ 771 default JctCompiler target(int target) { 772 if (target < 0) { 773 throw new IllegalArgumentException("Cannot provide a target version less than 0"); 774 } 775 776 return target(Integer.toString(target)); 777 } 778 779 /** 780 * Set the target version. 781 * 782 * <p>This will clear any release version that is set. 783 * 784 * <p>Unless explicitly defined, the default setting is expected to be a sane compiler-specific 785 * default. 786 * 787 * <p>Source and target versions have mostly been replaced with the release version 788 * mechanism which controls both flags and can ensure other behaviours are consistent. This 789 * feature is still provided in case you have a specific use case that is not covered by this 790 * functionality. 791 * 792 * @param target the version to set. 793 * @return this compiler object for further call chaining. 794 * @throws UnsupportedOperationException if the compiler does not support integer versions. 795 * @throws NullPointerException if the target is null. 796 */ 797 default JctCompiler target(SourceVersion target) { 798 return target(Integer.toString(target.ordinal())); 799 } 800 801 /** 802 * Get whether we will attempt to fix modules appearing on the classpath, or non-modules appearing 803 * on the module path. 804 * 805 * <p>This enables correct classpath and module path detection when the test pack is a module but 806 * the code being compiled in the test is not, and vice versa. We need this because many build 807 * systems decide whether to populate the {@code --module-path} or the {@code --classpath} 808 * with JPMS-enabled dependencies based on whether the project under compilation is a JPMS module 809 * itself. 810 * 811 * <p>This only applies if {@link #isInheritModulePath()} or {@link #isInheritClassPath()} is 812 * enabled, and only applies to the current JVM classpath and module path. 813 * 814 * <p>Unless otherwise changed or specified, implementations should default to 815 * {@link #DEFAULT_FIX_JVM_MODULE_PATH_MISMATCH}. 816 * 817 * @return {@code true} if enabled, or {@code false} if disabled. 818 */ 819 boolean isFixJvmModulePathMismatch(); 820 821 /** 822 * Get whether we will attempt to fix modules appearing on the classpath, or non-modules appearing 823 * on the module path. 824 * 825 * <p>Unless otherwise changed or specified, implementations should default to 826 * {@link #DEFAULT_FIX_JVM_MODULE_PATH_MISMATCH}. 827 * 828 * @param fixJvmModulePathMismatch whether to enable the mismatch fixing or not. 829 * @return this compiler object for further call chaining. 830 */ 831 JctCompiler fixJvmModulePathMismatch(boolean fixJvmModulePathMismatch); 832 833 /** 834 * Get whether the class path is inherited from the active JVM or not. 835 * 836 * <p>Unless otherwise changed or specified, implementations should default to 837 * {@link #DEFAULT_INHERIT_CLASS_PATH}. 838 * 839 * @return whether the current class path is being inherited or not. 840 */ 841 boolean isInheritClassPath(); 842 843 /** 844 * Set whether the class path is inherited from the active JVM or not. 845 * 846 * <p>Unless otherwise changed or specified, implementations should default to 847 * {@link #DEFAULT_INHERIT_CLASS_PATH}. 848 * 849 * @param inheritClassPath {@code true} to include it, or {@code false} to exclude it. 850 * @return this compiler object for further call chaining. 851 */ 852 JctCompiler inheritClassPath(boolean inheritClassPath); 853 854 /** 855 * Get whether the module path is inherited from the active JVM or not. 856 * 857 * <p>Unless otherwise changed or specified, implementations should default to 858 * {@link #DEFAULT_INHERIT_MODULE_PATH}. 859 * 860 * @return whether the module path is being inherited or not. 861 */ 862 boolean isInheritModulePath(); 863 864 /** 865 * Set whether the module path is inherited from the active JVM or not. 866 * 867 * <p>Unless otherwise changed or specified, implementations should default to 868 * {@link #DEFAULT_INHERIT_MODULE_PATH}. 869 * 870 * @param inheritModulePath {@code true} to include it, or {@code false} to exclude it. 871 * @return this compiler object for further call chaining. 872 */ 873 JctCompiler inheritModulePath(boolean inheritModulePath); 874 875 /** 876 * Get whether the system module path is inherited from the active JVM or not. 877 * 878 * <p>Unless otherwise changed or specified, implementations should default to 879 * {@link #DEFAULT_INHERIT_SYSTEM_MODULE_PATH}. 880 * 881 * @return whether the system module path is being inherited or not. 882 */ 883 boolean isInheritSystemModulePath(); 884 885 /** 886 * Set whether the system module path is inherited from the active JVM or not. 887 * 888 * <p>Unless otherwise changed or specified, implementations should default to 889 * {@link #DEFAULT_INHERIT_SYSTEM_MODULE_PATH}. 890 * 891 * @param inheritSystemModulePath {@code true} to include it, or {@code false} to exclude it. 892 * @return this compiler object for further call chaining. 893 */ 894 JctCompiler inheritSystemModulePath(boolean inheritSystemModulePath); 895 896 /** 897 * Get the output locale. 898 * 899 * <p>Unless otherwise changed or specified, implementations should default to 900 * {@link #DEFAULT_LOCALE}. 901 * 902 * @return the output locale to use. 903 */ 904 Locale getLocale(); 905 906 /** 907 * Set the output locale. 908 * 909 * <p>Unless otherwise changed or specified, implementations should default to 910 * {@link #DEFAULT_LOCALE}. 911 * 912 * @param locale the locale to use. 913 * @return this compiler for further call chaining. 914 */ 915 JctCompiler locale(Locale locale); 916 917 /** 918 * Get the charset being used to write compiler logs with. 919 * 920 * <p>Unless otherwise changed or specified, implementations should default to 921 * {@link #DEFAULT_LOG_CHARSET}. 922 * 923 * @return the charset. 924 */ 925 Charset getLogCharset(); 926 927 /** 928 * Set the charset being used to write compiler logs with. 929 * 930 * <p>Unless otherwise changed or specified, implementations should default to 931 * {@link #DEFAULT_LOG_CHARSET}. 932 * 933 * @param logCharset the charset to use. 934 * @return this compiler for further call chaining. 935 */ 936 JctCompiler logCharset(Charset logCharset); 937 938 /** 939 * Get the current file manager logging mode. 940 * 941 * <p>Unless otherwise changed or specified, implementations should default to 942 * {@link #DEFAULT_FILE_MANAGER_LOGGING_MODE}. 943 * 944 * @return the current file manager logging mode. 945 */ 946 LoggingMode getFileManagerLoggingMode(); 947 948 /** 949 * Set how to handle logging calls to underlying file managers. 950 * 951 * <p>Unless otherwise changed or specified, implementations should default to 952 * {@link #DEFAULT_FILE_MANAGER_LOGGING_MODE}. 953 * 954 * @param fileManagerLoggingMode the mode to use for file manager logging. 955 * @return this compiler for further call chaining. 956 */ 957 JctCompiler fileManagerLoggingMode(LoggingMode fileManagerLoggingMode); 958 959 /** 960 * Get the current diagnostic logging mode. 961 * 962 * <p>Unless otherwise changed or specified, implementations should default to 963 * {@link #DEFAULT_DIAGNOSTIC_LOGGING_MODE}. 964 * 965 * @return the current diagnostic logging mode. 966 */ 967 LoggingMode getDiagnosticLoggingMode(); 968 969 /** 970 * Set how to handle diagnostic capture. 971 * 972 * <p>Unless otherwise changed or specified, implementations should default to 973 * {@link #DEFAULT_DIAGNOSTIC_LOGGING_MODE}. 974 * 975 * @param diagnosticLoggingMode the mode to use for diagnostic capture. 976 * @return this compiler for further call chaining. 977 */ 978 JctCompiler diagnosticLoggingMode(LoggingMode diagnosticLoggingMode); 979 980 /** 981 * Get how to perform annotation processor discovery. 982 * 983 * <p>Unless otherwise changed or specified, implementations should default to 984 * {@link #DEFAULT_ANNOTATION_PROCESSOR_DISCOVERY}. 985 * 986 * <p>Specifying any annotation processors explicitly with 987 * {@link #addAnnotationProcessors(Iterable)} or 988 * {@link #addAnnotationProcessors(Processor...)} will bypass this setting, treating it 989 * as being disabled. 990 * 991 * @return the processor discovery mode to use. 992 */ 993 AnnotationProcessorDiscovery getAnnotationProcessorDiscovery(); 994 995 /** 996 * Set how to perform annotation processor discovery. 997 * 998 * <p>Unless otherwise changed or specified, implementations should default to 999 * {@link #DEFAULT_ANNOTATION_PROCESSOR_DISCOVERY}. 1000 * 1001 * <p>Specifying any annotation processors explicitly with 1002 * {@link #addAnnotationProcessors(Iterable)} or 1003 * {@link #addAnnotationProcessors(Processor...)} will bypass this setting, treating it 1004 * as being disabled. 1005 * 1006 * @param annotationProcessorDiscovery the processor discovery mode to use. 1007 * @return this compiler for further call chaining. 1008 */ 1009 JctCompiler annotationProcessorDiscovery( 1010 AnnotationProcessorDiscovery annotationProcessorDiscovery); 1011 1012 /** 1013 * Get the debugging info that is enabled. 1014 * 1015 * <p>Unless otherwise changed or specified, implementations should default to 1016 * {@link #DEFAULT_DEBUGGING_INFO}. 1017 * 1018 * @return the set of debugging info flags that are enabled. 1019 * @since 3.0.0 1020 */ 1021 Set<DebuggingInfo> getDebuggingInfo(); 1022 1023 /** 1024 * Set the debugging info level to use. 1025 * 1026 * @param debuggingInfoFlags the set of debugging info flags to enable. 1027 * @return this compiler for further call chaining. 1028 * @since 3.0.0 1029 */ 1030 JctCompiler debuggingInfo(Set<DebuggingInfo> debuggingInfoFlags); 1031 1032 /** 1033 * Determine if including reflective parameter info is enabled or not. 1034 * 1035 * <p>Unless otherwise changed or specified, implementations should default to 1036 * {@link #DEFAULT_PARAMETER_INFO_ENABLED}. 1037 * 1038 * @return the parameter info inclusion preference. 1039 * @since 3.0.0 1040 */ 1041 boolean isParameterInfoEnabled(); 1042 1043 /** 1044 * Set whether to include parameter reflective info by default in compiled classes or not. 1045 * 1046 * @param parameterInfoEnabled whether to include the parameter reflective info or not. 1047 * @return this compiler for further call chaining. 1048 * @since 3.0.0 1049 */ 1050 JctCompiler parameterInfoEnabled(boolean parameterInfoEnabled); 1051}