blob: 41ff050b3ce5dd8deefe147f8bf47a1956c053ea [file] [log] [blame]
/*
* Copyright 2000-2014 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 com.intellij.psi.search.scope.packageSet;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.*;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.problems.WolfTheProblemSolver;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.File;
import java.util.List;
import java.util.regex.Pattern;
public class PatternPackageSet extends PatternBasedPackageSet {
@NonNls public static final String SCOPE_TEST = "test";
@NonNls public static final String SCOPE_SOURCE = "src";
@NonNls public static final String SCOPE_LIBRARY = "lib";
@NonNls public static final String SCOPE_PROBLEM = "problem";
public static final String SCOPE_ANY = "";
private final Pattern myPattern;
private final Pattern myModulePattern;
private final Pattern myModuleGroupPattern;
private final String myAspectJSyntaxPattern;
private final String myScope;
private final String myModulePatternText;
public PatternPackageSet(@NonNls @Nullable String aspectPattern,
@NotNull String scope,
@NonNls String modulePattern) {
myAspectJSyntaxPattern = aspectPattern;
myScope = scope;
myModulePatternText = modulePattern;
Pattern mmgp = null;
Pattern mmp = null;
if (modulePattern == null || modulePattern.isEmpty()) {
mmp = null;
}
else {
if (modulePattern.startsWith("group:")) {
int idx = modulePattern.indexOf(':', 6);
if (idx == -1) idx = modulePattern.length();
mmgp = Pattern.compile(StringUtil.replace(modulePattern.substring(6, idx), "*", ".*"));
if (idx < modulePattern.length() - 1) {
mmp = Pattern.compile(StringUtil.replace(modulePattern.substring(idx + 1), "*", ".*"));
}
} else {
mmp = Pattern.compile(StringUtil.replace(modulePattern, "*", ".*"));
}
}
myModulePattern = mmp;
myModuleGroupPattern = mmgp;
myPattern = aspectPattern != null ? Pattern.compile(FilePatternPackageSet.convertToRegexp(aspectPattern, '.')) : null;
}
@Override
public boolean contains(VirtualFile file, @NotNull NamedScopesHolder holder) {
return contains(file, holder.getProject(), holder);
}
@Override
public boolean contains(VirtualFile file, @NotNull Project project, @Nullable NamedScopesHolder holder) {
ProjectFileIndex fileIndex = ProjectRootManager.getInstance(project).getFileIndex();
return matchesScope(file, project, fileIndex) && (myPattern == null || myPattern.matcher(getPackageName(file, fileIndex)).matches());
}
private boolean matchesScope(VirtualFile file, Project project, ProjectFileIndex fileIndex) {
if (file == null) return false;
boolean isSource = fileIndex.isInSourceContent(file);
if (myScope == SCOPE_ANY) {
return fileIndex.isInContent(file) && FilePatternPackageSet.matchesModule(myModuleGroupPattern, myModulePattern, file, fileIndex);
}
if (myScope == SCOPE_SOURCE) {
return isSource && !fileIndex.isInTestSourceContent(file) && FilePatternPackageSet.matchesModule(myModuleGroupPattern, myModulePattern,
file, fileIndex);
}
if (myScope == SCOPE_LIBRARY) {
return (fileIndex.isInLibraryClasses(file) || fileIndex.isInLibrarySource(file)) && matchesLibrary(myModulePattern, file, fileIndex);
}
if (myScope == SCOPE_TEST) {
return isSource && fileIndex.isInTestSourceContent(file) && FilePatternPackageSet.matchesModule(myModuleGroupPattern, myModulePattern,
file, fileIndex);
}
if (myScope == SCOPE_PROBLEM) {
return isSource && WolfTheProblemSolver.getInstance(project).isProblemFile(file) &&
FilePatternPackageSet.matchesModule(myModuleGroupPattern, myModulePattern, file, fileIndex);
}
throw new RuntimeException("Unknown scope: " + myScope);
}
private static String getPackageName(VirtualFile file, ProjectFileIndex fileIndex) {
return StringUtil.getQualifiedName(fileIndex.getPackageNameByDirectory(file.isDirectory() ? file : file.getParent()), file.getNameWithoutExtension());
}
@NotNull
@Override
public PackageSet createCopy() {
return new PatternPackageSet(myAspectJSyntaxPattern, myScope, myModulePatternText);
}
@Override
public int getNodePriority() {
return 0;
}
@NotNull
@Override
public String getText() {
StringBuilder buf = new StringBuilder();
if (myScope != SCOPE_ANY) {
buf.append(myScope);
}
if (myModulePattern != null || myModuleGroupPattern != null) {
buf.append("[").append(myModulePatternText).append("]");
}
if (buf.length() > 0) {
buf.append(':');
}
buf.append(myAspectJSyntaxPattern);
return buf.toString();
}
@Override
public String getModulePattern() {
return myModulePatternText;
}
@Override
public boolean isOn(String oldQName) {
return Comparing.strEqual(oldQName, myAspectJSyntaxPattern) || //class qname
Comparing.strEqual(oldQName + "..*", myAspectJSyntaxPattern) || //package req
Comparing.strEqual(oldQName + ".*", myAspectJSyntaxPattern); //package
}
@Override
public String getPattern() {
return myAspectJSyntaxPattern;
}
public static boolean matchesLibrary(final Pattern libPattern,
final VirtualFile file,
final ProjectFileIndex fileIndex) {
if (libPattern != null) {
final List<OrderEntry> entries = fileIndex.getOrderEntriesForFile(file);
for (OrderEntry orderEntry : entries) {
if (orderEntry instanceof LibraryOrderEntry) {
final String libraryName = ((LibraryOrderEntry)orderEntry).getLibraryName();
if (libraryName != null) {
if (libPattern.matcher(libraryName).matches()) return true;
} else {
final String presentableName = orderEntry.getPresentableName();
final String fileName = new File(presentableName).getName();
if (libPattern.matcher(fileName).matches()) return true;
}
} else if (orderEntry instanceof JdkOrderEntry) {
final String jdkName = ((JdkOrderEntry)orderEntry).getJdkName();
if (jdkName != null && libPattern.matcher(jdkName).matches()) return true;
}
}
return false;
}
return true;
}
}