<commit_before>/*
 * Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
 */
package com.intellij.lang.properties;

import com.intellij.lang.properties.psi.PropertiesFile;
import com.intellij.lang.properties.xml.XmlPropertiesIndex;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.project.DumbService;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiManager;
import com.intellij.psi.search.FileTypeIndex;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.util.CachedValueProvider;
import com.intellij.psi.util.CachedValuesManager;
import com.intellij.psi.util.PsiModificationTracker;
import com.intellij.util.containers.ConcurrentFactoryMap;
import com.intellij.util.indexing.FileBasedIndex;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.concurrent.ConcurrentMap;

/**
 * @author max
 */
public class PropertiesReferenceManager {
  private final PsiManager myPsiManager;
  private final DumbService myDumbService;

  public static PropertiesReferenceManager getInstance(Project project) {
    return ServiceManager.getService(project, PropertiesReferenceManager.class);
  }

  public PropertiesReferenceManager(PsiManager psiManager, DumbService dumbService) {
    myPsiManager = psiManager;
    myDumbService = dumbService;
  }

  @NotNull
  public List<PropertiesFile> findPropertiesFiles(@NotNull Module module, final String bundleName) {
    ConcurrentMap<String, List<PropertiesFile>> map =
      CachedValuesManager.getManager(module.getProject()).getCachedValue(module, () -> {
        ConcurrentMap<String, List<PropertiesFile>> factoryMap = ConcurrentFactoryMap.createMap(
          bundleName1 -> findPropertiesFiles(GlobalSearchScope.moduleWithDependenciesAndLibrariesScope(module), bundleName1,
                                             BundleNameEvaluator.DEFAULT));
        return CachedValueProvider.Result.create(factoryMap, PsiModificationTracker.MODIFICATION_COUNT);
      });
    return map.get(bundleName);
  }

  @NotNull
  public List<PropertiesFile> findPropertiesFiles(@NotNull final GlobalSearchScope searchScope,
                                                  final String bundleName,
                                                  BundleNameEvaluator bundleNameEvaluator) {


    final ArrayList<PropertiesFile> result = new ArrayList<>();
    processPropertiesFiles(searchScope, (baseName, propertiesFile) -> {
      if (baseName.equals(bundleName)) {
        result.add(propertiesFile);
      }
      return true;
    }, bundleNameEvaluator);
    return result;
  }

  @Nullable
  public PropertiesFile findPropertiesFile(final Module module,
                                           final String bundleName,
                                           final Locale locale) {
    List<PropertiesFile> propFiles = findPropertiesFiles(module, bundleName);
    if (locale != null) {
      for(PropertiesFile propFile: propFiles) {
        if (propFile.getLocale().equals(locale)) {
          return propFile;
        }
      }
    }

    // fallback to default locale
    for(PropertiesFile propFile: propFiles) {
      if (propFile.getLocale().getLanguage().length() == 0 || propFile.getLocale().equals(Locale.getDefault())) {
        return propFile;
      }
    }

    // fallback to any file
    if (!propFiles.isEmpty()) {
      return propFiles.get(0);
    }

    return null;
  }

  public boolean processAllPropertiesFiles(@NotNull final PropertiesFileProcessor processor) {
    return processPropertiesFiles(GlobalSearchScope.allScope(myPsiManager.getProject()), processor, BundleNameEvaluator.DEFAULT);
  }

  public boolean processPropertiesFiles(@NotNull final GlobalSearchScope searchScope,
                                        @NotNull final PropertiesFileProcessor processor,
                                        @NotNull final BundleNameEvaluator evaluator) {
    for(VirtualFile file:FileTypeIndex.getFiles(PropertiesFileType.INSTANCE, searchScope)) {
      if (!processFile(file, evaluator, processor)) return false;
    }
    if (!myDumbService.isDumb()) {
      for(VirtualFile file:FileBasedIndex.getInstance().getContainingFiles(XmlPropertiesIndex.NAME, XmlPropertiesIndex.MARKER_KEY, searchScope)) {
        if (!processFile(file, evaluator, processor)) return false;
      }
    }

    return true;
  }

  private boolean processFile(VirtualFile file, BundleNameEvaluator evaluator, PropertiesFileProcessor processor) {
    final PsiFile psiFile = myPsiManager.findFile(file);
    PropertiesFile propertiesFile = PropertiesImplUtil.getPropertiesFile(psiFile);
    if (propertiesFile != null) {
      final String qName = evaluator.evaluateBundleName(psiFile);
      if (qName != null) {
        if (!processor.process(qName, propertiesFile)) return false;
      }
    }
    return true;
  }
}<commit_msg>notnulls<commit_after>/*
 * Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
 */
package com.intellij.lang.properties;

import com.intellij.lang.properties.psi.PropertiesFile;
import com.intellij.lang.properties.xml.XmlPropertiesIndex;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.project.DumbService;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiManager;
import com.intellij.psi.search.FileTypeIndex;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.util.CachedValueProvider;
import com.intellij.psi.util.CachedValuesManager;
import com.intellij.psi.util.PsiModificationTracker;
import com.intellij.util.containers.ConcurrentFactoryMap;
import com.intellij.util.indexing.FileBasedIndex;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.concurrent.ConcurrentMap;

/**
 * @author max
 */
public class PropertiesReferenceManager {
  private final PsiManager myPsiManager;
  private final DumbService myDumbService;

  public static PropertiesReferenceManager getInstance(@NotNull Project project) {
    return ServiceManager.getService(project, PropertiesReferenceManager.class);
  }

  public PropertiesReferenceManager(PsiManager psiManager, DumbService dumbService) {
    myPsiManager = psiManager;
    myDumbService = dumbService;
  }

  @NotNull
  public List<PropertiesFile> findPropertiesFiles(@NotNull Module module, @NotNull String bundleName) {
    ConcurrentMap<String, List<PropertiesFile>> map =
      CachedValuesManager.getManager(module.getProject()).getCachedValue(module, () -> {
        ConcurrentMap<String, List<PropertiesFile>> factoryMap = ConcurrentFactoryMap.createMap(
          bundleName1 -> findPropertiesFiles(GlobalSearchScope.moduleWithDependenciesAndLibrariesScope(module), bundleName1,
                                             BundleNameEvaluator.DEFAULT));
        return CachedValueProvider.Result.create(factoryMap, PsiModificationTracker.MODIFICATION_COUNT);
      });
    return map.get(bundleName);
  }

  @NotNull
  public List<PropertiesFile> findPropertiesFiles(@NotNull GlobalSearchScope searchScope,
                                                  @NotNull String bundleName,
                                                  @NotNull BundleNameEvaluator bundleNameEvaluator) {


    final ArrayList<PropertiesFile> result = new ArrayList<>();
    processPropertiesFiles(searchScope, (baseName, propertiesFile) -> {
      if (baseName.equals(bundleName)) {
        result.add(propertiesFile);
      }
      return true;
    }, bundleNameEvaluator);
    return result;
  }

  @Nullable
  public PropertiesFile findPropertiesFile(@NotNull Module module,
                                           @NotNull String bundleName,
                                           @Nullable Locale locale) {
    List<PropertiesFile> propFiles = findPropertiesFiles(module, bundleName);
    if (locale != null) {
      for(PropertiesFile propFile: propFiles) {
        if (propFile.getLocale().equals(locale)) {
          return propFile;
        }
      }
    }

    // fallback to default locale
    for(PropertiesFile propFile: propFiles) {
      if (propFile.getLocale().getLanguage().length() == 0 || propFile.getLocale().equals(Locale.getDefault())) {
        return propFile;
      }
    }

    // fallback to any file
    if (!propFiles.isEmpty()) {
      return propFiles.get(0);
    }

    return null;
  }

  public boolean processAllPropertiesFiles(@NotNull final PropertiesFileProcessor processor) {
    return processPropertiesFiles(GlobalSearchScope.allScope(myPsiManager.getProject()), processor, BundleNameEvaluator.DEFAULT);
  }

  public boolean processPropertiesFiles(@NotNull final GlobalSearchScope searchScope,
                                        @NotNull final PropertiesFileProcessor processor,
                                        @NotNull final BundleNameEvaluator evaluator) {
    for(VirtualFile file:FileTypeIndex.getFiles(PropertiesFileType.INSTANCE, searchScope)) {
      if (!processFile(file, evaluator, processor)) return false;
    }
    if (!myDumbService.isDumb()) {
      for(VirtualFile file:FileBasedIndex.getInstance().getContainingFiles(XmlPropertiesIndex.NAME, XmlPropertiesIndex.MARKER_KEY, searchScope)) {
        if (!processFile(file, evaluator, processor)) return false;
      }
    }

    return true;
  }

  private boolean processFile(@NotNull VirtualFile file, @NotNull BundleNameEvaluator evaluator, @NotNull PropertiesFileProcessor processor) {
    final PsiFile psiFile = myPsiManager.findFile(file);
    PropertiesFile propertiesFile = PropertiesImplUtil.getPropertiesFile(psiFile);
    if (propertiesFile != null) {
      final String qName = evaluator.evaluateBundleName(psiFile);
      if (qName != null) {
        if (!processor.process(qName, propertiesFile)) return false;
      }
    }
    return true;
  }
}
{'fraction_non_alphanumeric': 0.08874832279087598, 'fraction_numerical': 0.0026835345984282154, 'mean_word_length': 3.4727818259751393, 'pattern_counts': {'":': 0, '<': 21, '<?xml version=': 0, '>': 27, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 2}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 24, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7255479', 'n_tokens_mistral': 2760, 'n_tokens_neox': 2692, 'n_words': 570}