From c325230a37cd5893bc53c6e7df2fcb39d7f1bd8b Mon Sep 17 00:00:00 2001 From: Valentin Kipyatkov Date: Thu, 23 Oct 2014 12:27:55 +0400 Subject: [PATCH] Converted LazyImportScopy to Kotlin --- .../lang/resolve/lazy/LazyImportScope.java | 356 ------------------ .../jet/lang/resolve/lazy/LazyImportScope.kt | 220 +++++++++++ .../jet/lang/resolve/lazy/ScopeProvider.java | 2 +- 3 files changed, 221 insertions(+), 357 deletions(-) delete mode 100644 compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/LazyImportScope.java create mode 100644 compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/LazyImportScope.kt diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/LazyImportScope.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/LazyImportScope.java deleted file mode 100644 index 04eeaa924b4..00000000000 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/LazyImportScope.java +++ /dev/null @@ -1,356 +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.resolve.lazy; - -import com.google.common.collect.Lists; -import com.google.common.collect.Sets; -import kotlin.Function0; -import kotlin.Function1; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import org.jetbrains.jet.lang.descriptors.*; -import org.jetbrains.jet.lang.psi.JetCodeFragment; -import org.jetbrains.jet.lang.psi.JetFile; -import org.jetbrains.jet.lang.psi.JetImportDirective; -import org.jetbrains.jet.lang.psi.JetImportList; -import org.jetbrains.jet.lang.psi.debugText.DebugTextPackage; -import org.jetbrains.jet.lang.resolve.BindingTrace; -import org.jetbrains.jet.lang.resolve.Importer; -import org.jetbrains.jet.lang.resolve.ImportsResolver; -import org.jetbrains.jet.lang.resolve.JetModuleUtil; -import org.jetbrains.jet.lang.resolve.name.Name; -import org.jetbrains.jet.lang.resolve.scopes.*; -import org.jetbrains.jet.storage.MemoizedFunctionToNotNull; -import org.jetbrains.jet.utils.Printer; - -import java.util.Collection; -import java.util.Collections; -import java.util.List; -import java.util.Set; - -import static org.jetbrains.jet.lang.resolve.QualifiedExpressionResolver.LookupMode; - -public class LazyImportScope implements JetScope, LazyEntity { - private final ResolveSession resolveSession; - private final PackageViewDescriptor packageDescriptor; - private final ImportsProvider importsProvider; - private final JetScope rootScope; - private final BindingTrace traceForImportResolve; - private final String debugName; - - private static class ImportResolveStatus { - private final LookupMode lookupMode; - private final JetScope scope; - private final Collection descriptors; - - ImportResolveStatus(LookupMode lookupMode, JetScope scope, Collection descriptors) { - this.lookupMode = lookupMode; - this.scope = scope; - this.descriptors = descriptors; - } - } - - private class ImportDirectiveResolveCache { - private final JetImportDirective directive; - - @Nullable - private volatile ImportResolveStatus importResolveStatus; - - private ImportDirectiveResolveCache(JetImportDirective directive) { - this.directive = directive; - } - - private JetScope scopeForMode(final LookupMode mode) { - ImportResolveStatus status = importResolveStatus; - if (status != null && (status.lookupMode == mode || status.lookupMode == LookupMode.EVERYTHING)) { - return status.scope; - } - - return resolveSession.getStorageManager().compute(new Function0() { - @Override - public JetScope invoke() { - ImportResolveStatus cachedStatus = importResolveStatus; - if (cachedStatus != null && (cachedStatus.lookupMode == mode || cachedStatus.lookupMode == LookupMode.EVERYTHING)) { - return cachedStatus.scope; - } - - WritableScope directiveImportScope = new WritableScopeImpl( - JetScope.EMPTY, packageDescriptor, RedeclarationHandler.DO_NOTHING, - "Scope for import '" + DebugTextPackage.getDebugText(directive) + "' resolve in " + toString()); - directiveImportScope.changeLockLevel(WritableScope.LockLevel.BOTH); - - Importer.StandardImporter importer = new Importer.StandardImporter(directiveImportScope); - directiveUnderResolve = directive; - - Collection descriptors; - try { - descriptors = resolveSession.getQualifiedExpressionResolver().processImportReference( - directive, - rootScope, - packageDescriptor.getMemberScope(), - importer, - traceForImportResolve, - resolveSession.getModuleDescriptor(), - mode); - if (mode == LookupMode.EVERYTHING) { - ImportsResolver.checkPlatformTypesMappedToKotlin( - packageDescriptor.getModule(), - traceForImportResolve, - directive, - descriptors - ); - } - } - finally { - directiveUnderResolve = null; - directiveImportScope.changeLockLevel(WritableScope.LockLevel.READING); - } - - importResolveStatus = new ImportResolveStatus(mode, directiveImportScope, descriptors); - return directiveImportScope; - } - }); - } - } - - private final MemoizedFunctionToNotNull importedScopesProvider; - - private JetImportDirective directiveUnderResolve = null; - - public LazyImportScope( - @NotNull ResolveSession resolveSession, - @NotNull PackageViewDescriptor packageDescriptor, - @NotNull List imports, - @NotNull BindingTrace traceForImportResolve, - @NotNull String debugName, - boolean inRootPackage - ) { - this.resolveSession = resolveSession; - this.packageDescriptor = packageDescriptor; - this.importsProvider = new ImportsProvider(resolveSession.getStorageManager(), imports); - this.traceForImportResolve = traceForImportResolve; - this.debugName = debugName; - - this.importedScopesProvider = resolveSession.getStorageManager().createMemoizedFunction(new Function1() { - @Override - public ImportDirectiveResolveCache invoke(JetImportDirective directive) { - return new ImportDirectiveResolveCache(directive); - } - }); - - this.rootScope = JetModuleUtil.getImportsResolutionScope(resolveSession.getModuleDescriptor(), inRootPackage); - } - - public static LazyImportScope createImportScopeForFile( - @NotNull ResolveSession resolveSession, - @NotNull PackageViewDescriptor packageDescriptor, - @NotNull JetFile jetFile, - @NotNull BindingTrace traceForImportResolve, - @NotNull String debugName - ) { - List importDirectives; - if (jetFile instanceof JetCodeFragment) { - JetImportList importList = ((JetCodeFragment) jetFile).importsAsImportList(); - importDirectives = importList != null ? importList.getImports() : Collections.emptyList(); - } - else { - importDirectives = jetFile.getImportDirectives(); - } - - return new LazyImportScope( - resolveSession, - packageDescriptor, - Lists.reverse(importDirectives), - traceForImportResolve, - debugName, - packageDescriptor.getFqName().isRoot()); - } - - @Override - public void forceResolveAllContents() { - for (JetImportDirective importDirective : importsProvider.getAllImports()) { - forceResolveImportDirective(importDirective); - } - } - - public void forceResolveImportDirective(@NotNull JetImportDirective importDirective) { - getImportScope(importDirective, LookupMode.EVERYTHING); - - ImportResolveStatus status = importedScopesProvider.invoke(importDirective).importResolveStatus; - if (status != null && !status.descriptors.isEmpty()) { - JetScope fileScope = resolveSession.getScopeProvider().getFileScope(importDirective.getContainingJetFile()); - ImportsResolver.reportUselessImport(importDirective, fileScope, status.descriptors, traceForImportResolve); - } - } - - @Nullable - private D selectFirstFromImports( - final Name name, - final LookupMode lookupMode, - final JetScopeSelectorUtil.ScopeByNameSelector descriptorSelector - ) { - return resolveSession.getStorageManager().compute(new Function0() { - @Override - public D invoke() { - for (JetImportDirective directive : importsProvider.getImports(name)) { - if (directive == directiveUnderResolve) { - // This is the recursion in imports analysis - return null; - } - - D foundDescriptor = descriptorSelector.get(getImportScope(directive, lookupMode), name); - if (foundDescriptor != null) { - return foundDescriptor; - } - } - - return null; - } - }); - } - - @NotNull - private Collection collectFromImports( - final Name name, - final LookupMode lookupMode, - final JetScopeSelectorUtil.ScopeByNameMultiSelector descriptorsSelector - ) { - return resolveSession.getStorageManager().compute(new Function0>() { - @Override - public Collection invoke() { - Set descriptors = Sets.newHashSet(); - for (JetImportDirective directive : importsProvider.getImports(name)) { - if (directive == directiveUnderResolve) { - // This is the recursion in imports analysis - throw new IllegalStateException("Recursion while resolving many imports: " + directive.getText()); - } - - descriptors.addAll(descriptorsSelector.get(getImportScope(directive, lookupMode), name)); - } - - return descriptors; - } - }); - } - - @NotNull - private Collection collectFromImports( - final LookupMode lookupMode, - final JetScopeSelectorUtil.ScopeDescriptorSelector descriptorsSelector - ) { - return resolveSession.getStorageManager().compute(new Function0>() { - @Override - public Collection invoke() { - Set descriptors = Sets.newHashSet(); - for (JetImportDirective directive : importsProvider.getAllImports()) { - if (directive == directiveUnderResolve) { - // This is the recursion in imports analysis - throw new IllegalStateException("Recursion while resolving many imports: " + directive.getText()); - } - - descriptors.addAll(descriptorsSelector.get(getImportScope(directive, lookupMode))); - } - - return descriptors; - } - }); - } - - @NotNull - private JetScope getImportScope(JetImportDirective directive, LookupMode lookupMode) { - return importedScopesProvider.invoke(directive).scopeForMode(lookupMode); - } - - @Nullable - @Override - public ClassifierDescriptor getClassifier(@NotNull Name name) { - return selectFirstFromImports(name, LookupMode.ONLY_CLASSES, JetScopeSelectorUtil.CLASSIFIER_DESCRIPTOR_SCOPE_SELECTOR); - } - - @Nullable - @Override - public PackageViewDescriptor getPackage(@NotNull Name name) { - return selectFirstFromImports(name, LookupMode.ONLY_CLASSES, JetScopeSelectorUtil.PACKAGE_SCOPE_SELECTOR); - } - - @NotNull - @Override - public Collection getProperties(@NotNull Name name) { - return collectFromImports(name, LookupMode.EVERYTHING, JetScopeSelectorUtil.NAMED_PROPERTIES_SCOPE_SELECTOR); - } - - @Nullable - @Override - public VariableDescriptor getLocalVariable(@NotNull Name name) { - return null; - } - - @NotNull - @Override - public Collection getFunctions(@NotNull Name name) { - return collectFromImports(name, LookupMode.EVERYTHING, JetScopeSelectorUtil.NAMED_FUNCTION_SCOPE_SELECTOR); - } - - @NotNull - @Override - public DeclarationDescriptor getContainingDeclaration() { - return packageDescriptor; - } - - @NotNull - @Override - public Collection getDeclarationsByLabel(@NotNull Name labelName) { - return Collections.emptyList(); - } - - @NotNull - @Override - public Collection getAllDescriptors() { - return collectFromImports(LookupMode.EVERYTHING, JetScopeSelectorUtil.ALL_DESCRIPTORS_SCOPE_SELECTOR); - } - - @NotNull - @Override - public List getImplicitReceiversHierarchy() { - return Collections.emptyList(); - } - - @NotNull - @Override - public Collection getOwnDeclaredDescriptors() { - return Collections.emptyList(); - } - - @Override - public String toString() { - return "LazyImportScope: " + debugName; - } - - @Override - public void printScopeStructure(@NotNull Printer p) { - p.println(getClass().getSimpleName(), ": ", debugName, " {"); - p.pushIndent(); - - p.println("packageDescriptor = ", packageDescriptor); - - p.print("rootScope = "); - rootScope.printScopeStructure(p.withholdIndentOnce()); - - p.popIndent(); - p.println("}"); - } -} diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/LazyImportScope.kt b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/LazyImportScope.kt new file mode 100644 index 00000000000..919cb9b27b7 --- /dev/null +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/LazyImportScope.kt @@ -0,0 +1,220 @@ +/* + * 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.resolve.lazy + +import com.google.common.collect.Sets +import org.jetbrains.jet.lang.descriptors.* +import org.jetbrains.jet.lang.psi.JetCodeFragment +import org.jetbrains.jet.lang.psi.JetFile +import org.jetbrains.jet.lang.psi.JetImportDirective +import org.jetbrains.jet.lang.psi.debugText.* +import org.jetbrains.jet.lang.resolve.BindingTrace +import org.jetbrains.jet.lang.resolve.Importer +import org.jetbrains.jet.lang.resolve.ImportsResolver +import org.jetbrains.jet.lang.resolve.JetModuleUtil +import org.jetbrains.jet.lang.resolve.name.Name +import org.jetbrains.jet.lang.resolve.scopes.* +import org.jetbrains.jet.storage.MemoizedFunctionToNotNull +import org.jetbrains.jet.utils.Printer + +import org.jetbrains.jet.lang.resolve.QualifiedExpressionResolver.LookupMode + +public class LazyImportScope(private val resolveSession: ResolveSession, + private val containingDeclaration: PackageViewDescriptor, + imports: List, + private val traceForImportResolve: BindingTrace, + private val debugName: String, + inRootPackage: Boolean) : JetScope, LazyEntity { + private val importsProvider: ImportsProvider + private val rootScope: JetScope + + private class ImportResolveStatus(val lookupMode: LookupMode, val scope: JetScope, val descriptors: Collection) + + private inner class ImportDirectiveResolveCache(private val directive: JetImportDirective) { + + volatile var importResolveStatus: ImportResolveStatus? = null + + fun scopeForMode(mode: LookupMode): JetScope { + val status = importResolveStatus + if (status != null && (status.lookupMode == mode || status.lookupMode == LookupMode.EVERYTHING)) { + return status.scope + } + + return resolveSession.getStorageManager().compute { + val cachedStatus = importResolveStatus + if (cachedStatus != null && (cachedStatus.lookupMode == mode || cachedStatus.lookupMode == LookupMode.EVERYTHING)) { + cachedStatus.scope + } + else { + val directiveImportScope = WritableScopeImpl(JetScope.EMPTY, containingDeclaration, RedeclarationHandler.DO_NOTHING, "Scope for import '" + directive.getDebugText() + "' resolve in " + toString()) + directiveImportScope.changeLockLevel(WritableScope.LockLevel.BOTH) + + val importer = Importer.StandardImporter(directiveImportScope) + directiveUnderResolve = directive + + val descriptors: Collection + try { + val resolver = resolveSession.getQualifiedExpressionResolver() + descriptors = resolver.processImportReference(directive, rootScope, containingDeclaration.getMemberScope(), + importer, traceForImportResolve, resolveSession.getModuleDescriptor(), mode) + if (mode == LookupMode.EVERYTHING) { + ImportsResolver.checkPlatformTypesMappedToKotlin(containingDeclaration.getModule(), traceForImportResolve, directive, descriptors) + } + } + finally { + directiveUnderResolve = null + directiveImportScope.changeLockLevel(WritableScope.LockLevel.READING) + } + + importResolveStatus = ImportResolveStatus(mode, directiveImportScope, descriptors) + directiveImportScope + } + } + } + } + + private val importedScopesProvider: MemoizedFunctionToNotNull + + private var directiveUnderResolve: JetImportDirective? = null + + { + this.importsProvider = ImportsProvider(resolveSession.getStorageManager(), imports) + + this.importedScopesProvider = resolveSession.getStorageManager().createMemoizedFunction { ImportDirectiveResolveCache(it) } + + this.rootScope = JetModuleUtil.getImportsResolutionScope(resolveSession.getModuleDescriptor(), inRootPackage) + } + + override fun forceResolveAllContents() { + for (importDirective in importsProvider.getAllImports()) { + forceResolveImportDirective(importDirective) + } + } + + public fun forceResolveImportDirective(importDirective: JetImportDirective) { + getImportScope(importDirective, LookupMode.EVERYTHING) + + val status = importedScopesProvider(importDirective).importResolveStatus + if (status != null && !status.descriptors.isEmpty()) { + val fileScope = resolveSession.getScopeProvider().getFileScope(importDirective.getContainingJetFile()) + ImportsResolver.reportUselessImport(importDirective, fileScope, status.descriptors, traceForImportResolve) + } + } + + private fun selectFirstFromImports(name: Name, lookupMode: LookupMode, descriptorSelector: JetScopeSelectorUtil.ScopeByNameSelector): D? { + fun compute(): D? { + for (directive in importsProvider.getImports(name)) { + if (directive == directiveUnderResolve) { + // This is the recursion in imports analysis + return null + } + + val foundDescriptor = descriptorSelector.get(getImportScope(directive, lookupMode), name) + if (foundDescriptor != null) { + return foundDescriptor + } + } + + return null + } + return resolveSession.getStorageManager().compute(::compute) + } + + private fun collectFromImports(name: Name, lookupMode: LookupMode, descriptorsSelector: JetScopeSelectorUtil.ScopeByNameMultiSelector): Collection { + return resolveSession.getStorageManager().compute { + val descriptors = Sets.newHashSet() + for (directive in importsProvider.getImports(name)) { + if (directive == directiveUnderResolve) { + // This is the recursion in imports analysis + throw IllegalStateException("Recursion while resolving many imports: " + directive.getText()) + } + + descriptors.addAll(descriptorsSelector.get(getImportScope(directive, lookupMode), name)) + } + + descriptors + } + } + + private fun collectFromImports(lookupMode: LookupMode, descriptorsSelector: JetScopeSelectorUtil.ScopeDescriptorSelector): Collection { + return resolveSession.getStorageManager().compute { + val descriptors = Sets.newHashSet() + for (directive in importsProvider.getAllImports()) { + if (directive == directiveUnderResolve) { + // This is the recursion in imports analysis + throw IllegalStateException("Recursion while resolving many imports: " + directive.getText()) + } + + descriptors.addAll(descriptorsSelector.get(getImportScope(directive, lookupMode))) + } + + descriptors + } + } + + private fun getImportScope(directive: JetImportDirective, lookupMode: LookupMode) = importedScopesProvider(directive).scopeForMode(lookupMode) + + override fun getClassifier(name: Name) = selectFirstFromImports(name, LookupMode.ONLY_CLASSES, JetScopeSelectorUtil.CLASSIFIER_DESCRIPTOR_SCOPE_SELECTOR) + + override fun getPackage(name: Name) = selectFirstFromImports(name, LookupMode.ONLY_CLASSES, JetScopeSelectorUtil.PACKAGE_SCOPE_SELECTOR) + + override fun getProperties(name: Name) = collectFromImports(name, LookupMode.EVERYTHING, JetScopeSelectorUtil.NAMED_PROPERTIES_SCOPE_SELECTOR) + + override fun getLocalVariable(name: Name) = null + + override fun getFunctions(name: Name) = collectFromImports(name, LookupMode.EVERYTHING, JetScopeSelectorUtil.NAMED_FUNCTION_SCOPE_SELECTOR) + + override fun getDeclarationsByLabel(labelName: Name): Collection = listOf() + + override fun getAllDescriptors() = collectFromImports(LookupMode.EVERYTHING, JetScopeSelectorUtil.ALL_DESCRIPTORS_SCOPE_SELECTOR) + + override fun getImplicitReceiversHierarchy(): List = listOf() + + override fun getOwnDeclaredDescriptors(): Collection = listOf() + + override fun getContainingDeclaration() = containingDeclaration + + override fun toString() = "LazyImportScope: " + debugName + + override fun printScopeStructure(p: Printer) { + p.println(javaClass.getSimpleName(), ": ", debugName, " {") + p.pushIndent() + + p.println("packageDescriptor = ", containingDeclaration) + + p.print("rootScope = ") + rootScope.printScopeStructure(p.withholdIndentOnce()) + + p.popIndent() + p.println("}") + } + + class object { + public fun createImportScopeForFile(resolveSession: ResolveSession, packageDescriptor: PackageViewDescriptor, jetFile: JetFile, traceForImportResolve: BindingTrace, debugName: String): LazyImportScope { + val importDirectives: List + if (jetFile is JetCodeFragment) { + val importList = jetFile.importsAsImportList() + importDirectives = if (importList != null) importList.getImports() else listOf() + } + else { + importDirectives = jetFile.getImportDirectives() + } + + return LazyImportScope(resolveSession, packageDescriptor, importDirectives.reverse(), traceForImportResolve, debugName, packageDescriptor.getFqName().isRoot()) + } + } +} diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/ScopeProvider.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/ScopeProvider.java index 82d26d17874..393a26aaf4c 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/ScopeProvider.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/ScopeProvider.java @@ -62,7 +62,7 @@ public class ScopeProvider { } private LazyImportScope createExplicitImportScope(@NotNull JetFile file) { - return LazyImportScope.createImportScopeForFile( + return LazyImportScope.OBJECT$.createImportScopeForFile( resolveSession, getFilePackageDescriptor(file), file,