diff --git a/jps/jps-builders/src/org/jetbrains/jps/builders/java/BackendCallbackToGraphDeltaAdapter.java b/jps/jps-builders/src/org/jetbrains/jps/builders/java/BackendCallbackToGraphDeltaAdapter.java index 35b9aadebce4..3deed5a64e18 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/builders/java/BackendCallbackToGraphDeltaAdapter.java +++ b/jps/jps-builders/src/org/jetbrains/jps/builders/java/BackendCallbackToGraphDeltaAdapter.java @@ -3,6 +3,7 @@ package org.jetbrains.jps.builders.java; import com.intellij.openapi.util.Pair; import com.intellij.util.SmartList; +import kotlinx.metadata.*; import org.jetbrains.jps.builders.java.dependencyView.Callbacks; import org.jetbrains.jps.dependency.*; import org.jetbrains.jps.dependency.java.*; @@ -21,6 +22,7 @@ final class BackendCallbackToGraphDeltaAdapter implements Callbacks.Backend { private final Map> myAdditionalUsages = Collections.synchronizedMap(new HashMap<>()); private final Map> myPerSourceAdditionalUsages = Collections.synchronizedMap(new HashMap<>()); private final List, Iterable>> myNodes = new ArrayList<>(); + private final Map> mySelfUsages = new HashMap<>(); private final GraphConfiguration myGraphConfig; BackendCallbackToGraphDeltaAdapter(GraphConfiguration graphConfig) { @@ -44,30 +46,63 @@ final class BackendCallbackToGraphDeltaAdapter implements Callbacks.Backend { builder.addUsage(usage); } } - for (Usage usage : Iterators.flat(Iterators.map(sources, src -> myPerSourceAdditionalUsages.get(Path.of(src))))) { - builder.addUsage(usage); - } + var node = builder.getResult(); + List nodeSources = Iterators.collect(Iterators.map(sources, myGraphConfig.getPathMapper()::toNodeSource), new SmartList<>()); + + Iterable lookups = Iterators.flat(Iterators.map(node.getMetadata(KotlinMeta.class), meta -> { + KmDeclarationContainer container = meta.getDeclarationContainer(); + final JvmNodeReferenceID owner; + LookupNameUsage clsUsage = null; + if (container instanceof KmPackage) { + owner = new JvmNodeReferenceID(JvmClass.getPackageName(node.getName())); + } + else if (container instanceof KmClass) { + owner = new JvmNodeReferenceID(((KmClass)container).getName()); + String ownerName = owner.getNodeName(); + String scopeName = JvmClass.getPackageName(ownerName); + String symbolName = scopeName.isEmpty()? ownerName : ownerName.substring(scopeName.length() + 1); + clsUsage = new LookupNameUsage(scopeName, symbolName); + } + else { + owner = null; + } + if (owner == null) { + return Collections.emptyList(); + } + Iterable memberLookups = + Iterators.map(Iterators.unique(Iterators.flat(Iterators.map(container.getFunctions(), KmFunction::getName), Iterators.map(container.getProperties(), KmProperty::getName))), name -> new LookupNameUsage(owner, name)); + return clsUsage == null? memberLookups : Iterators.flat(Iterators.asIterable(clsUsage), memberLookups); + })); + + for (LookupNameUsage lookup : lookups) { + for (NodeSource src : nodeSources) { + mySelfUsages.computeIfAbsent(src, s -> new HashSet<>()).add(lookup); + } + } + if (!node.isPrivate()) { - myNodes.add(new Pair<>(node, Iterators.collect(Iterators.map(sources, myGraphConfig.getPathMapper()::toNodeSource), new SmartList<>()))); + myNodes.add(new Pair<>(node, nodeSources)); } } public List, Iterable>> getNodes() { - try { + + if (!myPerSourceAdditionalUsages.isEmpty()) { NodeSourcePathMapper pathMapper = myGraphConfig.getPathMapper(); - for (NodeSource source : Iterators.flat(Iterators.map(myNodes, p -> p.getSecond()))) { - myPerSourceAdditionalUsages.remove(pathMapper.toPath(source)); - } for (Map.Entry> entry : myPerSourceAdditionalUsages.entrySet()) { NodeSource src = pathMapper.toNodeSource(entry.getKey()); - myNodes.add(new Pair<>(new FileNode(src.toString(), entry.getValue()), List.of(src))); + Set usages = entry.getValue(); + Set selfUsages = mySelfUsages.get(src); + if (selfUsages != null) { + usages.removeAll(selfUsages); + } + myNodes.add(new Pair<>(new FileNode(src.toString(), usages), List.of(src))); } - return myNodes; - } - finally { myPerSourceAdditionalUsages.clear(); } + + return myNodes; } @Override diff --git a/jps/jps-builders/src/org/jetbrains/jps/dependency/java/JvmClassNodeBuilder.java b/jps/jps-builders/src/org/jetbrains/jps/dependency/java/JvmClassNodeBuilder.java index 7f541543b71d..ceda085c6902 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/dependency/java/JvmClassNodeBuilder.java +++ b/jps/jps-builders/src/org/jetbrains/jps/dependency/java/JvmClassNodeBuilder.java @@ -5,7 +5,10 @@ import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.util.Ref; import com.intellij.util.ArrayUtil; import com.intellij.util.SmartList; -import kotlinx.metadata.*; +import kotlinx.metadata.Attributes; +import kotlinx.metadata.KmDeclarationContainer; +import kotlinx.metadata.KmFunction; +import kotlinx.metadata.KmProperty; import kotlinx.metadata.jvm.JvmExtensionsKt; import kotlinx.metadata.jvm.JvmMethodSignature; import org.jetbrains.annotations.NotNull; @@ -491,27 +494,6 @@ public final class JvmClassNodeBuilder extends ClassVisitor implements NodeBuild } } - // remove own members lookups - KmDeclarationContainer container = findKotlinDeclarationContainer(); - if (container != null) { - JvmNodeReferenceID owner = null; - if (container instanceof KmPackage) { - owner = new JvmNodeReferenceID(JvmClass.getPackageName(myName)); - } - else if (container instanceof KmClass) { - owner = new JvmNodeReferenceID(((KmClass)container).getName()); - String nodeName = owner.getNodeName(); - String scopeName = JvmClass.getPackageName(nodeName); - String symbolName = scopeName.isEmpty()? nodeName : nodeName.substring(scopeName.length() + 1); - myUsages.remove(new LookupNameUsage(scopeName, symbolName)); - } - if (owner != null) { - for (String name : Iterators.unique(Iterators.flat(Iterators.map(container.getFunctions(), KmFunction::getName), Iterators.map(container.getProperties(), KmProperty::getName)))) { - myUsages.remove(new LookupNameUsage(owner, name)); - } - } - } - return new JvmClass(flags, mySignature, myName, myFileName, mySuperClass, myOuterClassName.get(), myInterfaces, myFields, myMethods, myAnnotations, myTargets, myRetentionPolicy, myUsages, myMetadata); }