From 109c09cf7cfbb8eaad13c1cb2eadabf8ee6ad43d Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Wed, 3 Jun 2015 17:50:23 +0200 Subject: [PATCH] get rid of WritableScopeWithImports --- .../impl/MutableClassDescriptor.java | 11 +- .../kotlin/resolve/scopes/WritableScope.kt | 2 - .../resolve/scopes/WritableScopeImpl.kt | 89 +++++--- .../scopes/WritableScopeWithImports.kt | 190 ------------------ .../AbstractJvmRuntimeDescriptorLoaderTest.kt | 32 +-- .../kotlin/types/JetTypeCheckerTest.java | 13 +- 6 files changed, 93 insertions(+), 244 deletions(-) delete mode 100644 compiler/frontend/src/org/jetbrains/kotlin/resolve/scopes/WritableScopeWithImports.kt diff --git a/compiler/frontend/src/org/jetbrains/kotlin/descriptors/impl/MutableClassDescriptor.java b/compiler/frontend/src/org/jetbrains/kotlin/descriptors/impl/MutableClassDescriptor.java index 9fff1ae4d99..af844e04472 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/descriptors/impl/MutableClassDescriptor.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/descriptors/impl/MutableClassDescriptor.java @@ -48,7 +48,8 @@ public class MutableClassDescriptor extends ClassDescriptorBase implements Class private final Set properties = Sets.newLinkedHashSet(); private final Set functions = Sets.newLinkedHashSet(); - private final WritableScope scopeForMemberResolution; + private final WritableScope writableScopeForMemberResolution; + private final JetScope scopeForMemberResolution; // This scope contains type parameters but does not contain inner classes private final WritableScope scopeForSupertypeResolution; private WritableScope scopeForInitializers; //contains members + primary constructor value parameters + map for backing fields @@ -75,15 +76,15 @@ public class MutableClassDescriptor extends ClassDescriptorBase implements Class .changeLockLevel(WritableScope.LockLevel.BOTH)); this.scopeForSupertypeResolution = new WritableScopeImpl(outerScope, this, redeclarationHandler, "SupertypeResolution") .changeLockLevel(WritableScope.LockLevel.BOTH); - this.scopeForMemberResolution = new WritableScopeImpl(scopeForSupertypeResolution, this, redeclarationHandler, "MemberResolution") + this.writableScopeForMemberResolution = new WritableScopeImpl(scopeForSupertypeResolution, this, redeclarationHandler, "MemberResolution") .changeLockLevel(WritableScope.LockLevel.BOTH); if (kind == ClassKind.INTERFACE) { setUpScopeForInitializers(this); } - scopeForMemberResolution.importScope(staticScope); - scopeForMemberResolution.addLabeledDeclaration(this); + this.scopeForMemberResolution = new ChainedScope(this, "MemberResolutionWithStatic", writableScopeForMemberResolution, staticScope); + writableScopeForMemberResolution.addLabeledDeclaration(this); } @Nullable @@ -227,7 +228,7 @@ public class MutableClassDescriptor extends ClassDescriptorBase implements Class for (FunctionDescriptor functionDescriptor : getConstructors()) { ((ConstructorDescriptorImpl) functionDescriptor).setReturnType(getDefaultType()); } - scopeForMemberResolution.setImplicitReceiver(getThisAsReceiverParameter()); + writableScopeForMemberResolution.setImplicitReceiver(getThisAsReceiverParameter()); } @Override diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/scopes/WritableScope.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/scopes/WritableScope.kt index 28e2154ba6d..78aba76d8da 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/scopes/WritableScope.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/scopes/WritableScope.kt @@ -37,8 +37,6 @@ public trait WritableScope : JetScope { public fun addClassifierDescriptor(classifierDescriptor: ClassifierDescriptor) - public fun importScope(imported: JetScope) - public fun setImplicitReceiver(implicitReceiver: ReceiverParameterDescriptor) } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/scopes/WritableScopeImpl.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/scopes/WritableScopeImpl.kt index 5c58dcb00f1..2e11f8b9192 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/scopes/WritableScopeImpl.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/scopes/WritableScopeImpl.kt @@ -28,15 +28,14 @@ import com.intellij.util.SmartList // Reads from: // 1. Maps // 2. Worker -// 3. Imports // Writes to: maps -public class WritableScopeImpl(scope: JetScope, +public class WritableScopeImpl(override val workerScope: JetScope, private val ownerDeclarationDescriptor: DeclarationDescriptor, - redeclarationHandler: RedeclarationHandler, - debugName: String) -: WritableScopeWithImports(scope, redeclarationHandler, debugName) { + protected val redeclarationHandler: RedeclarationHandler, + private val debugName: String) +: AbstractScopeAdapter(), WritableScope { private val explicitlyAddedDescriptors = SmartList() private val declaredDescriptorsAccessibleBySimpleName = HashMultimap.create() @@ -53,11 +52,30 @@ public class WritableScopeImpl(scope: JetScope, private var implicitReceiver: ReceiverParameterDescriptor? = null + private var implicitReceiverHierarchy: List? = null + override fun getContainingDeclaration(): DeclarationDescriptor = ownerDeclarationDescriptor - override fun importScope(imported: JetScope) { - checkMayWrite() - super.importScope(imported) + private var lockLevel: WritableScope.LockLevel = WritableScope.LockLevel.WRITING + + override fun changeLockLevel(lockLevel: WritableScope.LockLevel): WritableScope { + if (lockLevel.ordinal() < this.lockLevel.ordinal()) { + throw IllegalStateException("cannot lower lock level from " + this.lockLevel + " to " + lockLevel + " at " + toString()) + } + this.lockLevel = lockLevel + return this + } + + protected fun checkMayRead() { + if (lockLevel != WritableScope.LockLevel.READING && lockLevel != WritableScope.LockLevel.BOTH) { + throw IllegalStateException("cannot read with lock level " + lockLevel + " at " + toString()) + } + } + + protected fun checkMayWrite() { + if (lockLevel != WritableScope.LockLevel.WRITING && lockLevel != WritableScope.LockLevel.BOTH) { + throw IllegalStateException("cannot write with lock level " + lockLevel + " at " + toString()) + } } override fun getDescriptors(kindFilter: DescriptorKindFilter, @@ -68,7 +86,6 @@ public class WritableScopeImpl(scope: JetScope, val result = ArrayList() result.addAll(explicitlyAddedDescriptors) result.addAll(workerScope.getDescriptors(kindFilter, nameFilter)) - getImports().flatMapTo(result) { it.getDescriptors(kindFilter, nameFilter) } return result } @@ -82,9 +99,8 @@ public class WritableScopeImpl(scope: JetScope, override fun getDeclarationsByLabel(labelName: Name): Collection { checkMayRead() - val superResult = super.getDeclarationsByLabel(labelName) - val declarationDescriptors = getLabelsToDescriptors()[labelName] - if (declarationDescriptors == null) return superResult + val superResult = super.getDeclarationsByLabel(labelName) + val declarationDescriptors = labelsToDescriptors?.get(labelName) ?: return superResult if (superResult.isEmpty()) return declarationDescriptors return declarationDescriptors + superResult } @@ -137,15 +153,13 @@ public class WritableScopeImpl(scope: JetScope, addToDeclared(variableDescriptor) } - override fun getProperties(name: Name): Set { + override fun getProperties(name: Name): Collection { checkMayRead() - val result = Sets.newLinkedHashSet(getPropertyGroups().get(name)) + val propertyGroupsByName = propertyGroups?.get(name) ?: return workerScope.getProperties(name) + val result = Sets.newLinkedHashSet(propertyGroupsByName) result.addAll(workerScope.getProperties(name)) - - result.addAll(super.getProperties(name)) - return result } @@ -157,7 +171,7 @@ public class WritableScopeImpl(scope: JetScope, return descriptor } - return workerScope.getLocalVariable(name) ?: super.getLocalVariable(name) + return workerScope.getLocalVariable(name) } private fun getPropertyGroups(): SetMultimap { @@ -184,12 +198,10 @@ public class WritableScopeImpl(scope: JetScope, override fun getFunctions(name: Name): Collection { checkMayRead() - val result = Sets.newLinkedHashSet(getFunctionGroups().get(name)) + val functionGroupByName = functionGroups?.get(name) ?: return workerScope.getFunctions(name) + val result = Sets.newLinkedHashSet(functionGroupByName) result.addAll(workerScope.getFunctions(name)) - - result.addAll(super.getFunctions(name)) - return result } @@ -228,7 +240,6 @@ public class WritableScopeImpl(scope: JetScope, return getVariableOrClassDescriptors()[name] as? ClassifierDescriptor ?: workerScope.getClassifier(name) - ?: super.getClassifier(name) } override fun getPackage(name: Name): PackageViewDescriptor? { @@ -236,7 +247,6 @@ public class WritableScopeImpl(scope: JetScope, return getPackageAliases().get(name) ?: workerScope.getPackage(name) - ?: super.getPackage(name) } override fun setImplicitReceiver(implicitReceiver: ReceiverParameterDescriptor) { @@ -248,11 +258,20 @@ public class WritableScopeImpl(scope: JetScope, this.implicitReceiver = implicitReceiver } - override fun computeImplicitReceiversHierarchy(): List { + override fun getImplicitReceiversHierarchy(): List { + checkMayRead() + + if (implicitReceiverHierarchy == null) { + implicitReceiverHierarchy = computeImplicitReceiversHierarchy() + } + return implicitReceiverHierarchy!! + } + + private fun computeImplicitReceiversHierarchy(): List { return if (implicitReceiver != null) - listOf(implicitReceiver!!) + super.computeImplicitReceiversHierarchy() + listOf(implicitReceiver!!) + super.getImplicitReceiversHierarchy() else - super.computeImplicitReceiversHierarchy() + super.getImplicitReceiversHierarchy() } private fun addToDeclared(descriptor: DeclarationDescriptor) { @@ -262,6 +281,20 @@ public class WritableScopeImpl(scope: JetScope, override fun getOwnDeclaredDescriptors(): Collection = declaredDescriptorsAccessibleBySimpleName.values() - override fun printAdditionalScopeStructure(p: Printer) { + override fun toString(): String { + return javaClass.getSimpleName() + "@" + Integer.toHexString(System.identityHashCode(this)) + " " + debugName + " for " + getContainingDeclaration() + } + + override fun printScopeStructure(p: Printer) { + p.println(javaClass.getSimpleName(), ": ", debugName, " for ", getContainingDeclaration(), " {") + p.pushIndent() + + p.println("lockLevel = ", lockLevel) + + p.print("worker = ") + workerScope.printScopeStructure(p.withholdIndentOnce()) + + p.popIndent() + p.println("}") } } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/scopes/WritableScopeWithImports.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/scopes/WritableScopeWithImports.kt deleted file mode 100644 index 9c63501fe0a..00000000000 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/scopes/WritableScopeWithImports.kt +++ /dev/null @@ -1,190 +0,0 @@ -/* - * Copyright 2010-2015 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.kotlin.resolve.scopes - -import com.google.common.collect.Lists -import com.google.common.collect.Sets -import org.jetbrains.kotlin.descriptors.* -import org.jetbrains.kotlin.name.Name -import org.jetbrains.kotlin.utils.Printer - -import java.util.* - -public abstract class WritableScopeWithImports(override val workerScope: JetScope, - protected val redeclarationHandler: RedeclarationHandler, - private val debugName: String) : AbstractScopeAdapter(), WritableScope { - - private var imports: MutableList? = null - private var currentIndividualImportScope: WritableScope? = null - private var implicitReceiverHierarchy: List? = null - - - private var lockLevel: WritableScope.LockLevel = WritableScope.LockLevel.WRITING - - override fun changeLockLevel(lockLevel: WritableScope.LockLevel): WritableScope { - if (lockLevel.ordinal() < this.lockLevel.ordinal()) { - throw IllegalStateException("cannot lower lock level from " + this.lockLevel + " to " + lockLevel + " at " + toString()) - } - this.lockLevel = lockLevel - return this - } - - protected fun checkMayRead() { - if (lockLevel != WritableScope.LockLevel.READING && lockLevel != WritableScope.LockLevel.BOTH) { - throw IllegalStateException("cannot read with lock level " + lockLevel + " at " + toString()) - } - } - - protected fun checkMayWrite() { - if (lockLevel != WritableScope.LockLevel.WRITING && lockLevel != WritableScope.LockLevel.BOTH) { - throw IllegalStateException("cannot write with lock level " + lockLevel + " at " + toString()) - } - } - - protected fun getImports(): MutableList { - if (imports == null) { - imports = ArrayList() - } - return imports!! - } - - override fun importScope(imported: JetScope) { - if (imported == this) { - throw IllegalStateException("cannot import scope into self") - } - - checkMayWrite() - - getImports().add(0, imported) - currentIndividualImportScope = null - } - - override fun getImplicitReceiversHierarchy(): List { - checkMayRead() - - if (implicitReceiverHierarchy == null) { - implicitReceiverHierarchy = computeImplicitReceiversHierarchy() - } - return implicitReceiverHierarchy!! - } - - protected open fun computeImplicitReceiversHierarchy(): List { - val implicitReceiverHierarchy = Lists.newArrayList() - // Imported scopes come with their receivers - // Example: class member resolution scope imports a scope of it's companion object - // members of the companion object must be able to find it as an implicit receiver - for (scope in getImports()) { - implicitReceiverHierarchy.addAll(scope.getImplicitReceiversHierarchy()) - } - implicitReceiverHierarchy.addAll(super.getImplicitReceiversHierarchy()) - return implicitReceiverHierarchy - } - - override fun getProperties(name: Name): Set { - checkMayRead() - - val properties = Sets.newLinkedHashSet() - for (imported in getImports()) { - properties.addAll(imported.getProperties(name)) - } - return properties - } - - override fun getLocalVariable(name: Name): VariableDescriptor? { - checkMayRead() - - // Meaningful lookup goes here - for (imported in getImports()) { - val importedDescriptor = imported.getLocalVariable(name) - if (importedDescriptor != null) { - return importedDescriptor - } - } - return null - } - - override fun getFunctions(name: Name): Collection { - checkMayRead() - - if (getImports().isEmpty()) { - return setOf() - } - val result = Sets.newLinkedHashSet() - for (imported in getImports()) { - result.addAll(imported.getFunctions(name)) - } - return result - } - - override fun getClassifier(name: Name): ClassifierDescriptor? { - checkMayRead() - - for (imported in getImports()) { - val importedClassifier = imported.getClassifier(name) - if (importedClassifier != null) { - return importedClassifier - } - } - return null - } - - override fun getPackage(name: Name): PackageViewDescriptor? { - checkMayRead() - - for (imported in getImports()) { - val importedDescriptor = imported.getPackage(name) - if (importedDescriptor != null) { - return importedDescriptor - } - } - return null - } - - override fun toString(): String { - return javaClass.getSimpleName() + "@" + Integer.toHexString(System.identityHashCode(this)) + " " + debugName + " for " + getContainingDeclaration() - } - - override fun printScopeStructure(p: Printer) { - p.println(javaClass.getSimpleName(), ": ", debugName, " for ", getContainingDeclaration(), " {") - p.pushIndent() - - p.println("lockLevel = ", lockLevel) - - printAdditionalScopeStructure(p) - - p.print("worker = ") - workerScope.printScopeStructure(p.withholdIndentOnce()) - - if (getImports().isEmpty()) { - p.println("imports = {}") - } - else { - p.println("imports = {") - p.pushIndent() - for (anImport in getImports()) { - anImport.printScopeStructure(p) - } - p.popIndent() - p.println("}") - } - - p.popIndent() - p.println("}") - } - - protected abstract fun printAdditionalScopeStructure(p: Printer) -} diff --git a/compiler/tests/org/jetbrains/kotlin/jvm/runtime/AbstractJvmRuntimeDescriptorLoaderTest.kt b/compiler/tests/org/jetbrains/kotlin/jvm/runtime/AbstractJvmRuntimeDescriptorLoaderTest.kt index 67f3cee5644..e5207d3b0fd 100644 --- a/compiler/tests/org/jetbrains/kotlin/jvm/runtime/AbstractJvmRuntimeDescriptorLoaderTest.kt +++ b/compiler/tests/org/jetbrains/kotlin/jvm/runtime/AbstractJvmRuntimeDescriptorLoaderTest.kt @@ -33,10 +33,7 @@ import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.renderer.DescriptorRenderer import org.jetbrains.kotlin.renderer.DescriptorRendererBuilder import org.jetbrains.kotlin.resolve.DescriptorUtils -import org.jetbrains.kotlin.resolve.scopes.JetScope -import org.jetbrains.kotlin.resolve.scopes.RedeclarationHandler -import org.jetbrains.kotlin.resolve.scopes.WritableScope -import org.jetbrains.kotlin.resolve.scopes.WritableScopeImpl +import org.jetbrains.kotlin.resolve.scopes.* import org.jetbrains.kotlin.serialization.deserialization.findClassAcrossModuleDependencies import org.jetbrains.kotlin.test.* import org.jetbrains.kotlin.test.JetTestUtils.TestFileFactoryNoModules @@ -133,14 +130,12 @@ public abstract class AbstractJvmRuntimeDescriptorLoaderTest : TestCaseWithTmpdi private fun createReflectedPackageView(classLoader: URLClassLoader): SyntheticPackageViewForTest { val module = RuntimeModuleData.create(classLoader).module - // Since runtime package view descriptor doesn't support getAllDescriptors(), we construct a synthetic package view here. - // It has in its scope descriptors for all the classes and top level members generated by the compiler - val actual = SyntheticPackageViewForTest(module) - val scope = actual.getMemberScope() val generatedPackageDir = File(tmpdir, LoadDescriptorUtil.TEST_PACKAGE_FQNAME.pathSegments().single().asString()) val allClassFiles = FileUtil.findFilesByMask(Pattern.compile(".*\\.class"), generatedPackageDir) + val packageScopes = arrayListOf() + val classes = arrayListOf() for (classFile in allClassFiles) { val className = tmpdir.relativePath(classFile).substringBeforeLast(".class").replace('/', '.').replace('\\', '.') @@ -148,8 +143,8 @@ public abstract class AbstractJvmRuntimeDescriptorLoaderTest : TestCaseWithTmpdi val header = ReflectKotlinClass.create(klass)?.getClassHeader() if (header?.kind == KotlinClassHeader.Kind.PACKAGE_FACADE) { - val packageView = module.getPackage(actual.getFqName()).sure { "Couldn't resolve package ${actual.getFqName()}" } - scope.importScope(packageView.getMemberScope()) + val packageView = module.getPackage(LoadDescriptorUtil.TEST_PACKAGE_FQNAME).sure { "Couldn't resolve package ${LoadDescriptorUtil.TEST_PACKAGE_FQNAME}" } + packageScopes.add(packageView.getMemberScope()) } else if (header == null || (header.kind == KotlinClassHeader.Kind.CLASS && header.classKind == JvmAnnotationNames.KotlinClass.Kind.CLASS)) { @@ -158,11 +153,15 @@ public abstract class AbstractJvmRuntimeDescriptorLoaderTest : TestCaseWithTmpdi if (!classId.isLocal()) { val classDescriptor = module.findClassAcrossModuleDependencies(classId).sure { "Couldn't resolve class $className" } if (DescriptorUtils.isTopLevelDeclaration(classDescriptor)) { - scope.addClassifierDescriptor(classDescriptor) + classes.add(classDescriptor) } } } } + + // Since runtime package view descriptor doesn't support getAllDescriptors(), we construct a synthetic package view here. + // It has in its scope descriptors for all the classes and top level members generated by the compiler + val actual = SyntheticPackageViewForTest(module, packageScopes, classes) return actual } @@ -180,11 +179,16 @@ public abstract class AbstractJvmRuntimeDescriptorLoaderTest : TestCaseWithTmpdi ) } - private class SyntheticPackageViewForTest(private val module: ModuleDescriptor) : PackageViewDescriptor { - private val scope = WritableScopeImpl(JetScope.Empty, this, RedeclarationHandler.THROW_EXCEPTION, "runtime descriptor loader test") + private class SyntheticPackageViewForTest(private val module: ModuleDescriptor, + packageScopes: List, + classes: List) : PackageViewDescriptor { + private val scope: JetScope init { - scope.changeLockLevel(WritableScope.LockLevel.BOTH) + val writableScope = WritableScopeImpl(JetScope.Empty, this, RedeclarationHandler.THROW_EXCEPTION, "runtime descriptor loader test") + classes.forEach { writableScope.addClassifierDescriptor(it) } + writableScope.changeLockLevel(WritableScope.LockLevel.READING) + scope = ChainedScope(null, "", *(listOf(writableScope) + packageScopes).toTypedArray()) } override fun getFqName() = LoadDescriptorUtil.TEST_PACKAGE_FQNAME diff --git a/compiler/tests/org/jetbrains/kotlin/types/JetTypeCheckerTest.java b/compiler/tests/org/jetbrains/kotlin/types/JetTypeCheckerTest.java index ef3f0a4be91..14784611076 100644 --- a/compiler/tests/org/jetbrains/kotlin/types/JetTypeCheckerTest.java +++ b/compiler/tests/org/jetbrains/kotlin/types/JetTypeCheckerTest.java @@ -591,7 +591,7 @@ public class JetTypeCheckerTest extends JetLiteFixture { assertEquals(expectedType, type); } - private WritableScope getDeclarationsScope(String path) throws IOException { + private JetScope getDeclarationsScope(String path) throws IOException { ModuleDescriptor moduleDescriptor = LazyResolveTestUtil.resolve( getProject(), Collections.singletonList(JetTestUtils.loadJetFile(getProject(), new File(path))) @@ -604,15 +604,18 @@ public class JetTypeCheckerTest extends JetLiteFixture { } @SuppressWarnings("ConstantConditions") - private WritableScopeImpl addImports(JetScope scope) { + private JetScope addImports(JetScope scope) { WritableScopeImpl writableScope = new WritableScopeImpl( scope, scope.getContainingDeclaration(), RedeclarationHandler.DO_NOTHING, "JetTypeCheckerTest.addImports" ); + List scopeChain = new ArrayList(); + scopeChain.add(writableScope); + ModuleDescriptor module = LazyResolveTestUtil.resolveProject(getProject()); for (ImportPath defaultImport : module.getDefaultImports()) { FqName fqName = defaultImport.fqnPart(); if (defaultImport.isAllUnder()) { - writableScope.importScope(module.getPackage(fqName).getMemberScope()); + scopeChain.add(module.getPackage(fqName).getMemberScope()); } else { Name shortName = fqName.shortName(); @@ -620,9 +623,9 @@ public class JetTypeCheckerTest extends JetLiteFixture { writableScope.addClassifierDescriptor(module.getPackage(fqName.parent()).getMemberScope().getClassifier(shortName)); } } - writableScope.importScope(module.getPackage(FqName.ROOT).getMemberScope()); + scopeChain.add(module.getPackage(FqName.ROOT).getMemberScope()); writableScope.changeLockLevel(WritableScope.LockLevel.BOTH); - return writableScope; + return new ChainedScope(scope.getContainingDeclaration(), "", scopeChain.toArray(new JetScope[scopeChain.size()])); } private JetType makeType(String typeStr) {