diff --git a/java/java-tests/testData/compileServer/incremental/fieldProperties/constantChain3.log b/java/java-tests/testData/compileServer/incremental/fieldProperties/constantChain3.log deleted file mode 100644 index 0e7f83ab4675..000000000000 --- a/java/java-tests/testData/compileServer/incremental/fieldProperties/constantChain3.log +++ /dev/null @@ -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 \ No newline at end of file diff --git a/java/java-tests/testData/compileServer/incremental/fieldProperties/constantChain3/Const1.java.new b/java/java-tests/testData/compileServer/incremental/fieldProperties/constantChain3/Const1.java.new deleted file mode 100644 index 4b630c37f216..000000000000 --- a/java/java-tests/testData/compileServer/incremental/fieldProperties/constantChain3/Const1.java.new +++ /dev/null @@ -1,3 +0,0 @@ -public class Const1 { - public static final String A1 = "20"; -} \ No newline at end of file diff --git a/java/java-tests/testData/compileServer/incremental/fieldProperties/constantChain3/src/Const1.java b/java/java-tests/testData/compileServer/incremental/fieldProperties/constantChain3/src/Const1.java deleted file mode 100644 index a8258d513d44..000000000000 --- a/java/java-tests/testData/compileServer/incremental/fieldProperties/constantChain3/src/Const1.java +++ /dev/null @@ -1,3 +0,0 @@ -public class Const1 { - public static final String A1 = "10"; -} \ No newline at end of file diff --git a/java/java-tests/testData/compileServer/incremental/fieldProperties/constantChain3/src/Const2.java b/java/java-tests/testData/compileServer/incremental/fieldProperties/constantChain3/src/Const2.java deleted file mode 100644 index 36a57aa48ee6..000000000000 --- a/java/java-tests/testData/compileServer/incremental/fieldProperties/constantChain3/src/Const2.java +++ /dev/null @@ -1,3 +0,0 @@ -public class Const2 { - public static final String A2 = Const1.A1; -} \ No newline at end of file diff --git a/java/java-tests/testData/compileServer/incremental/fieldProperties/constantChain3/src/Const3.java b/java/java-tests/testData/compileServer/incremental/fieldProperties/constantChain3/src/Const3.java deleted file mode 100644 index 902cd46d8970..000000000000 --- a/java/java-tests/testData/compileServer/incremental/fieldProperties/constantChain3/src/Const3.java +++ /dev/null @@ -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 -} 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 901aa2cc6495..e2c8347c64ac 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 @@ -22,8 +22,8 @@ final class BackendCallbackToGraphDeltaAdapter implements Callbacks.Backend { private final Map> myConstantRefs = Collections.synchronizedMap(new HashMap<>()); private final Map> myAdditionalUsages = Collections.synchronizedMap(new HashMap<>()); private final Map> myPerSourceAdditionalUsages = Collections.synchronizedMap(new HashMap<>()); - private final List>> myNodeBuilders = new ArrayList<>(); private final List, Iterable>> myNodes = new ArrayList<>(); + private final Map> 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> imports = myImportRefs.remove(nodeName); + if (imports != null) { + addImportUsages(builder, imports.getFirst(), imports.getSecond()); + } + Set additionalUsages = myAdditionalUsages.remove(nodeName); + if (additionalUsages != null) { + for (Usage usage : additionalUsages) { + 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); + } + } + + myNodes.add(new Pair<>(node, nodeSources)); } public List, Iterable>> getNodes() { - Map> fileLocalUsages = new HashMap<>(); - // post-process collected data - for (Pair> pair : myNodeBuilders) { - JvmClassNodeBuilder builder = pair.getFirst(); - Iterable nodeSources = pair.getSecond(); - JvmNodeReferenceID nodeID = builder.getReferenceID(); - String nodeName = nodeID.getNodeName(); - addConstantUsages(builder, nodeName, myConstantRefs.remove(nodeName)); - Pair, Collection> imports = myImportRefs.remove(nodeName); - if (imports != null) { - addImportUsages(builder, imports.getFirst(), imports.getSecond()); + if (!myPerSourceAdditionalUsages.isEmpty()) { + NodeSourcePathMapper pathMapper = myGraphConfig.getPathMapper(); + for (Map.Entry> entry : myPerSourceAdditionalUsages.entrySet()) { + NodeSource src = pathMapper.toNodeSource(entry.getKey()); + 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))); } - Set additionalUsages = myAdditionalUsages.remove(nodeName); - if (additionalUsages != null) { - for (Usage usage : additionalUsages) { - builder.addUsage(usage); - } - } - - var node = builder.getResult(); - - 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) { - 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> entry : myPerSourceAdditionalUsages.entrySet()) { - NodeSource src = pathMapper.toNodeSource(entry.getKey()); - Set usages = entry.getValue(); - Set 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; } diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/java/JavaBuilder.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/java/JavaBuilder.java index 04d8af5dd74b..c294c62c8094 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/incremental/java/JavaBuilder.java +++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/java/JavaBuilder.java @@ -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 diff --git a/jps/jps-builders/testSrc/org/jetbrains/ether/FieldPropertyTest.java b/jps/jps-builders/testSrc/org/jetbrains/ether/FieldPropertyTest.java index e689fa4b9e00..0499c6aca676 100644 --- a/jps/jps-builders/testSrc/org/jetbrains/ether/FieldPropertyTest.java +++ b/jps/jps-builders/testSrc/org/jetbrains/ether/FieldPropertyTest.java @@ -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 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");