Load JVM built-ins in IDE from module dependencies

Fix built-ins for JVM platform and make them consistent
with module's dependency on standard library. Changes
don't affect non-JVM platforms.

Previously all built-ins in IDE were loaded from classloader
and were based on the same pre-serialized .kotlin_builtins files.
This approach is generally not correct as built-in declarations
differ for different platforms, but it had been working for a while
without immediately observalble effects (see KT-33233 for more info).
After changes in standard library JvmBuiltins started producing
false errors (see KT-39728).

To fix this, JVM built-ins in IDE now utilize the same technique as
applied in CLI: using dependency on standard library as a module
for built-ins instead of artificial module that considers only
.kotlin_builtins.

Change summary:
- Provide JvmBuiltins with kind FROM_DEPENDENCIES
  for all modules with stdlib dependency in IDE
- Add JvmBuiltinsPackageFragmentProvider to JVM-ish module resolvers
  (JVM and Composite with JVM platform) to support their use as
  built-ins module
- Create KotlinBuiltInsMetadataIndex file index for tracking libraries
  containing .kotlin_builtins to support JvmBuiltinsPackageFragmentProvider
- Create KotlinStdlibIndex file index for tracking kotlin-stdlib(-common),
  which looks for "Kotlin-Runtime-Component" manifest attribute
- Add caching service to track LibraryInfo for kotlin-stdlib(-common)
- Put LibraryInfo for kotlin-stdlib(-common) alongside SDKs
  due to the need to resolve that modules in BuiltInsCache
- Update BuiltInsCache to separate JvmBuiltins by module's dependency
  on stdlib and JDK
- Make platform of KotlinSDK common instead of JVM
- Set built-ins module lazily in IDE

^KT-33233 Verification Pending
This commit is contained in:
Pavel Kirpichenkov
2020-12-14 16:30:29 +03:00
parent 1479c7a270
commit c0dd731818
27 changed files with 440 additions and 77 deletions
@@ -13,7 +13,7 @@ import org.jetbrains.kotlin.storage.StorageManager
import org.jetbrains.kotlin.storage.getValue
import org.jetbrains.kotlin.utils.sure
class JvmBuiltIns(storageManager: StorageManager, kind: Kind) : KotlinBuiltIns(storageManager) {
class JvmBuiltIns(storageManager: StorageManager, val kind: Kind) : KotlinBuiltIns(storageManager) {
/**
* Where built-ins should be loaded from.
*/
@@ -60,4 +60,8 @@ class JvmBuiltInsPackageFragmentProvider(
finder.findBuiltInsData(fqName)?.let { inputStream ->
BuiltInsPackageFragmentImpl.create(fqName, storageManager, moduleDescriptor, inputStream, isFallback = false)
}
companion object {
const val DOT_BUILTINS_METADATA_FILE_EXTENSION = ".kotlin_builtins"
}
}
@@ -39,6 +39,7 @@ import static org.jetbrains.kotlin.resolve.DescriptorUtils.getFqName;
public abstract class KotlinBuiltIns {
private ModuleDescriptorImpl builtInsModule;
private NotNullLazyValue<ModuleDescriptorImpl> postponedBuiltInsModule;
private final NotNullLazyValue<Primitives> primitives;
private final NotNullLazyValue<Collection<PackageViewDescriptor>> builtInPackagesImportedByDefault;
@@ -56,10 +57,10 @@ public abstract class KotlinBuiltIns {
@Override
public Collection<PackageViewDescriptor> invoke() {
return Arrays.asList(
builtInsModule.getPackage(BUILT_INS_PACKAGE_FQ_NAME),
builtInsModule.getPackage(COLLECTIONS_PACKAGE_FQ_NAME),
builtInsModule.getPackage(RANGES_PACKAGE_FQ_NAME),
builtInsModule.getPackage(ANNOTATION_PACKAGE_FQ_NAME)
getBuiltInsModule().getPackage(BUILT_INS_PACKAGE_FQ_NAME),
getBuiltInsModule().getPackage(COLLECTIONS_PACKAGE_FQ_NAME),
getBuiltInsModule().getPackage(RANGES_PACKAGE_FQ_NAME),
getBuiltInsModule().getPackage(ANNOTATION_PACKAGE_FQ_NAME)
);
}
});
@@ -123,6 +124,10 @@ public abstract class KotlinBuiltIns {
});
}
public void setPostponedBuiltinsModuleComputation(@NotNull Function0<ModuleDescriptorImpl> computation) {
postponedBuiltInsModule = storageManager.createLazyValue(computation);
}
@NotNull
protected AdditionalClassPartsProvider getAdditionalClassPartsProvider() {
return AdditionalClassPartsProvider.None.INSTANCE;
@@ -135,7 +140,8 @@ public abstract class KotlinBuiltIns {
@NotNull
protected Iterable<ClassDescriptorFactory> getClassDescriptorFactories() {
return Collections.<ClassDescriptorFactory>singletonList(new BuiltInFictitiousFunctionClassFactory(storageManager, builtInsModule));
return Collections.<ClassDescriptorFactory>singletonList(
new BuiltInFictitiousFunctionClassFactory(storageManager, getBuiltInsModule()));
}
@NotNull
@@ -161,6 +167,10 @@ public abstract class KotlinBuiltIns {
@NotNull
public ModuleDescriptorImpl getBuiltInsModule() {
assert builtInsModule != null || postponedBuiltInsModule != null : "Uninitialized built-ins module";
if (builtInsModule == null) {
builtInsModule = postponedBuiltInsModule.invoke();
}
return builtInsModule;
}
@@ -198,12 +208,12 @@ public abstract class KotlinBuiltIns {
@NotNull
public MemberScope getBuiltInsPackageScope() {
return builtInsModule.getPackage(BUILT_INS_PACKAGE_FQ_NAME).getMemberScope();
return getBuiltInsModule().getPackage(BUILT_INS_PACKAGE_FQ_NAME).getMemberScope();
}
@NotNull
public ClassDescriptor getBuiltInClassByFqName(@NotNull FqName fqName) {
ClassDescriptor descriptor = DescriptorUtilKt.resolveClassByFqName(builtInsModule, fqName, NoLookupLocation.FROM_BUILTINS);
ClassDescriptor descriptor = DescriptorUtilKt.resolveClassByFqName(getBuiltInsModule(), fqName, NoLookupLocation.FROM_BUILTINS);
assert descriptor != null : "Can't find built-in class " + fqName;
return descriptor;
}