mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
an internal action that collects java expression statistics to be used in completion
This commit is contained in:
@@ -0,0 +1,180 @@
|
||||
/*
|
||||
* Copyright 2000-2015 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @author max
|
||||
*/
|
||||
package com.intellij.internal;
|
||||
|
||||
import com.intellij.openapi.actionSystem.AnAction;
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent;
|
||||
import com.intellij.openapi.actionSystem.CommonDataKeys;
|
||||
import com.intellij.openapi.application.ex.ApplicationManagerEx;
|
||||
import com.intellij.openapi.progress.ProgressIndicator;
|
||||
import com.intellij.openapi.progress.ProgressManager;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.roots.ContentIterator;
|
||||
import com.intellij.openapi.roots.ProjectFileIndex;
|
||||
import com.intellij.openapi.ui.Messages;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class ExpressionStatisticsAction extends AnAction {
|
||||
@Override
|
||||
public void actionPerformed(AnActionEvent e) {
|
||||
final Project project = CommonDataKeys.PROJECT.getData(e.getDataContext());
|
||||
assert project != null;
|
||||
|
||||
final Data topLevelData = new Data();
|
||||
final Data subData = new Data();
|
||||
|
||||
final VirtualFile dir = CommonDataKeys.VIRTUAL_FILE.getData(e.getDataContext());
|
||||
assert dir != null;
|
||||
|
||||
final List<VirtualFile> javaFiles = collectJavaFiles(dir, project);
|
||||
|
||||
if (!ApplicationManagerEx.getApplicationEx().runProcessWithProgressSynchronouslyInReadAction(project, "Traversing PSI", true, "Cancel", null, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
final PsiManager psiManager = PsiManager.getInstance(project);
|
||||
ProgressIndicator indicator = ProgressManager.getInstance().getProgressIndicator();
|
||||
indicator.setIndeterminate(false);
|
||||
for (int i = 0; i < javaFiles.size(); i++) {
|
||||
VirtualFile file = javaFiles.get(i);
|
||||
indicator.setText2(file.getPath());
|
||||
indicator.setFraction((double)i / javaFiles.size());
|
||||
PsiFile psiFile = psiManager.findFile(file);
|
||||
if (psiFile instanceof PsiJavaFile) {
|
||||
psiFile.accept(new PsiRecursiveElementWalkingVisitor() {
|
||||
@Override
|
||||
public void visitElement(PsiElement element) {
|
||||
if (element instanceof PsiIdentifier) {
|
||||
int offset = element.getTextRange().getStartOffset();
|
||||
PsiExpression minExpression = PsiTreeUtil.getParentOfType(element, PsiExpression.class);
|
||||
if (minExpression != null && minExpression.getTextRange().getStartOffset() == offset) {
|
||||
PsiExpression maxExpression = minExpression;
|
||||
while (true) {
|
||||
PsiExpression nextExpression = PsiTreeUtil.getParentOfType(maxExpression, PsiExpression.class, true);
|
||||
if (nextExpression == null || nextExpression.getTextRange().getStartOffset() != offset) break;
|
||||
maxExpression = nextExpression;
|
||||
}
|
||||
collectExpressionData(minExpression, maxExpression, topLevelData, subData);
|
||||
}
|
||||
}
|
||||
|
||||
super.visitElement(element);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
})) {
|
||||
return;
|
||||
}
|
||||
|
||||
Messages.showMessageDialog("Top-level: " + topLevelData.toString() + "\n\n" + "Sub-expressions: " + subData.toString(), "Expression Statistics", null);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static List<VirtualFile> collectJavaFiles(VirtualFile dir, Project project) {
|
||||
final List<VirtualFile> javaFiles = ContainerUtil.newArrayList();
|
||||
ProjectFileIndex.SERVICE.getInstance(project).iterateContentUnderDirectory(dir, new ContentIterator() {
|
||||
@Override
|
||||
public boolean processFile(VirtualFile file) {
|
||||
if (file.getName().endsWith(".java")) {
|
||||
javaFiles.add(file);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
});
|
||||
return javaFiles;
|
||||
}
|
||||
|
||||
private static void collectExpressionData(PsiExpression minExpression, PsiExpression maxExpression, Data topLevelData, Data subExpressionData) {
|
||||
Data data;
|
||||
if (minExpression == maxExpression || maxExpression instanceof PsiMethodCallExpression && minExpression == ((PsiMethodCallExpression)maxExpression).getMethodExpression()) {
|
||||
data = topLevelData;
|
||||
} else {
|
||||
data = subExpressionData;
|
||||
}
|
||||
|
||||
if (minExpression instanceof PsiClassObjectAccessExpression || minExpression instanceof PsiThisExpression || minExpression instanceof PsiSuperExpression) {
|
||||
data.classes++;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(minExpression instanceof PsiJavaCodeReferenceElement)) {
|
||||
data.other++;
|
||||
return;
|
||||
}
|
||||
|
||||
classifyTarget(data, ((PsiJavaCodeReferenceElement)minExpression).resolve());
|
||||
}
|
||||
|
||||
private static void classifyTarget(Data data, PsiElement target) {
|
||||
if (target instanceof PsiLocalVariable) {
|
||||
data.localVars++;
|
||||
}
|
||||
else if (target instanceof PsiParameter) {
|
||||
data.parameters++;
|
||||
}
|
||||
else if (target instanceof PsiMethod) {
|
||||
data.methods++;
|
||||
}
|
||||
else if (target instanceof PsiClass) {
|
||||
data.classes++;
|
||||
}
|
||||
else if (target instanceof PsiPackage) {
|
||||
data.packages++;
|
||||
}
|
||||
else if (target instanceof PsiField) {
|
||||
data.fields++;
|
||||
}
|
||||
else {
|
||||
data.other++;
|
||||
}
|
||||
}
|
||||
|
||||
private static class Data {
|
||||
int localVars;
|
||||
int parameters;
|
||||
int methods;
|
||||
int classes;
|
||||
int fields;
|
||||
int packages;
|
||||
int other;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "localVars=" + localVars +
|
||||
"\nparameters=" + parameters +
|
||||
"\nmethods=" + methods +
|
||||
"\nfields=" + fields +
|
||||
"\nclasses=" + classes +
|
||||
"\npackages=" + packages +
|
||||
"\nother=" + other +
|
||||
"\ntotal=" + (localVars + parameters + methods + fields + classes + packages + other);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -150,6 +150,10 @@
|
||||
text="List Used Icons">
|
||||
<add-to-group group-id="Internal"/>
|
||||
</action>
|
||||
<action id="ExpressionStatistics" internal="true" class="com.intellij.internal.ExpressionStatisticsAction"
|
||||
text="Collect Java Expression Statistics">
|
||||
<add-to-group group-id="Internal"/>
|
||||
</action>
|
||||
|
||||
<action id="StaticIconFields" internal="true" class="com.intellij.internal.StaticIconFieldsAction"
|
||||
text="List Static Field Initializers">
|
||||
|
||||
Reference in New Issue
Block a user