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