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