org.jetbrains.jet.lang.resolve.lazy.ImportsProvider Maven / Gradle / Ivy
/*
* 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.resolve.lazy;
import com.google.common.collect.*;
import kotlin.Function0;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.psi.JetImportDirective;
import org.jetbrains.jet.lang.resolve.ImportPath;
import org.jetbrains.jet.lang.resolve.name.Name;
import org.jetbrains.jet.storage.NotNullLazyValue;
import org.jetbrains.jet.storage.StorageManager;
import java.util.List;
import java.util.Set;
class ImportsProvider {
private final List importDirectives;
private final NotNullLazyValue importsCacheValue;
public ImportsProvider(StorageManager storageManager, final List importDirectives) {
this.importDirectives = importDirectives;
this.importsCacheValue = storageManager.createLazyValue(new Function0() {
@Override
public NameToImportsCache invoke() {
return NameToImportsCache.createIndex(importDirectives);
}
});
}
@NotNull
public List getImports(@NotNull Name name) {
return importsCacheValue.invoke().getImports(name);
}
@NotNull
public List getAllImports() {
return importDirectives;
}
private static class NameToImportsCache {
private final ListMultimap nameToDirectives;
private final List allUnderImports;
private NameToImportsCache(ListMultimap directives, List imports) {
nameToDirectives = directives;
allUnderImports = imports;
}
private List getImports(@NotNull Name name) {
return nameToDirectives.containsKey(name) ? nameToDirectives.get(name) : allUnderImports;
}
private static NameToImportsCache createIndex(List importDirectives) {
ImmutableListMultimap.Builder namesToRelativeImportsBuilder = ImmutableListMultimap.builder();
Set processedAliases = Sets.newHashSet();
List processedAllUnderImports = Lists.newArrayList();
for (JetImportDirective anImport : importDirectives) {
ImportPath path = anImport.getImportPath();
if (path == null) {
// Could be some parse errors
continue;
}
if (path.isAllUnder()) {
processedAllUnderImports.add(anImport);
// All-Under import is relevant to all names found so far
for (Name aliasName : processedAliases) {
namesToRelativeImportsBuilder.put(aliasName, anImport);
}
}
else {
Name aliasName = path.getImportedName();
assert aliasName != null;
if (!processedAliases.contains(aliasName)) {
processedAliases.add(aliasName);
// Add to relevant imports all all-under imports found by this moment
namesToRelativeImportsBuilder.putAll(aliasName, processedAllUnderImports);
}
namesToRelativeImportsBuilder.put(aliasName, anImport);
}
}
return new NameToImportsCache(namesToRelativeImportsBuilder.build(), ImmutableList.copyOf(processedAllUnderImports));
}
}
}