Package org.intellij.erlang.eunit

Source Code of org.intellij.erlang.eunit.ErlangTestLocationProvider

/*
* Copyright 2012-2014 Sergey Ignatov
*
* 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.intellij.erlang.eunit;

import com.intellij.execution.Location;
import com.intellij.execution.PsiLocation;
import com.intellij.lang.ASTNode;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.PsiElement;
import com.intellij.psi.formatter.FormatterUtil;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.testIntegration.TestLocationProvider;
import com.intellij.util.SmartList;
import com.intellij.util.containers.ContainerUtil;
import org.intellij.erlang.ErlangFileType;
import org.intellij.erlang.index.ErlangModuleIndex;
import org.intellij.erlang.psi.ErlangFile;
import org.intellij.erlang.psi.ErlangFunction;
import org.intellij.erlang.psi.ErlangModule;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.Collection;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class ErlangTestLocationProvider implements TestLocationProvider {
  private static final Pattern LOCATION_PATTERN = Pattern.compile("^(\\w+)(?::(\\w+)(?::(-?\\d+))?)?$");

  @NotNull
  public List<Location> getLocation(@NotNull String protocolId, @NotNull String locationData, Project project) {
    if (!ErlangUnitRunConfigurationType.PROTOCOL.equals(protocolId)) return ContainerUtil.emptyList();

    Matcher matcher = LOCATION_PATTERN.matcher(locationData);
    if (!matcher.matches()) return ContainerUtil.emptyList();

    String module = matcher.group(1);
    String function = matcher.group(2);
    String line = matcher.group(3);
    List<Location> locations = new SmartList<Location>();
    Collection<ErlangFile> erlangFiles = getErlangFiles(project, module);

    if (function != null) {
      for (ErlangFile file : erlangFiles) {
        Location testLocation = getTestLocation(project, file, function, line);
        ContainerUtil.addIfNotNull(testLocation, locations);
      }
    }
    if (locations.isEmpty()) {
      for (ErlangFile file : erlangFiles) {
        Location moduleLocation = getModuleLocation(project, file);
        ContainerUtil.addIfNotNull(moduleLocation, locations);
      }
    }
    return locations;
  }

  @Nullable
  private static Location getTestLocation(Project project, ErlangFile file, String function, String line) {
    ErlangFunction f = ContainerUtil.getFirstItem(file.getFunctionsByName(function));
    String fileText = file.getText();
    int lineNumber = StringUtil.parseInt(line, -1);
    if (f == null) return null;
    if (lineNumber != -1) {
      lineNumber -= 1;
      if (lineNumber != StringUtil.offsetToLineNumber(fileText, f.getTextOffset())) {
        PsiElement testElement = findTestElementInLine(file, fileText, lineNumber);
        if (testElement != null) {
          return new PsiLocation<PsiElement>(project, testElement);
        }
      }
    }
    return new PsiLocation<PsiElement>(project, f);
  }

  @Nullable
  private static Location getModuleLocation(Project project, ErlangFile file) {
    ErlangModule module = file.getModule();
    return module != null ? new PsiLocation<PsiElement>(project, module) : null;
  }

  @Nullable
  @SuppressWarnings("unchecked")
  private static PsiElement findTestElementInLine(ErlangFile file, String fileText, int line) {
    int firstColumnOffset = StringUtil.lineColToOffset(fileText, line, 0);
    PsiElement element = file.findElementAt(firstColumnOffset);
    ASTNode node = element != null ? element.getNode() : null;
    if (node == null) return null;

    ASTNode nonWhitespaceSibling = FormatterUtil.getNextNonWhitespaceSibling(node);
    return nonWhitespaceSibling != null ? nonWhitespaceSibling.getPsi() : null;
  }

  private static Collection<ErlangFile> getErlangFiles(Project project, String module) {
    return ErlangModuleIndex.getFilesByName(project, module,
      GlobalSearchScope.getScopeRestrictedByFileTypes(GlobalSearchScope.projectScope(project), ErlangFileType.MODULE));
  }
}
TOP

Related Classes of org.intellij.erlang.eunit.ErlangTestLocationProvider

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.