Replace ModuleDescriptorImpl implementation

Change the way modules are configured:
Add dependencies on other modules instead of adding additional package fragment providers
Refactor related code
Drop DependencyKind
Hide common new module creation in CliLightClassGenerationSupport
This commit is contained in:
Pavel V. Talanov
2014-07-30 16:45:02 +04:00
parent 145aa5a276
commit 8496c535aa
30 changed files with 326 additions and 297 deletions
@@ -16,6 +16,8 @@
package org.jetbrains.jet.lang.descriptors;
import kotlin.jvm.KotlinSignature;
public interface DeclarationDescriptorVisitor<R, D> {
R visitPackageFragmentDescriptor(PackageFragmentDescriptor descriptor, D data);
@@ -30,6 +32,7 @@ public interface DeclarationDescriptorVisitor<R, D> {
R visitClassDescriptor(ClassDescriptor descriptor, D data);
@KotlinSignature("fun visitModuleDeclaration(descriptor: ModuleDescriptor, data: D): R")
R visitModuleDeclaration(ModuleDescriptor descriptor, D data);
R visitConstructorDescriptor(ConstructorDescriptor constructorDescriptor, D data);
@@ -1,24 +0,0 @@
/*
* Copyright 2010-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.jet.lang.descriptors;
public enum DependencyKind {
// Using this class is supposed to be a temporary measure before we switch to full-blown support for module dependency ordering
SOURCES,
BUILT_INS,
BINARIES
}
@@ -1,52 +0,0 @@
/*
* Copyright 2010-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.jet.lang.descriptors;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.PlatformToKotlinClassMap;
import org.jetbrains.jet.lang.resolve.ImportPath;
import org.jetbrains.jet.lang.resolve.name.FqName;
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
import org.jetbrains.jet.lang.types.TypeSubstitutor;
import java.util.List;
public interface ModuleDescriptor extends DeclarationDescriptor {
@Override
@Nullable
DeclarationDescriptor getContainingDeclaration();
@NotNull
PackageFragmentProvider getPackageFragmentProvider();
@Nullable
PackageViewDescriptor getPackage(@NotNull FqName fqName);
@NotNull
List<ImportPath> getDefaultImports();
@NotNull
PlatformToKotlinClassMap getPlatformToKotlinClassMap();
@NotNull
@Override
ModuleDescriptor substitute(@NotNull TypeSubstitutor substitutor);
@Override
<R, D> R accept(DeclarationDescriptorVisitor<R, D> visitor, D data);
}
@@ -0,0 +1,46 @@
/*
* Copyright 2010-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.jet.lang.descriptors
import org.jetbrains.jet.lang.PlatformToKotlinClassMap
import org.jetbrains.jet.lang.resolve.ImportPath
import org.jetbrains.jet.lang.resolve.name.FqName
import org.jetbrains.jet.lang.types.TypeSubstitutor
import org.jetbrains.jet.lang.descriptors.impl.PackageViewDescriptorImpl
public trait ModuleDescriptor : DeclarationDescriptor {
override fun getContainingDeclaration(): DeclarationDescriptor? = null
public fun getPackageFragmentProvider(): PackageFragmentProvider
public fun getPackage(fqName: FqName): PackageViewDescriptor? {
val fragments = getPackageFragmentProvider().getPackageFragments(fqName)
return if (!fragments.isEmpty()) PackageViewDescriptorImpl(this, fqName, fragments) else null
}
public val defaultImports: List<ImportPath>
public val platformToKotlinClassMap: PlatformToKotlinClassMap
override fun substitute(substitutor: TypeSubstitutor): ModuleDescriptor {
return this
}
override fun <R, D> accept(visitor: DeclarationDescriptorVisitor<R, D>, data: D): R {
return visitor.visitModuleDeclaration(this, data)
}
}
@@ -1,122 +0,0 @@
/*
* Copyright 2010-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.jet.lang.descriptors.impl;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.intellij.openapi.diagnostic.Logger;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.PlatformToKotlinClassMap;
import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.descriptors.annotations.Annotations;
import org.jetbrains.jet.lang.resolve.ImportPath;
import org.jetbrains.jet.lang.resolve.name.FqName;
import org.jetbrains.jet.lang.resolve.name.Name;
import org.jetbrains.jet.lang.types.TypeSubstitutor;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
public class ModuleDescriptorImpl extends DeclarationDescriptorImpl implements ModuleDescriptor {
private static final Logger LOG = Logger.getInstance(ModuleDescriptorImpl.class);
private final Map<DependencyKind, List<PackageFragmentProvider>> prioritizedFragmentProviders = Maps.newHashMap();
private final List<PackageFragmentProvider> fragmentProviders = Lists.newArrayList();
private final CompositePackageFragmentProvider packageFragmentProvider = new CompositePackageFragmentProvider(fragmentProviders);
private final List<ImportPath> defaultImports;
private final PlatformToKotlinClassMap platformToKotlinClassMap;
public ModuleDescriptorImpl(
@NotNull Name name,
@NotNull List<ImportPath> defaultImports,
@NotNull PlatformToKotlinClassMap platformToKotlinClassMap
) {
super(Annotations.EMPTY, name);
if (!name.isSpecial()) {
throw new IllegalArgumentException("module name must be special: " + name);
}
this.defaultImports = defaultImports;
this.platformToKotlinClassMap = platformToKotlinClassMap;
}
public void addFragmentProvider(@NotNull DependencyKind dependencyKind, @NotNull PackageFragmentProvider provider) {
if (fragmentProviders.contains(provider)) {
LOG.error("Trying to add already present fragment provider: " + provider);
}
List<PackageFragmentProvider> providers = prioritizedFragmentProviders.get(dependencyKind);
if (providers == null) {
providers = new ArrayList<PackageFragmentProvider>(1);
prioritizedFragmentProviders.put(dependencyKind, providers);
}
providers.add(provider);
buildProvidersList();
}
private void buildProvidersList() {
fragmentProviders.clear();
for (DependencyKind dependencyKind : DependencyKind.values()) {
List<PackageFragmentProvider> providers = prioritizedFragmentProviders.get(dependencyKind);
if (providers != null) {
fragmentProviders.addAll(providers);
}
}
}
@Override
@Nullable
public DeclarationDescriptor getContainingDeclaration() {
return null;
}
@NotNull
@Override
public PackageFragmentProvider getPackageFragmentProvider() {
return packageFragmentProvider;
}
@Nullable
@Override
public PackageViewDescriptor getPackage(@NotNull FqName fqName) {
List<PackageFragmentDescriptor> fragments = packageFragmentProvider.getPackageFragments(fqName);
return !fragments.isEmpty() ? new PackageViewDescriptorImpl(this, fqName, fragments) : null;
}
@NotNull
@Override
public List<ImportPath> getDefaultImports() {
return defaultImports;
}
@NotNull
@Override
public PlatformToKotlinClassMap getPlatformToKotlinClassMap() {
return platformToKotlinClassMap;
}
@NotNull
@Override
public ModuleDescriptor substitute(@NotNull TypeSubstitutor substitutor) {
return this;
}
@Override
public <R, D> R accept(DeclarationDescriptorVisitor<R, D> visitor, D data) {
return visitor.visitModuleDeclaration(this, data);
}
}
@@ -0,0 +1,87 @@
/*
* Copyright 2010-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.jet.lang.descriptors.impl
import org.jetbrains.jet.lang.resolve.name.Name
import org.jetbrains.jet.lang.PlatformToKotlinClassMap
import org.jetbrains.jet.lang.descriptors.PackageFragmentProvider
import java.util.ArrayList
import org.jetbrains.jet.lang.resolve.ImportPath
import org.jetbrains.jet.lang.descriptors.annotations.Annotations
import org.jetbrains.jet.lang.descriptors.ModuleDescriptor
import kotlin.properties.Delegates
public class ModuleDescriptorImpl(
moduleName: Name,
override val defaultImports: List<ImportPath>,
override val platformToKotlinClassMap: PlatformToKotlinClassMap
) : DeclarationDescriptorImpl(Annotations.EMPTY, moduleName), ModuleDescriptor {
{
if (!moduleName.isSpecial()) {
throw IllegalArgumentException("Module name must be special: $moduleName")
}
}
private var isSealed = false
/*
* Sealed module cannot have its dependencies modified. Seal the module after you're done configuring it.
* Module will be sealed automatically as soon as you query its contents.
*/
public fun seal() {
if (isSealed) return
assert(this in dependencies, "Module $id is not contained in his own dependencies, this is probably a misconfiguration")
isSealed = true
}
private val dependencies: MutableList<ModuleDescriptorImpl> = ArrayList()
private var packageFragmentProviderForModuleContent: PackageFragmentProvider? = null
private val packageFragmentProviderForWholeModuleWithDependencies by Delegates.lazy {
seal()
dependencies.forEach {
dependency ->
assert(dependency.isInitialized, "Dependency module ${dependency.id} was not initialized by the time contents of dependent module ${this.id} were queried")
}
CompositePackageFragmentProvider(dependencies.map {
it.packageFragmentProviderForModuleContent!!
})
}
private val isInitialized: Boolean
get() = packageFragmentProviderForModuleContent != null
public fun addDependencyOnModule(dependency: ModuleDescriptorImpl) {
assert(!isSealed, "Can't modify dependencies of sealed module $id")
assert(dependency !in dependencies, "Trying to add dependency on module ${dependency.id} a second time for module ${this.id}, this is probably a misconfiguration")
dependencies.add(dependency)
}
private val id: String
get() = getName().toString()
/*
* Call initialize() to set module contents. Uninitialized module cannot be queried for its contents.
* Initialize() and seal() can be called in any order.
*/
public fun initialize(providerForModuleContent: PackageFragmentProvider) {
assert(!isInitialized, "Attempt to initialize module $id twice")
packageFragmentProviderForModuleContent = providerForModuleContent
}
override fun getPackageFragmentProvider() = packageFragmentProviderForWholeModuleWithDependencies
}
@@ -109,7 +109,9 @@ public class KotlinBuiltIns {
Collections.<ImportPath>emptyList(),
PlatformToKotlinClassMap.EMPTY);
builtinsPackageFragment = new BuiltinsPackageFragment(new LockBasedStorageManager(), builtInsModule);
builtInsModule.addFragmentProvider(DependencyKind.SOURCES, builtinsPackageFragment.getProvider());
builtInsModule.initialize(builtinsPackageFragment.getProvider());
builtInsModule.addDependencyOnModule(builtInsModule);
builtInsModule.seal();
primitiveTypeToNullableJetType = new EnumMap<PrimitiveType, JetType>(PrimitiveType.class);
primitiveTypeToArrayJetType = new EnumMap<PrimitiveType, JetType>(PrimitiveType.class);