Revert "build dependency graph nodes when registered refs/imports/bytecode data is complete (IDEA-365745)"

This reverts commit 0a458a05ea38bdec8bb3ba0add3d4d62ce0b416d.

GitOrigin-RevId: 1fdd95ffaf559d082c976d4a822cdd33d882eb8d
This commit is contained in:
Dmitriy.Panov
2025-07-11 09:48:17 +00:00
committed by intellij-monorepo-bot
parent 09d271695e
commit 0324972d95
8 changed files with 82 additions and 137 deletions
@@ -1,19 +0,0 @@
Cleaning output files:
out/production/ConstantChain3/Const1.class
End of files
Compiling files:
src/Const1.java
End of files
Cleaning output files:
out/production/ConstantChain3/Const2.class
End of files
Compiling files:
src/Const2.java
End of files
Cleaning output files:
out/production/ConstantChain3/Const3.class
out/production/ConstantChain3/Dummy1.class
End of files
Compiling files:
src/Const3.java
End of files
@@ -1,3 +0,0 @@
public class Const1 {
public static final String A1 = "20";
}
@@ -1,3 +0,0 @@
public class Const1 {
public static final String A1 = "10";
}
@@ -1,3 +0,0 @@
public class Const2 {
public static final String A2 = Const1.A1;
}
@@ -1,14 +0,0 @@
public class Const3 extends Const2 {
public void data() {
Object[][] arr = new Object[][]{{A2}};
}
}
class Dummy1 {
// because of this additional class definition the order of events will be:
// 1. Const3 class generated
// 2. constant refs registered
// compared to the case when only one top-level definition were present in the file:
// 1. constant refs registered
// 2. Const3 class generated
}
@@ -22,8 +22,8 @@ final class BackendCallbackToGraphDeltaAdapter implements Callbacks.Backend {
private final Map<String, Collection<Callbacks.ConstantRef>> myConstantRefs = Collections.synchronizedMap(new HashMap<>());
private final Map<String, Set<Usage>> myAdditionalUsages = Collections.synchronizedMap(new HashMap<>());
private final Map<Path, Set<Usage>> myPerSourceAdditionalUsages = Collections.synchronizedMap(new HashMap<>());
private final List<Pair<JvmClassNodeBuilder, Iterable<NodeSource>>> myNodeBuilders = new ArrayList<>();
private final List<Pair<Node<?, ?>, Iterable<NodeSource>>> myNodes = new ArrayList<>();
private final Map<NodeSource, Set<Usage>> mySelfUsages = new HashMap<>();
private final GraphConfiguration myGraphConfig;
private final boolean reportMissingOutput = Boolean.parseBoolean(System.getProperty("jps.report.registered.unexistent.output"));
@@ -36,81 +36,74 @@ final class BackendCallbackToGraphDeltaAdapter implements Callbacks.Backend {
if (reportMissingOutput && !classFileName.startsWith("$") && !new File(classFileName).exists()) {
throw new RuntimeException("Class file '" + classFileName + "' was registered but it does not exist");
}
myNodeBuilders.add(Pair.create(
JvmClassNodeBuilder.create(classFileName, cr, isGenerated),
Iterators.collect(Iterators.map(sources, myGraphConfig.getPathMapper()::toNodeSource), new SmartList<>())
));
JvmClassNodeBuilder builder = JvmClassNodeBuilder.create(classFileName, cr, isGenerated);
JvmNodeReferenceID nodeID = builder.getReferenceID();
String nodeName = nodeID.getNodeName();
addConstantUsages(builder, nodeName, myConstantRefs.remove(nodeName));
Pair<Collection<String>, Collection<String>> imports = myImportRefs.remove(nodeName);
if (imports != null) {
addImportUsages(builder, imports.getFirst(), imports.getSecond());
}
Set<Usage> additionalUsages = myAdditionalUsages.remove(nodeName);
if (additionalUsages != null) {
for (Usage usage : additionalUsages) {
builder.addUsage(usage);
}
}
var node = builder.getResult();
List<NodeSource> nodeSources = Iterators.collect(Iterators.map(sources, myGraphConfig.getPathMapper()::toNodeSource), new SmartList<>());
Iterable<LookupNameUsage> 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<LookupNameUsage> 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);
}
}
myNodes.add(new Pair<>(node, nodeSources));
}
public List<Pair<Node<?, ?>, Iterable<NodeSource>>> getNodes() {
Map<NodeSource, Set<Usage>> fileLocalUsages = new HashMap<>();
// post-process collected data
for (Pair<JvmClassNodeBuilder, Iterable<NodeSource>> pair : myNodeBuilders) {
JvmClassNodeBuilder builder = pair.getFirst();
Iterable<NodeSource> nodeSources = pair.getSecond();
JvmNodeReferenceID nodeID = builder.getReferenceID();
String nodeName = nodeID.getNodeName();
addConstantUsages(builder, nodeName, myConstantRefs.remove(nodeName));
Pair<Collection<String>, Collection<String>> imports = myImportRefs.remove(nodeName);
if (imports != null) {
addImportUsages(builder, imports.getFirst(), imports.getSecond());
if (!myPerSourceAdditionalUsages.isEmpty()) {
NodeSourcePathMapper pathMapper = myGraphConfig.getPathMapper();
for (Map.Entry<Path, Set<Usage>> entry : myPerSourceAdditionalUsages.entrySet()) {
NodeSource src = pathMapper.toNodeSource(entry.getKey());
Set<Usage> usages = entry.getValue();
Set<Usage> selfUsages = mySelfUsages.get(src);
if (selfUsages != null) {
usages.removeAll(selfUsages);
}
myNodes.add(new Pair<>(new FileNode(src.toString(), usages), List.of(src)));
}
Set<Usage> additionalUsages = myAdditionalUsages.remove(nodeName);
if (additionalUsages != null) {
for (Usage usage : additionalUsages) {
builder.addUsage(usage);
}
}
var node = builder.getResult();
Iterable<LookupNameUsage> 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<LookupNameUsage> 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) {
fileLocalUsages.computeIfAbsent(src, s -> new HashSet<>()).add(lookup);
}
}
myNodes.add(Pair.create(node, nodeSources));
myPerSourceAdditionalUsages.clear();
}
myNodeBuilders.clear();
NodeSourcePathMapper pathMapper = myGraphConfig.getPathMapper();
for (Map.Entry<Path, Set<Usage>> entry : myPerSourceAdditionalUsages.entrySet()) {
NodeSource src = pathMapper.toNodeSource(entry.getKey());
Set<Usage> usages = entry.getValue();
Set<Usage> selfUsages = fileLocalUsages.get(src);
if (selfUsages != null) {
usages.removeAll(selfUsages);
}
myNodes.add(new Pair<>(new FileNode(src.toString(), usages), List.of(src)));
}
myPerSourceAdditionalUsages.clear();
return myNodes;
}
@@ -1300,7 +1300,7 @@ public final class JavaBuilder extends ModuleLevelBuilder {
return map;
}
private final class DiagnosticSink implements DiagnosticOutputConsumer {
private static final class DiagnosticSink implements DiagnosticOutputConsumer {
private final CompileContext myContext;
private final AtomicInteger myErrorCount = new AtomicInteger(0);
private final AtomicInteger myWarningCount = new AtomicInteger(0);
@@ -1318,12 +1318,9 @@ public final class JavaBuilder extends ModuleLevelBuilder {
@Override
public void registerJavacFileData(JavacFileData data) {
// ensure constants-, imports- and file content data is registered in the same sequence it arrives
submitAsyncTask(myContext, () -> {
for (JavacFileReferencesRegistrar registrar : myRegistrars) {
registrar.registerFile(myContext, data.getFilePath(), Iterators.map(data.getRefs().entrySet(), entry -> entry), data.getDefs(), data.getCasts(), data.getImplicitToStringRefs());
}
});
for (JavacFileReferencesRegistrar registrar : myRegistrars) {
registrar.registerFile(myContext, data.getFilePath(), Iterators.map(data.getRefs().entrySet(), entry -> entry), data.getDefs(), data.getCasts(), data.getImplicitToStringRefs());
}
}
@Override
@@ -1,30 +1,31 @@
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
/*
* Copyright 2000-2012 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.ether;
import org.jetbrains.jps.builders.java.JavaBuilderUtil;
import org.jetbrains.jps.model.JpsModuleRootModificationUtil;
import org.jetbrains.jps.model.java.JpsJavaExtensionService;
import org.jetbrains.jps.model.java.compiler.JavaCompilers;
import org.jetbrains.jps.model.java.compiler.JpsJavaCompilerConfiguration;
import org.jetbrains.jps.model.module.JpsModule;
import java.util.Set;
public class FieldPropertyTest extends IncrementalTestCase {
private static final Set<String> GRAPH_ONLY_TESTS = Set.of("constantChain3");
public FieldPropertyTest() {
super("fieldProperties");
}
@Override
protected boolean shouldRunTest() {
if (JavaBuilderUtil.isDepGraphEnabled()) {
return super.shouldRunTest();
}
return !GRAPH_ONLY_TESTS.contains(getTestName(true));
}
public void testConstantChain() {
doTest();
}
@@ -37,10 +38,6 @@ public class FieldPropertyTest extends IncrementalTestCase {
doTest();
}
public void testConstantChain3() {
doTest();
}
public void testConstantChainMultiModule() {
JpsModule moduleA = addModule("moduleA", "moduleA/src");
JpsModule moduleB = addModule("moduleB", "moduleB/src");