NPE (18686)
[fedora-idea.git] / platform / lang-impl / src / com / intellij / packageDependencies / DependenciesBuilder.java
blob002c094353448f2c3756f3a0f4660cf3a635367a
1 /*
2 * Copyright 2000-2009 JetBrains s.r.o.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 package com.intellij.packageDependencies;
19 import com.intellij.analysis.AnalysisScope;
20 import com.intellij.openapi.project.Project;
21 import com.intellij.psi.PsiElement;
22 import com.intellij.psi.PsiFile;
23 import com.intellij.psi.impl.PsiFileEx;
24 import org.jetbrains.annotations.NotNull;
26 import java.util.*;
28 /**
29 * User: anna
30 * Date: Jan 19, 2005
32 public abstract class DependenciesBuilder {
33 private Project myProject;
34 private final AnalysisScope myScope;
35 private final AnalysisScope myScopeOfInterest;
36 private final Map<PsiFile, Set<PsiFile>> myDependencies = new HashMap<PsiFile, Set<PsiFile>>();
37 protected int myTotalFileCount;
38 protected int myFileCount = 0;
39 protected int myTransitive = 0;
41 protected DependenciesBuilder(@NotNull final Project project, @NotNull final AnalysisScope scope) {
42 this(project, scope, null);
45 public DependenciesBuilder(final Project project, final AnalysisScope scope, final AnalysisScope scopeOfInterest) {
46 myProject = project;
47 myScope = scope;
48 myScopeOfInterest = scopeOfInterest;
49 myTotalFileCount = scope.getFileCount();
52 public void setInitialFileCount(final int fileCount) {
53 myFileCount = fileCount;
56 public void setTotalFileCount(final int totalFileCount) {
57 myTotalFileCount = totalFileCount;
60 public int getTotalFileCount() {
61 return myTotalFileCount;
64 public Map<PsiFile, Set<PsiFile>> getDependencies() {
65 return myDependencies;
68 public Map<PsiFile, Set<PsiFile>> getDirectDependencies() {
69 return getDependencies();
72 public AnalysisScope getScope() {
73 return myScope;
76 public AnalysisScope getScopeOfInterest() {
77 return myScopeOfInterest;
80 public Project getProject() {
81 return myProject;
84 public abstract String getRootNodeNameInUsageView();
86 public abstract String getInitialUsagesPosition();
88 public abstract boolean isBackward();
90 public abstract void analyze();
92 public Map<PsiFile, Map<DependencyRule, Set<PsiFile>>> getIllegalDependencies(){
93 Map<PsiFile, Map<DependencyRule, Set<PsiFile>>> result = new HashMap<PsiFile, Map<DependencyRule, Set<PsiFile>>>();
94 DependencyValidationManager validator = DependencyValidationManager.getInstance(myProject);
95 for (PsiFile file : getDirectDependencies().keySet()) {
96 Set<PsiFile> deps = getDirectDependencies().get(file);
97 Map<DependencyRule, Set<PsiFile>> illegal = null;
98 for (PsiFile dependency : deps) {
99 final DependencyRule rule = isBackward() ?
100 validator.getViolatorDependencyRule(dependency, file) :
101 validator.getViolatorDependencyRule(file, dependency);
102 if (rule != null) {
103 if (illegal == null) {
104 illegal = new HashMap<DependencyRule, Set<PsiFile>>();
105 result.put(file, illegal);
107 Set<PsiFile> illegalFilesByRule = illegal.get(rule);
108 if (illegalFilesByRule == null) {
109 illegalFilesByRule = new HashSet<PsiFile>();
111 illegalFilesByRule.add(dependency);
112 illegal.put(rule, illegalFilesByRule);
116 return result;
119 public List<List<PsiFile>> findPaths(PsiFile from, PsiFile to) {
120 return findPaths(from, to, new HashSet<PsiFile>());
123 private List<List<PsiFile>> findPaths(PsiFile from, PsiFile to, Set<PsiFile> processed) {
124 final List<List<PsiFile>> result = new ArrayList<List<PsiFile>>();
125 final Set<PsiFile> reachable = getDirectDependencies().get(from);
126 if (reachable != null) {
127 if (reachable.contains(to)) {
128 final ArrayList<PsiFile> path = new ArrayList<PsiFile>();
129 result.add(path);
130 return result;
132 if (!processed.contains(from)) {
133 processed.add(from);
134 for (PsiFile file : reachable) {
135 if (!getScope().contains(file)) { //exclude paths through scope
136 final List<List<PsiFile>> paths = findPaths(file, to, processed);
137 for (List<PsiFile> path : paths) {
138 path.add(0, file);
140 result.addAll(paths);
145 return result;
150 public static void analyzeFileDependencies(PsiFile file, DependencyProcessor processor) {
151 file.putUserData(PsiFileEx.BATCH_REFERENCE_PROCESSING, Boolean.TRUE);
152 file.accept(DependenciesVisitorFactory.getInstance().createVisitor(processor));
153 file.putUserData(PsiFileEx.BATCH_REFERENCE_PROCESSING, null);
156 public boolean isTransitive() {
157 return myTransitive > 0;
160 public int getTransitiveBorder() {
161 return myTransitive;
164 public interface DependencyProcessor {
165 void process(PsiElement place, PsiElement dependency);