`-Xbuild-file` argument allows the compiler to run without
passing any Kotlin source file in arguments.
We have been using this property in
Kotlin Gradle plugin for a few important cases:
1. incremental compilation (to update caches when there are only removed files);
2. for KAPT (Kotlin sources don't make sense in context
of running APs).
We want to stop using `-Xbuild-file` in Kotlin Gradle plugin,
and avoid breaking the Gradle plugin or IC in other build-systems.
This change adds an argument to explicitly run
the compiler without specifying any Kotlin source file.
In TopDownAnalyzerFacadeForJVM, we now always use the "load built-ins
from module dependencies" behavior that was previously only enabled with
the dedicated CLI argument -Xload-builtins-from-dependencies. However,
sometimes we compile code without kotlin-stdlib in the classpath, and we
don't want everything to crash because some standard type like
kotlin.Unit hasn't been found.
To mitigate this, we add another module at the end of the dependencies
list, namely a "fallback built-ins" module. This module loads all
built-in declarations from the compiler's class loader, as was done by
default previously. This prevents the compiler from crashing if any
built-in declaration is not found, but compiling the code against
built-ins found in the compiler is still discouraged, so we report an
error if anything is resolved to a declaration from this module, via a
new checker MissingBuiltInDeclarationChecker.
Also introduce a new CLI argument -Xsuppress-missing-builtins-error
specifically to suppress this error and to allow compiling code against
compiler's own built-ins.
#KT-19227 Fixed
#KT-28198 Fixed
Preface: for Groovy traits with fields, the Groovy compiler generates
synthetic "$Trait$FieldHelper" classes which posed several problems to
our class file reader, caused by the fact that the contents of the
InnerClasses attribute broke some assumptions about how names on the JVM
are formed and used.
For a trait named `A`, the Groovy compiler will additionally generate a
synthetic class file `A$Trait$FieldHelper` with the following in the
InnerClasses attribute:
InnerClasses:
public static #15= #2 of #14; //FieldHelper=class A$Trait$FieldHelper of class A
i.e. the simple name of the class is `FieldHelper`, the name of its
outer class is `A`, but the full internal name is `A$Trait$FieldHelper`,
which is surprising considering that the names are usually obtained by
separating the outer and inner names via the dollar sign.
Another detail is that in some usages of this synthetic class, the
InnerClasses attribute was missing at all. For example, if an empty
class `B` extends `A`, then there's no InnerClasses attribute in `B`'s
class file, which is surprising because we might decode the same name
differently depending on the class file we encounter it in.
In this change, we attempt to treat these synthetic classes as top-level
by refusing to read "invalid" InnerClasses attribute values (they are
not technically invalid because they still conform to JVMS), fixing the
problem of "unresolved supertypes" error which occurred when these
classes were used as supertypes in a class file in a dependency.
1) In ClassifierResolutionContext.mapInternalNameToClassId, do not use
the ad-hoc logic (copy-pasted from intellij-core) to determine class
id heuristically from the internal name. For $Trait$FieldHelper
classes this logic attempted to replace all dollar signs with dots,
which was semantically incorrect: dollars there were used as
synthetic characters, not as a separator between outer and inner
classes.
2) In isNotTopLevelClass (Other.kt), only consider "valid" InnerClasses
attribute values, where the full name of the class is obtained by
separating the outer name and the inner name with a dollar character.
This way, we'll be able to treat class files with invalid attribute
values as top-level and avoid breaking any other assumptions in the
class file loader.
3) In BinaryJavaClass.visitInnerClass, record all valid InnerClasses
attribute values present in the class file, not just those related to
the class in question itself. This is needed now because previously,
the removed heuristics (see p.1) transformed mentioned inner class
names to class ids correctly >99% of the time. Now that the
heuristics are gone, we'll use the information present in the class
file to map names correctly and predictably. According to JVMS, this
attribute should contain information about all inner classes
mentioned in the class file, and this is true at least for class
files produced by javac.
#KT-18592 Fixed
Declare AnalysisFlags in module 'frontend', and JvmAnalysisFlags in
module 'frontend.java', to avoid leaking Java-related logic to common
compiler code
There are two visible effects of this change:
1) If an empty argument is passed in quotes, it will be parsed as an
empty string and handled by the compiler, which will report an error
later. The specific error is not very important because it's an edge
case anyway; at the moment, "source file or directory not found:" is
reported which is no better than the "invalid flag:" error reported
by javac in the similar case
2) It's no longer possible to split an argument into several parts and
quote them separately, such as:
"-langu"ag"e-"ver'sio'n 1.2
No test added for this change in behavior since it's an even edgier
case. Note that javac also prohibits this.
#KT-27226 Fixed
Preface: Kotlin 1.3 will be able to read metadata of .class files
produced by Kotlin 1.4 (see KT-25972). Also, to simplify implementation
and to improve diagnostic messages, we're going to advance JVM metadata
version to 1.4.0 in Kotlin 1.4, and would like to keep it in sync with
the compiler version thereafter. This presents a problem: in an unlikely
event that before releasing 1.4, we find out that the metadata-reading
implementation in 1.3 was incorrect, we'd like to be able to fix the bug
in that implementation and _forbid_ 1.3 from reading metadata of 1.4.
But prior to this commit the only way to do this was to advance the
metadata version, in this case to 1.5, and that breaks the
metadata/compiler version equivalence we'd like to keep.
The solution is to add another boolean flag to the class file, called
"strict metadata version semantics", which signifies that if this class
file has metadata version 1.X, then it can only be read by the compilers
of versions 1.X and greater. This flag effectively disables the smooth
migration scenario proposed in KT-25972 (as does increasing metadata
version by 2), and will be used only in hopeless situations as in the
case described above.
When sourceMapEmbedSources are not null and source maps is disabled warning is reported, since it has effect only when source maps are enabled. Also this fixes some JPS JS with warnings count assertions.