mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Rework reporting other *Stub* exceptions IDEA-331326 Create FUS event for stub index inconsistency
GitOrigin-RevId: a59d3c32d5c013c091fbfcf8db6b21927707ca4d
This commit is contained in:
committed by
intellij-monorepo-bot
parent
25ada6f21c
commit
04d899f7c4
@@ -15,45 +15,27 @@ public interface StubInconsistencyReporter {
|
||||
}
|
||||
|
||||
enum SourceOfCheck {
|
||||
DeliberateAdditionalCheckInCompletion(
|
||||
"deliberate_additional_check_in_completion"), //Registry.is("ide.check.stub.text.consistency") is enabled
|
||||
DeliberateAdditionalCheckInIntentions(
|
||||
"deliberate_additional_check_in_intentions"), //Registry.is("ide.check.stub.text.consistency") is enabled
|
||||
WrongTypePsiInStubHelper("wrong_type_psi_in_stub_helper"),
|
||||
OffsetOutsideFileInJava("offset_outside_file_in_java"),
|
||||
CheckAfterExceptionInJava("check_after_exception_in_java"),
|
||||
NoPsiMatchingASTinJava("no_psi_matching_ast_in_java"),
|
||||
DeliberateAdditionalCheckInCompletion, //Registry.is("ide.check.stub.text.consistency") is enabled
|
||||
DeliberateAdditionalCheckInIntentions, //Registry.is("ide.check.stub.text.consistency") is enabled
|
||||
WrongTypePsiInStubHelper,
|
||||
OffsetOutsideFileInJava,
|
||||
CheckAfterExceptionInJava,
|
||||
NoPsiMatchingASTinJava,
|
||||
|
||||
ForTests("for_tests"),//is definitely not expected to actually appear in FUS
|
||||
Other("other");
|
||||
|
||||
private final String fusDescription;
|
||||
|
||||
SourceOfCheck(String fusDescription) {
|
||||
this.fusDescription = fusDescription;
|
||||
}
|
||||
|
||||
public String getFusDescription() {
|
||||
return fusDescription;
|
||||
}
|
||||
ForTests,//is definitely not expected to actually appear in FUS
|
||||
Other //better use null
|
||||
}
|
||||
|
||||
enum InconsistencyType {
|
||||
DifferentNumberOfPsiTrees("different_number_of_psi_trees"), MismatchingPsiTree("mismatching_psi_tree");
|
||||
private final String fusDescription;
|
||||
|
||||
InconsistencyType(String fusDescription) {
|
||||
this.fusDescription = fusDescription;
|
||||
}
|
||||
|
||||
public String getFusDescription() {
|
||||
return fusDescription;
|
||||
}
|
||||
DifferentNumberOfPsiTrees, MismatchingPsiTree
|
||||
}
|
||||
|
||||
/**
|
||||
* Sometimes stub inconsistency related exception is thrown even when no inconsistency is found during the usual check
|
||||
* Sometimes stub inconsistency-related exception is thrown even when no inconsistency is found during the usual check
|
||||
*
|
||||
* @deprecated all related methods are deprecated
|
||||
*/
|
||||
@Deprecated
|
||||
enum EnforcedInconsistencyType {
|
||||
PsiOfUnexpectedClass("psi_of_unexpected_class"), Other("other");
|
||||
private final String fusDescription;
|
||||
@@ -62,14 +44,27 @@ public interface StubInconsistencyReporter {
|
||||
this.fusDescription = fusDescription;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public String getFusDescription() {
|
||||
return fusDescription;
|
||||
}
|
||||
}
|
||||
|
||||
void reportStubInconsistency(@NotNull Project project,
|
||||
@Nullable StubInconsistencyReporter.SourceOfCheck reason,
|
||||
@Nullable InconsistencyType type);
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link #reportStubInconsistency(Project, SourceOfCheck, InconsistencyType)}
|
||||
*/
|
||||
@Deprecated
|
||||
void reportEnforcedStubInconsistency(@NotNull Project project, @NotNull StubInconsistencyReporter.SourceOfCheck reason,
|
||||
@NotNull EnforcedInconsistencyType enforcedInconsistencyType);
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link #reportStubInconsistency(Project, SourceOfCheck, InconsistencyType)}
|
||||
*/
|
||||
@Deprecated
|
||||
void reportStubInconsistency(@NotNull Project project, @NotNull StubInconsistencyReporter.SourceOfCheck reason,
|
||||
@NotNull InconsistencyType type,
|
||||
@Nullable EnforcedInconsistencyType enforcedInconsistencyType);
|
||||
|
||||
@@ -59,38 +59,43 @@ public final class StubTextInconsistencyException extends RuntimeException imple
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public static void checkStubTextConsistency(@NotNull PsiFile file) {
|
||||
checkStubTextConsistency(file, SourceOfCheck.Other, null);
|
||||
}
|
||||
|
||||
public static void checkStubTextConsistency(@NotNull PsiFile file, @NotNull StubInconsistencyReporter.SourceOfCheck reason) {
|
||||
checkStubTextConsistency(file, reason, null);
|
||||
checkStubTextConsistency(file, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parameters reason and enforcedInconsistencyType are used for tracking statistic of the errors' sources.
|
||||
* {@link StubInconsistencyReporter.SourceOfCheck#Other} and {@code null} are recommended values for callers outside IntelliJ repository.
|
||||
* Left for backward compatibility.
|
||||
*
|
||||
* @deprecated Use {@link #checkStubTextConsistency(PsiFile, SourceOfCheck)}
|
||||
*/
|
||||
@Deprecated
|
||||
public static void checkStubTextConsistency(@NotNull PsiFile file,
|
||||
@NotNull StubInconsistencyReporter.SourceOfCheck reason,
|
||||
@Nullable StubInconsistencyReporter.EnforcedInconsistencyType enforcedInconsistencyType)
|
||||
@SuppressWarnings("unused")
|
||||
@Nullable StubInconsistencyReporter.EnforcedInconsistencyType enforcedInconsistencyType) {
|
||||
checkStubTextConsistency(file, reason);
|
||||
}
|
||||
|
||||
/**
|
||||
* `reason` parameter is used for tracking statistic of the errors' sources.
|
||||
* {@code null} is recommended values for callers outside IntelliJ repository.
|
||||
*/
|
||||
public static void checkStubTextConsistency(@NotNull PsiFile file,
|
||||
@Nullable StubInconsistencyReporter.SourceOfCheck reason)
|
||||
throws StubTextInconsistencyException {
|
||||
PsiUtilCore.ensureValid(file);
|
||||
|
||||
FileViewProvider viewProvider = file.getViewProvider();
|
||||
if (viewProvider instanceof FreeThreadedFileViewProvider || viewProvider.getVirtualFile() instanceof LightVirtualFile) {
|
||||
reportInconsistency(file, reason, null, enforcedInconsistencyType);
|
||||
return;
|
||||
}
|
||||
|
||||
PsiFile bindingRoot = viewProvider.getStubBindingRoot();
|
||||
if (!(bindingRoot instanceof PsiFileImpl)) {
|
||||
reportInconsistency(file, reason, null, enforcedInconsistencyType);
|
||||
return;
|
||||
}
|
||||
|
||||
IStubFileElementType<?> fileElementType = ((PsiFileImpl)bindingRoot).getElementTypeForStubBuilder();
|
||||
if (fileElementType == null || !fileElementType.shouldBuildStubFor(viewProvider.getVirtualFile())) {
|
||||
reportInconsistency(file, reason, null, enforcedInconsistencyType);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -100,7 +105,7 @@ public final class StubTextInconsistencyException extends RuntimeException imple
|
||||
.map(StubTreeBuilder.getStubbedRoots(viewProvider), p -> (PsiFileStub<?>)((PsiFileImpl)p.getSecond()).calcStubTree().getRoot());
|
||||
|
||||
if (fromPsi.size() != fromText.size()) {
|
||||
reportInconsistency(file, reason, InconsistencyType.DifferentNumberOfPsiTrees, enforcedInconsistencyType);
|
||||
reportInconsistency(file, reason, InconsistencyType.DifferentNumberOfPsiTrees);
|
||||
throw new StubTextInconsistencyException("Inconsistent stub roots: " +
|
||||
"PSI says it's " + ContainerUtil.map(fromPsi, s -> s.getType()) +
|
||||
" but re-parsing the text gives " + ContainerUtil.map(fromText, s -> s.getType()),
|
||||
@@ -110,24 +115,17 @@ public final class StubTextInconsistencyException extends RuntimeException imple
|
||||
for (int i = 0; i < fromPsi.size(); i++) {
|
||||
PsiFileStub<?> psiStub = fromPsi.get(i);
|
||||
if (!DebugUtil.stubTreeToString(psiStub).equals(DebugUtil.stubTreeToString(fromText.get(i)))) {
|
||||
reportInconsistency(file, reason, InconsistencyType.MismatchingPsiTree, enforcedInconsistencyType);
|
||||
reportInconsistency(file, reason, InconsistencyType.MismatchingPsiTree);
|
||||
throw new StubTextInconsistencyException("Stub is inconsistent with text in " + file.getLanguage(),
|
||||
file, fromText, fromPsi);
|
||||
}
|
||||
}
|
||||
reportInconsistency(file, reason, null, enforcedInconsistencyType);
|
||||
}
|
||||
|
||||
private static void reportInconsistency(@NotNull PsiFile file, @NotNull StubInconsistencyReporter.SourceOfCheck reason,
|
||||
@Nullable InconsistencyType inconsistencyType,
|
||||
@Nullable StubInconsistencyReporter.EnforcedInconsistencyType enforcedInconsistencyType) {
|
||||
if (inconsistencyType == null) {
|
||||
if (enforcedInconsistencyType != null) {
|
||||
StubInconsistencyReporter.getInstance().reportEnforcedStubInconsistency(file.getProject(), reason, enforcedInconsistencyType);
|
||||
}
|
||||
return;
|
||||
}
|
||||
StubInconsistencyReporter.getInstance().reportStubInconsistency(file.getProject(), reason, inconsistencyType, enforcedInconsistencyType);
|
||||
private static void reportInconsistency(@NotNull PsiFile file,
|
||||
@Nullable StubInconsistencyReporter.SourceOfCheck reason,
|
||||
@NotNull InconsistencyType inconsistencyType) {
|
||||
StubInconsistencyReporter.getInstance().reportStubInconsistency(file.getProject(), reason, inconsistencyType);
|
||||
}
|
||||
|
||||
private static @NotNull List<PsiFileStub<?>> restoreStubsFromText(FileViewProvider viewProvider) {
|
||||
|
||||
@@ -17,6 +17,7 @@ import com.intellij.psi.impl.DebugUtil;
|
||||
import com.intellij.psi.impl.source.PsiFileWithStubSupport;
|
||||
import com.intellij.psi.tree.IStubFileElementType;
|
||||
import com.intellij.util.Function;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -54,14 +55,15 @@ public abstract class StubTreeLoader {
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates exception with full description. Should be used when requesting indexes is safe,
|
||||
* in particular counting indexes for changed files won't need some already taken lock.
|
||||
* Creates exception with full description.
|
||||
* Should be used when requesting indexes is safe, in particular, counting indexes for changed files won't need some already taken lock.
|
||||
* <p/>
|
||||
* From under lock, which may be needed to compute indexes for changed files,
|
||||
* use {@link StubTreeLoader#createCoarseExceptionStubTreeAndIndexDoNotMatch(ObjectStubTree, PsiFileWithStubSupport, Throwable,
|
||||
* StubInconsistencyReporter.StubTreeAndIndexDoNotMatchSource)}
|
||||
* and invoke {@link StubTreeAndIndexUnmatchCoarseException#createCompleteException()} outside the lock.
|
||||
*/
|
||||
@ApiStatus.Internal
|
||||
public @NotNull RuntimeException stubTreeAndIndexDoNotMatch(
|
||||
@Nullable ObjectStubTree<?> stubTree,
|
||||
@NotNull PsiFileWithStubSupport psiFile,
|
||||
@@ -73,22 +75,11 @@ public abstract class StubTreeLoader {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use @{link {@link #stubTreeAndIndexDoNotMatch(ObjectStubTree, PsiFileWithStubSupport, Throwable,
|
||||
* StubInconsistencyReporter.StubTreeAndIndexDoNotMatchSource)}}
|
||||
*/
|
||||
@Deprecated
|
||||
public @NotNull RuntimeException stubTreeAndIndexDoNotMatch(@Nullable ObjectStubTree<?> stubTree,
|
||||
@NotNull PsiFileWithStubSupport psiFile,
|
||||
@Nullable Throwable cause) {
|
||||
return stubTreeAndIndexDoNotMatch(stubTree, psiFile, cause, null);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @see StubTreeLoader#stubTreeAndIndexDoNotMatch(ObjectStubTree, PsiFileWithStubSupport, Throwable,
|
||||
* StubInconsistencyReporter.StubTreeAndIndexDoNotMatchSource)
|
||||
*/
|
||||
@ApiStatus.Internal
|
||||
public @NotNull StubTreeAndIndexUnmatchCoarseException createCoarseExceptionStubTreeAndIndexDoNotMatch(
|
||||
@Nullable ObjectStubTree<?> stubTree,
|
||||
@NotNull PsiFileWithStubSupport psiFile,
|
||||
@@ -100,19 +91,6 @@ public abstract class StubTreeLoader {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link #createCoarseExceptionStubTreeAndIndexDoNotMatch(ObjectStubTree, PsiFileWithStubSupport, Throwable,
|
||||
* StubInconsistencyReporter.StubTreeAndIndexDoNotMatchSource)}
|
||||
*/
|
||||
@Deprecated
|
||||
public @NotNull StubTreeAndIndexUnmatchCoarseException createCoarseExceptionStubTreeAndIndexDoNotMatch(
|
||||
@Nullable ObjectStubTree<?> stubTree,
|
||||
@NotNull PsiFileWithStubSupport psiFile,
|
||||
@Nullable Throwable cause
|
||||
) {
|
||||
return createCoarseExceptionStubTreeAndIndexDoNotMatch(stubTree, psiFile, cause, null);
|
||||
}
|
||||
|
||||
private @NotNull StubTreeAndIndexUnmatchCoarseException doCreateCoarseExceptionStubTreeAndIndexDoNotMatch(
|
||||
@Nullable ObjectStubTree<?> stubTree,
|
||||
@NotNull PsiFileWithStubSupport psiFile,
|
||||
|
||||
@@ -15,7 +15,6 @@ import com.intellij.psi.impl.source.PsiFileWithStubSupport;
|
||||
import com.intellij.psi.impl.source.StubbedSpine;
|
||||
import com.intellij.psi.search.FileTypeIndex;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.psi.stubs.StubInconsistencyReporter.EnforcedInconsistencyType;
|
||||
import com.intellij.psi.stubs.StubInconsistencyReporter.SourceOfCheck;
|
||||
import com.intellij.util.Processor;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
@@ -128,7 +127,7 @@ public abstract class StubProcessingHelperBase {
|
||||
if (psiFile instanceof PsiBinaryFile) {
|
||||
// a file can be indexed as containing stubs,
|
||||
// but then in a specific project FileViewProviderFactory can decide not to create stub-aware PSI
|
||||
// because the file isn't in expected location
|
||||
// because the file isn't in the expected location
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -163,9 +162,7 @@ public abstract class StubProcessingHelperBase {
|
||||
@Nullable StubInconsistencyReporter.StubTreeAndIndexDoNotMatchSource source
|
||||
) {
|
||||
try {
|
||||
StubTextInconsistencyException.checkStubTextConsistency(psiFile,
|
||||
SourceOfCheck.WrongTypePsiInStubHelper,
|
||||
EnforcedInconsistencyType.PsiOfUnexpectedClass);
|
||||
StubTextInconsistencyException.checkStubTextConsistency(psiFile, SourceOfCheck.WrongTypePsiInStubHelper);
|
||||
LOG.error(extraMessage + "\n" + StubTreeLoader.getInstance().stubTreeAndIndexDoNotMatch(stubTree, psiFile, null, source));
|
||||
}
|
||||
finally {
|
||||
|
||||
+1
-43
@@ -8,9 +8,6 @@ import com.intellij.internal.statistic.service.fus.collectors.CounterUsagesColle
|
||||
import com.intellij.internal.statistic.utils.StatisticsUtil
|
||||
import com.intellij.openapi.extensions.PluginId
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.psi.stubs.StubInconsistencyReporter
|
||||
import com.intellij.psi.stubs.StubInconsistencyReporter.InconsistencyType
|
||||
import com.intellij.psi.stubs.StubInconsistencyReporter.SourceOfCheck
|
||||
import com.intellij.util.indexing.FileBasedIndex.RebuildRequestedByUserAction
|
||||
import com.intellij.util.indexing.ID
|
||||
import org.jetbrains.annotations.ApiStatus.Internal
|
||||
@@ -18,46 +15,7 @@ import java.util.*
|
||||
|
||||
@Internal
|
||||
object IndexStatisticGroup {
|
||||
val GROUP = EventLogGroup("indexing.statistics", 12)
|
||||
|
||||
private val sourceOfCheckField =
|
||||
EventFields.Enum<SourceOfCheck>("check_source") { type -> type.fusDescription }
|
||||
private val inconsistencyTypeField = EventFields.Enum<InconsistencyType>("inconsistency_type") { type -> type.fusDescription }
|
||||
private val enforcedInconsistencyTypeField =
|
||||
EventFields.Enum<StubInconsistencyReporter.EnforcedInconsistencyType>("enforced_inconsistency") { type -> type.fusDescription }
|
||||
|
||||
private val stubIndexInconsistencyRegistered = GROUP.registerVarargEvent("stub.index.inconsistency", sourceOfCheckField,
|
||||
inconsistencyTypeField, enforcedInconsistencyTypeField)
|
||||
|
||||
@JvmStatic
|
||||
fun reportEnforcedStubInconsistency(project: Project,
|
||||
sourceOfCheck: SourceOfCheck,
|
||||
enforcedInconsistencyType: StubInconsistencyReporter.EnforcedInconsistencyType) {
|
||||
stubIndexInconsistencyRegistered.log(project,
|
||||
sourceOfCheckField.with(sourceOfCheck),
|
||||
enforcedInconsistencyTypeField.with(enforcedInconsistencyType))
|
||||
}
|
||||
|
||||
/**
|
||||
* `stub.index.inconsistency` event with only a project in versions of collector <= 11
|
||||
* corresponds in collectors of version 12+ to a `stub.index.inconsistency` event with a project,
|
||||
* SourceOfCheck.WrongTypePsiInStubHelper,
|
||||
* any InconsistencyType including none,
|
||||
* and EnforcedInconsistencyType.PsiOfUnexpectedClass
|
||||
*/
|
||||
@JvmStatic
|
||||
fun reportStubInconsistency(project: Project,
|
||||
sourceOfCheck: SourceOfCheck,
|
||||
inconsistencyType: InconsistencyType,
|
||||
enforcedInconsistencyType: StubInconsistencyReporter.EnforcedInconsistencyType?) {
|
||||
if (enforcedInconsistencyType == null) {
|
||||
stubIndexInconsistencyRegistered.log(project, sourceOfCheckField.with(sourceOfCheck), inconsistencyTypeField.with(inconsistencyType))
|
||||
}
|
||||
else {
|
||||
stubIndexInconsistencyRegistered.log(project, sourceOfCheckField.with(sourceOfCheck), inconsistencyTypeField.with(inconsistencyType),
|
||||
enforcedInconsistencyTypeField.with(enforcedInconsistencyType))
|
||||
}
|
||||
}
|
||||
val GROUP = EventLogGroup("indexing.statistics", 13)
|
||||
|
||||
private val indexIdField =
|
||||
EventFields.StringValidatedByCustomRule("index_id", IndexIdRuleValidator::class.java)
|
||||
|
||||
+15
-1
@@ -7,7 +7,7 @@ import com.intellij.internal.statistic.eventLog.events.EventId2
|
||||
import com.intellij.internal.statistic.eventLog.events.EventPair
|
||||
import com.intellij.internal.statistic.service.fus.collectors.CounterUsagesCollector
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.psi.stubs.StubInconsistencyReporter.StubTreeAndIndexDoNotMatchSource
|
||||
import com.intellij.psi.stubs.StubInconsistencyReporter.*
|
||||
import org.jetbrains.annotations.ApiStatus
|
||||
|
||||
@ApiStatus.Internal
|
||||
@@ -53,6 +53,20 @@ object StubInconsistencyReportUtil {
|
||||
STUB_TREE_AND_INDEX_DO_NOT_MATCH_EVENT.log(project, EventPair(STUB_TREE_AND_INDEX_DO_NOT_MATCH_SOURCE_FIELD, source))
|
||||
}
|
||||
}
|
||||
|
||||
private val CHECK_REASON_FIELD = EventFields.Enum<SourceOfCheck>("reason")
|
||||
private val INCONSISTENCY_TYPE_FIELD = EventFields.Enum<InconsistencyType>("type")
|
||||
private val STUB_INCONSISTENCY_EVENT = GROUP.registerVarargEvent(
|
||||
"stub.inconsistency", CHECK_REASON_FIELD, INCONSISTENCY_TYPE_FIELD
|
||||
)
|
||||
|
||||
@JvmStatic
|
||||
fun reportStubInconsistency(project: Project, reason: SourceOfCheck?, type: InconsistencyType?) {
|
||||
val parameters = mutableListOf<EventPair<*>>()
|
||||
reason?.let { parameters.add(CHECK_REASON_FIELD.with(it)) }
|
||||
type?.let { parameters.add(INCONSISTENCY_TYPE_FIELD.with(it)) }
|
||||
STUB_INCONSISTENCY_EVENT.log(project, parameters)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
+11
-4
@@ -9,19 +9,26 @@ import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@ApiStatus.Internal
|
||||
public class StubInconsistencyReporterImpl implements StubInconsistencyReporter {
|
||||
@Override
|
||||
public void reportStubInconsistency(@NotNull Project project,
|
||||
@Nullable SourceOfCheck reason,
|
||||
@Nullable InconsistencyType type) {
|
||||
StubInconsistencyReportUtil.reportStubInconsistency(project, reason, type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reportEnforcedStubInconsistency(@NotNull Project project,
|
||||
@NotNull StubInconsistencyReporter.SourceOfCheck reason,
|
||||
@NotNull EnforcedInconsistencyType enforcedInconsistencyType) {
|
||||
IndexStatisticGroup.reportEnforcedStubInconsistency(project, reason, enforcedInconsistencyType);
|
||||
@SuppressWarnings("deprecation") @NotNull EnforcedInconsistencyType enforcedInconsistencyType) {
|
||||
StubInconsistencyReportUtil.reportStubInconsistency(project, reason, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reportStubInconsistency(@NotNull Project project,
|
||||
@NotNull StubInconsistencyReporter.SourceOfCheck reason,
|
||||
@NotNull InconsistencyType type,
|
||||
@Nullable EnforcedInconsistencyType enforcedInconsistencyType) {
|
||||
IndexStatisticGroup.reportStubInconsistency(project, reason, type, enforcedInconsistencyType);
|
||||
@SuppressWarnings("deprecation") @Nullable EnforcedInconsistencyType enforcedInconsistencyType) {
|
||||
StubInconsistencyReportUtil.reportStubInconsistency(project, reason, type);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
Reference in New Issue
Block a user