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