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