Merge remote-tracking branch 'origin/master'

This commit is contained in:
Ekaterina Tuzova
2013-11-25 16:01:43 +04:00
213 changed files with 2879 additions and 1180 deletions
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2012 JetBrains s.r.o.
* Copyright 2000-2013 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.
@@ -21,6 +21,7 @@ import com.intellij.openapi.compiler.*;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.DumbService;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.vfs.LocalFileSystem;
@@ -32,14 +33,14 @@ import java.util.ArrayList;
import java.util.List;
/**
* This is an adapter for running any FileProcessingCompiler as a compiler task
*
* This is an adapter for running any FileProcessingCompiler as a compiler task.
*
* @author Eugene Zhuravlev
* Date: 9/5/12
*/
public class FileProcessingCompilerAdapterTask implements CompileTask{
public class FileProcessingCompilerAdapterTask implements CompileTask {
private static final Logger LOG = Logger.getInstance("#com.intellij.compiler.impl.FileProcessingCompilerAdapterTask");
private final FileProcessingCompiler myCompiler;
public FileProcessingCompilerAdapterTask(FileProcessingCompiler compiler) {
@@ -56,15 +57,15 @@ public class FileProcessingCompilerAdapterTask implements CompileTask{
if (!CompilerWorkspaceConfiguration.getInstance(project).useOutOfProcessBuild()) {
return true;
}
try {
final FileProcessingCompiler.ProcessingItem[] items = myCompiler.getProcessingItems(context);
if (items.length == 0) {
return true;
}
final List<FileProcessingCompiler.ProcessingItem> toProcess = new ArrayList<FileProcessingCompiler.ProcessingItem>();
final Ref<IOException> ex = new Ref<IOException>(null);
final FileProcessingCompilerStateCache cache = getCache(context);
final boolean isMake = context.isMake();
DumbService.getInstance(project).runReadActionInSmartMode(new Runnable() {
@@ -76,7 +77,7 @@ public class FileProcessingCompilerAdapterTask implements CompileTask{
if (isMake && cache.getTimestamp(url) == file.getTimeStamp()) {
final ValidityState state = cache.getExtState(url);
final ValidityState itemState = item.getValidityState();
if (state != null ? state.equalsTo(itemState) : itemState == null) {
if (Comparing.equal(state, itemState)) {
continue;
}
}
@@ -89,16 +90,17 @@ public class FileProcessingCompilerAdapterTask implements CompileTask{
}
});
if (ex.get() != null) {
throw ex.get();
IOException exception = ex.get();
if (exception != null) {
throw exception;
}
if (toProcess.isEmpty()) {
return true;
}
final FileProcessingCompiler.ProcessingItem[] processed = myCompiler.process(context, toProcess.toArray(new FileProcessingCompiler.ProcessingItem[toProcess.size()]));
final FileProcessingCompiler.ProcessingItem[] array = toProcess.toArray(new FileProcessingCompiler.ProcessingItem[toProcess.size()]);
final FileProcessingCompiler.ProcessingItem[] processed = myCompiler.process(context, array);
if (processed.length == 0) {
return true;
}
@@ -481,8 +481,10 @@ public class SetValueAction extends DebuggerAction {
stateManager.addListener(new DebuggerContextListener() {
public void changeEvent(DebuggerContextImpl newContext, int event) {
stateManager.removeListener(this);
editor.cancelEditing();
if (event != DebuggerSession.EVENT_THREADS_REFRESH) {
stateManager.removeListener(this);
editor.cancelEditing();
}
}
});
@@ -102,6 +102,7 @@ public class ViewTextAction extends BaseValueAction {
editor.setVerticalScrollbarVisible(true);
editor.setEmbeddedIntoDialogWrapper(true);
editor.getComponent().setPreferredSize(null);
editor.getSettings().setUseSoftWraps(true);
return editor;
}
}
@@ -22,6 +22,7 @@ import com.intellij.debugger.engine.events.DebuggerCommandImpl;
import com.intellij.debugger.engine.events.SuspendContextCommandImpl;
import com.intellij.debugger.engine.requests.LocatableEventRequestor;
import com.intellij.debugger.engine.requests.MethodReturnValueWatcher;
import com.intellij.debugger.impl.DebuggerSession;
import com.intellij.debugger.jdi.ThreadReferenceProxyImpl;
import com.intellij.debugger.jdi.VirtualMachineProxyImpl;
import com.intellij.debugger.requests.Requestor;
@@ -39,7 +40,6 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.MessageType;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.xdebugger.impl.XDebugSessionImpl;
import com.sun.jdi.InternalException;
import com.sun.jdi.ThreadReference;
@@ -182,7 +182,7 @@ public class DebugProcessEvents extends DebugProcessImpl {
getManagerThread().invokeAndWait(new DebuggerCommandImpl() {
protected void action() throws Exception {
if (eventSet.suspendPolicy() == EventRequest.SUSPEND_ALL && !enableBreakpointsDuringEvaluation()) {
if (eventSet.suspendPolicy() == EventRequest.SUSPEND_ALL && !DebuggerSession.enableBreakpointsDuringEvaluation()) {
// check if there is already one request with policy SUSPEND_ALL
for (SuspendContextImpl context : getSuspendManager().getEventContexts()) {
if (context.getSuspendPolicy() == EventRequest.SUSPEND_ALL) {
@@ -420,7 +420,7 @@ public class DebugProcessEvents extends DebugProcessImpl {
final SuspendManager suspendManager = getSuspendManager();
SuspendContextImpl evaluatingContext = SuspendManagerUtil.getEvaluatingContext(suspendManager, getSuspendContext().getThread());
if (evaluatingContext != null && !enableBreakpointsDuringEvaluation()) {
if (evaluatingContext != null && !DebuggerSession.enableBreakpointsDuringEvaluation()) {
// is inside evaluation, so ignore any breakpoints
suspendManager.voteResume(suspendContext);
return;
@@ -476,10 +476,6 @@ public class DebugProcessEvents extends DebugProcessImpl {
});
}
private static boolean enableBreakpointsDuringEvaluation() {
return Registry.is("debugger.enable.breakpoints.during.evaluation");
}
private void processDefaultEvent(SuspendContextImpl suspendContext) {
preprocessEvent(suspendContext, null);
getSuspendManager().voteResume(suspendContext);
@@ -21,6 +21,7 @@ import com.intellij.debugger.engine.*;
import com.intellij.debugger.engine.evaluation.EvaluateException;
import com.intellij.debugger.engine.evaluation.EvaluationListener;
import com.intellij.debugger.engine.events.SuspendContextCommandImpl;
import com.intellij.debugger.engine.jdi.StackFrameProxy;
import com.intellij.debugger.engine.requests.RequestManagerImpl;
import com.intellij.debugger.jdi.StackFrameProxyImpl;
import com.intellij.debugger.jdi.ThreadReferenceProxyImpl;
@@ -43,9 +44,11 @@ import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.psi.PsiCompiledElement;
import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.PsiFile;
@@ -284,7 +287,12 @@ public class DebuggerSession implements AbstractDebuggerSession {
public void resume() {
final SuspendContextImpl suspendContext = getSuspendContext();
if(suspendContext != null) {
mySteppingThroughThreads.clear();
if (suspendContext.getSuspendPolicy() == EventRequest.SUSPEND_ALL) {
mySteppingThroughThreads.clear();
}
else {
mySteppingThroughThreads.remove(suspendContext.getThread());
}
resetIgnoreStepFiltersFlag();
resumeAction(myDebugProcess.createResumeCommand(suspendContext), EVENT_RESUME);
}
@@ -408,6 +416,15 @@ public class DebuggerSession implements AbstractDebuggerSession {
LOG.debug("paused");
}
if (!shouldSetAsActiveContext(suspendContext)) {
DebuggerInvocationUtil.invokeLater(getProject(), new Runnable() {
public void run() {
getContextManager().fireStateChanged(getContextManager().getContext(), EVENT_THREADS_REFRESH);
}
});
return;
}
ThreadReferenceProxyImpl currentThread = suspendContext.getThread();
final StackFrameContext positionContext;
@@ -503,9 +520,10 @@ public class DebuggerSession implements AbstractDebuggerSession {
else if (sourceMissing) {
// adjust position to be position of the breakpoint in order to show the real originator of the event
position = breakpointPosition;
final StackFrameProxy frameProxy = positionContext.getFrameProxy();
String className;
try {
className = positionContext.getFrameProxy().location().declaringType().name();
className = frameProxy != null? frameProxy.location().declaringType().name() : "";
}
catch (EvaluateException e) {
className = "";
@@ -527,6 +545,23 @@ public class DebuggerSession implements AbstractDebuggerSession {
});
}
private boolean shouldSetAsActiveContext(final SuspendContextImpl suspendContext) {
final ThreadReferenceProxyImpl newThread = suspendContext.getThread();
if (newThread == null || suspendContext.getSuspendPolicy() == EventRequest.SUSPEND_ALL || isSteppingThrough(newThread)) {
return true;
}
final SuspendContextImpl currentSuspendContext = getContextManager().getContext().getSuspendContext();
if (currentSuspendContext == null) {
return true;
}
if (enableBreakpointsDuringEvaluation()) {
final ThreadReferenceProxyImpl currentThread = currentSuspendContext.getThread();
return currentThread == null || Comparing.equal(currentThread.getThreadReference(), newThread.getThreadReference());
}
return false;
}
public void resumed(final SuspendContextImpl suspendContext) {
final SuspendContextImpl currentContext = getProcess().getSuspendManager().getPausedContext();
DebuggerInvocationUtil.invokeLater(getProject(), new Runnable() {
@@ -626,4 +661,9 @@ public class DebuggerSession implements AbstractDebuggerSession {
});
}
}
public static boolean enableBreakpointsDuringEvaluation() {
return Registry.is("debugger.enable.breakpoints.during.evaluation");
}
}
@@ -46,6 +46,7 @@ import org.jetbrains.annotations.Nullable;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreeNode;
import javax.swing.tree.TreePath;
import java.util.*;
public abstract class BaseLibrariesConfigurable extends BaseStructureConfigurable {
@@ -257,14 +258,23 @@ public abstract class BaseLibrariesConfigurable extends BaseStructureConfigurabl
}
public void removeLibrary(@NotNull LibraryProjectStructureElement element) {
getModelProvider().getModifiableModel().removeLibrary(element.getLibrary());
myContext.getDaemonAnalyzer().removeElement(element);
final MyNode node = findNodeByObject(myRoot, element.getLibrary());
if (node != null) {
removePaths(TreeUtil.getPathFromRoot(node));
}
removeLibraries(Collections.singletonList(element));
}
public void removeLibraries(@NotNull List<LibraryProjectStructureElement> libraries) {
List<TreePath> pathsToRemove = new ArrayList<TreePath>();
for (LibraryProjectStructureElement element : libraries) {
getModelProvider().getModifiableModel().removeLibrary(element.getLibrary());
MyNode node = findNodeByObject(myRoot, element.getLibrary());
if (node != null) {
pathsToRemove.add(TreeUtil.getPathFromRoot(node));
}
}
myContext.getDaemonAnalyzer().removeElements(libraries);
removePaths(pathsToRemove.toArray(new TreePath[pathsToRemove.size()]));
}
@Override
protected boolean removeLibrary(final Library library) {
final LibraryTable table = library.getTable();
@@ -41,6 +41,7 @@ import org.jetbrains.annotations.NotNull;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
@@ -148,7 +149,7 @@ public class LibraryProjectStructureElement extends ProjectStructureElement {
@Override
public ProjectStructureProblemDescription createUnusedElementWarning() {
final List<ConfigurationErrorQuickFix> fixes = Arrays.asList(new AddLibraryToDependenciesFix(), new RemoveLibraryFix());
final List<ConfigurationErrorQuickFix> fixes = Arrays.asList(new AddLibraryToDependenciesFix(), new RemoveLibraryFix(), new RemoveAllUnusedLibrariesFix());
return new ProjectStructureProblemDescription("Library '" + StringUtil.escapeXml(myLibrary.getName()) + "'" + " is not used", null, createPlace(),
ProjectStructureProblemType.unused("unused-library"), ProjectStructureProblemDescription.ProblemLevel.PROJECT,
fixes, false);
@@ -225,4 +226,24 @@ public class LibraryProjectStructureElement extends ProjectStructureElement {
BaseLibrariesConfigurable.getInstance(myContext.getProject(), myLibrary.getTable().getTableLevel()).removeLibrary(LibraryProjectStructureElement.this);
}
}
private class RemoveAllUnusedLibrariesFix extends ConfigurationErrorQuickFix {
private RemoveAllUnusedLibrariesFix() {
super("Remove All Unused Libraries");
}
@Override
public void performFix() {
BaseLibrariesConfigurable configurable = BaseLibrariesConfigurable.getInstance(myContext.getProject(), LibraryTablesRegistrar.PROJECT_LEVEL);
Library[] libraries = configurable.getModelProvider().getModifiableModel().getLibraries();
List<LibraryProjectStructureElement> toRemove = new ArrayList<LibraryProjectStructureElement>();
for (Library library : libraries) {
LibraryProjectStructureElement libraryElement = new LibraryProjectStructureElement(myContext, library);
if (myContext.getDaemonAnalyzer().getUsages(libraryElement).isEmpty()) {
toRemove.add(libraryElement);
}
}
configurable.removeLibraries(toRemove);
}
}
}
@@ -7,13 +7,13 @@ import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.roots.ui.configuration.projectRoot.StructureConfigurableContext;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.MultiValuesMap;
import com.intellij.util.Alarm;
import com.intellij.util.EventDispatcher;
import com.intellij.util.ui.update.MergingUpdateQueue;
import com.intellij.util.ui.update.Update;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.util.*;
import java.util.concurrent.atomic.AtomicBoolean;
@@ -29,6 +29,7 @@ public class ProjectStructureDaemonAnalyzer implements Disposable {
private final Set<ProjectStructureElement> myElementsToShowWarningIfUnused = new HashSet<ProjectStructureElement>();
private final Map<ProjectStructureElement, ProjectStructureProblemDescription> myWarningsAboutUnused = new HashMap<ProjectStructureElement, ProjectStructureProblemDescription>();
private final MergingUpdateQueue myAnalyzerQueue;
private final MergingUpdateQueue myResultsUpdateQueue;
private final EventDispatcher<ProjectStructureDaemonAnalyzerListener> myDispatcher = EventDispatcher.create(ProjectStructureDaemonAnalyzerListener.class);
private final AtomicBoolean myStopped = new AtomicBoolean(false);
private final ProjectConfigurationProblems myProjectConfigurationProblems;
@@ -36,7 +37,9 @@ public class ProjectStructureDaemonAnalyzer implements Disposable {
public ProjectStructureDaemonAnalyzer(StructureConfigurableContext context) {
Disposer.register(context, this);
myProjectConfigurationProblems = new ProjectConfigurationProblems(this, context);
myAnalyzerQueue = new MergingUpdateQueue("Project Structure Daemon Analyzer", 300, false, null, this, null, false);
myAnalyzerQueue = new MergingUpdateQueue("Project Structure Daemon Analyzer", 300, false, null, this, null, Alarm.ThreadToUse.POOLED_THREAD);
myResultsUpdateQueue = new MergingUpdateQueue("Project Structure Analysis Results Updater", 300, false, MergingUpdateQueue.ANY_COMPONENT,
this, null, Alarm.ThreadToUse.SWING_THREAD);
}
private void doUpdate(final ProjectStructureElement element, final boolean check, final boolean collectUsages) {
@@ -63,21 +66,7 @@ public class ProjectStructureDaemonAnalyzer implements Disposable {
ProjectStructureValidator.check(element, problemsHolder);
}
}.execute();
invokeLater(new Runnable() {
@Override
public void run() {
if (myStopped.get()) return;
if (LOG.isDebugEnabled()) {
LOG.debug("updating problems for " + element);
}
final ProjectStructureProblemDescription warning = myWarningsAboutUnused.get(element);
if (warning != null)
problemsHolder.registerProblem(warning);
myProblemHolders.put(element, problemsHolder);
myDispatcher.getMulticaster().problemsChanged(element);
}
});
myResultsUpdateQueue.queue(new ProblemsComputedUpdate(element, problemsHolder));
}
private void doCollectUsages(final ProjectStructureElement element) {
@@ -92,18 +81,9 @@ public class ProjectStructureDaemonAnalyzer implements Disposable {
result.setResult(getUsagesInElement(element));
}
}.execute().getResultObject();
invokeLater(new Runnable() {
@Override
public void run() {
if (myStopped.get() || usages == null) return;
if (LOG.isDebugEnabled()) {
LOG.debug("updating usages for " + element);
}
updateUsages(element, usages);
}
});
if (usages != null) {
myResultsUpdateQueue.queue(new UsagesCollectedUpdate(element, usages));
}
}
private static List<ProjectStructureElementUsage> getUsagesInElement(final ProjectStructureElement element) {
@@ -116,11 +96,7 @@ public class ProjectStructureDaemonAnalyzer implements Disposable {
addUsage(usage);
}
myElementWithNotCalculatedUsages.remove(element);
reportUnusedElements();
}
private static void invokeLater(Runnable runnable) {
SwingUtilities.invokeLater(runnable);
myResultsUpdateQueue.queue(new ReportUnusedElementsUpdate());
}
public void queueUpdate(@NotNull final ProjectStructureElement element) {
@@ -141,21 +117,28 @@ public class ProjectStructureDaemonAnalyzer implements Disposable {
}
public void removeElement(ProjectStructureElement element) {
myElementWithNotCalculatedUsages.remove(element);
myElementsToShowWarningIfUnused.remove(element);
myWarningsAboutUnused.remove(element);
myProblemHolders.remove(element);
final Collection<ProjectStructureElementUsage> usages = mySourceElement2Usages.removeAll(element);
if (usages != null) {
for (ProjectStructureElementUsage usage : usages) {
myProblemHolders.remove(usage.getContainingElement());
}
}
removeUsagesInElement(element);
myDispatcher.getMulticaster().problemsChanged(element);
reportUnusedElements();
removeElements(Collections.singletonList(element));
}
public void removeElements(@NotNull List<? extends ProjectStructureElement> elements) {
myElementWithNotCalculatedUsages.removeAll(elements);
myElementsToShowWarningIfUnused.removeAll(elements);
for (ProjectStructureElement element : elements) {
myWarningsAboutUnused.remove(element);
myProblemHolders.remove(element);
final Collection<ProjectStructureElementUsage> usages = mySourceElement2Usages.removeAll(element);
if (usages != null) {
for (ProjectStructureElementUsage usage : usages) {
myProblemHolders.remove(usage.getContainingElement());
}
}
removeUsagesInElement(element);
myDispatcher.getMulticaster().problemsChanged(element);
}
myResultsUpdateQueue.queue(new ReportUnusedElementsUpdate());
}
private void reportUnusedElements() {
if (!myElementWithNotCalculatedUsages.isEmpty()) return;
@@ -205,8 +188,10 @@ public class ProjectStructureDaemonAnalyzer implements Disposable {
LOG.debug("analyzer stopped");
myStopped.set(true);
myAnalyzerQueue.cancelAllUpdates();
myResultsUpdateQueue.cancelAllUpdates();
clearCaches();
myAnalyzerQueue.deactivate();
myResultsUpdateQueue.deactivate();
}
public void clearCaches() {
@@ -232,6 +217,7 @@ public class ProjectStructureDaemonAnalyzer implements Disposable {
public void dispose() {
myStopped.set(true);
myAnalyzerQueue.cancelAllUpdates();
myResultsUpdateQueue.cancelAllUpdates();
}
@Nullable
@@ -256,6 +242,7 @@ public class ProjectStructureDaemonAnalyzer implements Disposable {
public void reset() {
LOG.debug("analyzer started");
myAnalyzerQueue.activate();
myResultsUpdateQueue.activate();
myAnalyzerQueue.queue(new Update("reset") {
@Override
public void run() {
@@ -270,9 +257,7 @@ public class ProjectStructureDaemonAnalyzer implements Disposable {
mySourceElement2Usages.clear();
myContainingElement2Usages.clear();
myElementWithNotCalculatedUsages.clear();
if (myProjectConfigurationProblems != null) {
myProjectConfigurationProblems.clearProblems();
}
myProjectConfigurationProblems.clearProblems();
}
private class AnalyzeElementUpdate extends Update {
@@ -312,4 +297,78 @@ public class ProjectStructureDaemonAnalyzer implements Disposable {
}
}
}
private class UsagesCollectedUpdate extends Update {
private final ProjectStructureElement myElement;
private final List<ProjectStructureElementUsage> myUsages;
private final Object[] myEqualityObjects;
public UsagesCollectedUpdate(ProjectStructureElement element, List<ProjectStructureElementUsage> usages) {
super(element);
myElement = element;
myUsages = usages;
myEqualityObjects = new Object[]{element, "usages collected"};
}
@NotNull
@Override
public Object[] getEqualityObjects() {
return myEqualityObjects;
}
@Override
public void run() {
if (myStopped.get()) return;
if (LOG.isDebugEnabled()) {
LOG.debug("updating usages for " + myElement);
}
updateUsages(myElement, myUsages);
}
}
private class ProblemsComputedUpdate extends Update {
private final ProjectStructureElement myElement;
private final ProjectStructureProblemsHolderImpl myProblemsHolder;
private final Object[] myEqualityObjects;
public ProblemsComputedUpdate(ProjectStructureElement element, ProjectStructureProblemsHolderImpl problemsHolder) {
super(element);
myElement = element;
myProblemsHolder = problemsHolder;
myEqualityObjects = new Object[]{element, "problems computed"};
}
@NotNull
@Override
public Object[] getEqualityObjects() {
return myEqualityObjects;
}
@Override
public void run() {
if (myStopped.get()) return;
if (LOG.isDebugEnabled()) {
LOG.debug("updating problems for " + myElement);
}
final ProjectStructureProblemDescription warning = myWarningsAboutUnused.get(myElement);
if (warning != null) {
myProblemsHolder.registerProblem(warning);
}
myProblemHolders.put(myElement, myProblemsHolder);
myDispatcher.getMulticaster().problemsChanged(myElement);
}
}
private class ReportUnusedElementsUpdate extends Update {
private ReportUnusedElementsUpdate() {
super("unused elements");
}
@Override
public void run() {
reportUnusedElements();
}
}
}
@@ -18,6 +18,7 @@ package com.intellij.codeInspection.localCanBeFinal;
import com.intellij.codeInsight.FileModificationService;
import com.intellij.codeInsight.daemon.GroupNames;
import com.intellij.codeInspection.*;
import com.intellij.codeInspection.ui.MultipleCheckboxOptionsPanel;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
@@ -44,6 +45,8 @@ public class LocalCanBeFinal extends BaseJavaBatchLocalInspectionTool {
public boolean REPORT_VARIABLES = true;
public boolean REPORT_PARAMETERS = true;
public boolean REPORT_CATCH_PARAMETERS = true;
public boolean REPORT_FOREACH_PARAMETERS = true;
private final LocalQuickFix myQuickFix;
@NonNls public static final String SHORT_NAME = "LocalCanBeFinal";
@@ -148,6 +151,7 @@ public class LocalCanBeFinal extends BaseJavaBatchLocalInspectionTool {
@Override
public void visitCatchSection(PsiCatchSection section) {
super.visitCatchSection(section);
if (!REPORT_CATCH_PARAMETERS) return;
final PsiParameter parameter = section.getParameter();
if (PsiTreeUtil.getParentOfType(parameter, PsiClass.class) != PsiTreeUtil.getParentOfType(body, PsiClass.class)) {
return;
@@ -164,6 +168,7 @@ public class LocalCanBeFinal extends BaseJavaBatchLocalInspectionTool {
@Override public void visitForeachStatement(PsiForeachStatement statement) {
super.visitForeachStatement(statement);
if (!REPORT_FOREACH_PARAMETERS) return;
final PsiParameter param = statement.getIterationParameter();
if (PsiTreeUtil.getParentOfType(param, PsiClass.class) != PsiTreeUtil.getParentOfType(body, PsiClass.class)) {
return;
@@ -219,7 +224,7 @@ public class LocalCanBeFinal extends BaseJavaBatchLocalInspectionTool {
}
});
if (body.getParent() instanceof PsiMethod && isReportParameters()) {
if (body.getParent() instanceof PsiMethod && REPORT_PARAMETERS) {
final PsiMethod method = (PsiMethod)body.getParent();
if (!(method instanceof SyntheticElement)) { // e.g. JspHolderMethod
Collections.addAll(result, method.getParameterList().getParameters());
@@ -231,6 +236,16 @@ public class LocalCanBeFinal extends BaseJavaBatchLocalInspectionTool {
if (shouldBeIgnored(variable)) {
iterator.remove();
}
final PsiElement parent = variable.getParent();
if (!(parent instanceof PsiDeclarationStatement)) {
continue;
}
final PsiDeclarationStatement declarationStatement = (PsiDeclarationStatement)parent;
final PsiElement[] elements = declarationStatement.getDeclaredElements();
final PsiElement grandParent = parent.getParent();
if (elements.length > 1 && grandParent instanceof PsiForStatement) {
iterator.remove(); // do not report when more than 1 variable declared in for loop
}
}
for (PsiVariable writtenVariable : writtenVariables) {
@@ -261,19 +276,21 @@ public class LocalCanBeFinal extends BaseJavaBatchLocalInspectionTool {
private boolean shouldBeIgnored(PsiVariable psiVariable) {
if (psiVariable.hasModifierProperty(PsiModifier.FINAL)) return true;
return isLocalVariable(psiVariable) ? !isReportVariables() : !isReportParameters();
}
private static boolean isLocalVariable(PsiVariable variable) {
if (variable instanceof PsiLocalVariable) {
return true;
if (psiVariable instanceof PsiLocalVariable) {
return !REPORT_VARIABLES;
}
if (!(variable instanceof PsiParameter)) {
return false;
if (psiVariable instanceof PsiParameter) {
final PsiParameter parameter = (PsiParameter)psiVariable;
final PsiElement declarationScope = parameter.getDeclarationScope();
if (declarationScope instanceof PsiCatchSection) {
return !REPORT_CATCH_PARAMETERS;
}
else if (declarationScope instanceof PsiForeachStatement) {
return !REPORT_FOREACH_PARAMETERS;
}
return !REPORT_PARAMETERS;
}
final PsiParameter parameter = (PsiParameter)variable;
final PsiElement declarationScope = parameter.getDeclarationScope();
return !(declarationScope instanceof PsiMethod) && !(declarationScope instanceof PsiLambdaExpression);
return true;
}
@Override
@@ -326,55 +343,12 @@ public class LocalCanBeFinal extends BaseJavaBatchLocalInspectionTool {
@Override
public JComponent createOptionsPanel() {
return new OptionsPanel();
}
private boolean isReportVariables() {
return REPORT_VARIABLES;
}
private boolean isReportParameters() {
return REPORT_PARAMETERS;
}
private class OptionsPanel extends JPanel {
private final JCheckBox myReportVariablesCheckbox;
private final JCheckBox myReportParametersCheckbox;
private OptionsPanel() {
super(new GridBagLayout());
GridBagConstraints gc = new GridBagConstraints();
gc.weighty = 0;
gc.weightx = 1;
gc.fill = GridBagConstraints.HORIZONTAL;
gc.anchor = GridBagConstraints.NORTHWEST;
myReportVariablesCheckbox = new JCheckBox(InspectionsBundle.message("inspection.local.can.be.final.option"));
myReportVariablesCheckbox.setSelected(REPORT_VARIABLES);
myReportVariablesCheckbox.getModel().addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
REPORT_VARIABLES = myReportVariablesCheckbox.isSelected();
}
});
gc.gridy = 0;
add(myReportVariablesCheckbox, gc);
myReportParametersCheckbox = new JCheckBox(InspectionsBundle.message("inspection.local.can.be.final.option1"));
myReportParametersCheckbox.setSelected(REPORT_PARAMETERS);
myReportParametersCheckbox.getModel().addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
REPORT_PARAMETERS = myReportParametersCheckbox.isSelected();
}
});
gc.weighty = 1;
gc.gridy++;
add(myReportParametersCheckbox, gc);
}
final MultipleCheckboxOptionsPanel panel = new MultipleCheckboxOptionsPanel(this);
panel.addCheckbox(InspectionsBundle.message("inspection.local.can.be.final.option"), "REPORT_VARIABLES");
panel.addCheckbox(InspectionsBundle.message("inspection.local.can.be.final.option1"), "REPORT_PARAMETERS");
panel.addCheckbox(InspectionsBundle.message("inspection.local.can.be.final.option2"), "REPORT_CATCH_PARAMETERS");
panel.addCheckbox(InspectionsBundle.message("inspection.local.can.be.final.option3"), "REPORT_FOREACH_PARAMETERS");
return panel;
}
@Override
@@ -19,6 +19,7 @@ import com.intellij.ide.util.DefaultPsiElementCellRenderer;
import com.intellij.navigation.ChooseByNameContributorEx;
import com.intellij.navigation.NavigationItem;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
import com.intellij.psi.impl.PsiSuperMethodImplUtil;
@@ -30,13 +31,11 @@ import com.intellij.util.Processor;
import com.intellij.util.containers.HashSet;
import com.intellij.util.indexing.FindSymbolParameters;
import com.intellij.util.indexing.IdFilter;
import gnu.trove.THashSet;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.*;
public class DefaultSymbolNavigationContributor implements ChooseByNameContributorEx {
private static final Logger LOG = Logger.getInstance("#com.intellij.ide.util.gotoByName.DefaultSymbolNavigationContributor");
@@ -111,27 +110,40 @@ public class DefaultSymbolNavigationContributor implements ChooseByNameContribut
IdFilter filter = parameters.getIdFilter();
PsiShortNamesCache cache = PsiShortNamesCache.getInstance(scope.getProject());
//noinspection UnusedDeclaration
boolean dummy = cache.processFieldsWithName(name, new Processor<PsiField>() {
final Set<PsiMethod> collectedMethods = new THashSet<PsiMethod>();
boolean success = cache.processFieldsWithName(name, new Processor<PsiField>() {
@Override
public boolean process(PsiField field) {
if (isOpenable(field)) return processor.process(field);
return true;
}
}, scope, filter) &&
cache.processMethodsWithName(name, new Processor<PsiMethod>() {
@Override
public boolean process(PsiMethod method) {
if(!method.isConstructor() && isOpenable(method) && !hasSuperMethod(method)) return processor.process(method);
return true;
}
}, scope, filter) &&
cache.processClassesWithName(name, new Processor<PsiClass>() {
@Override
public boolean process(PsiClass aClass) {
if (isOpenable(aClass)) return processor.process(aClass);
return true;
}
}, scope, filter) &&
cache.processMethodsWithName(name, new Processor<PsiMethod>() {
@Override
public boolean process(PsiMethod method) {
if(!method.isConstructor() && isOpenable(method)) {
collectedMethods.add(method);
}
return true;
}
}, scope, filter);
if (success) {
// hashSuperMethod accesses index and can not be invoked without risk of the deadlock in processMethodsWithName
Iterator<PsiMethod> iterator = collectedMethods.iterator();
while(iterator.hasNext()) {
PsiMethod method = iterator.next();
if (!hasSuperMethod(method) && !processor.process(method)) return;
ProgressManager.checkCanceled();
iterator.remove();
}
}
}
private static class MyComparator implements Comparator<PsiModifierListOwner>{
@@ -1178,7 +1178,6 @@ public abstract class AbstractJavaBlock extends AbstractBlock implements JavaBlo
}
private boolean shouldEnforceIndentToChildren(@NotNull ASTNode node) {
// Filter only anonymous class instances as method call arguments
if (myNode.getElementType() != JavaElementType.EXPRESSION_LIST) {
return false;
}
@@ -1186,13 +1185,10 @@ public abstract class AbstractJavaBlock extends AbstractBlock implements JavaBlo
if (parent == null || parent.getElementType() != JavaElementType.METHOD_CALL_EXPRESSION) {
return false;
}
if (!isAnonymousClass(node) || !JavaFormatterUtil.hasAnonymousClassesArguments((PsiExpressionList)myNode.getPsi(), 2)) {
return false;
}
// Enforce indent only if anonymous class instance expression doesn't start new line and have anonymous class expression sibling.
ASTNode prev = node.getTreePrev();
return prev != null && !(StringUtil.containsLineBreak(prev.getChars()) && prev.getElementType() != TokenType.WHITE_SPACE);
PsiExpressionList methodParamsList = (PsiExpressionList)myNode.getPsi();
return JavaFormatterUtil.hasMultilineArguments(methodParamsList)
&& JavaFormatterUtil.isMultilineExceptArguments(methodParamsList);
}
private static boolean isAnonymousClass(@Nullable ASTNode node) {
@@ -19,10 +19,10 @@ import com.intellij.lang.ASTNode;
import com.intellij.psi.PsiExpression;
import com.intellij.psi.PsiExpressionList;
import com.intellij.psi.PsiPolyadicExpression;
import com.intellij.psi.PsiWhiteSpace;
import com.intellij.psi.impl.source.tree.JavaElementType;
import com.intellij.psi.tree.IElementType;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.HashSet;
import java.util.Set;
@@ -75,35 +75,36 @@ public class JavaFormatterUtil {
return expression1.getOperationTokenType() == expression2.getOperationTokenType();
}
/**
* Allows to check if given expression list has given number of anonymous classes.
*
* @param count interested number of anonymous classes used at the given expression list
* @return <code>true</code> if given expression list contains given number of anonymous classes;
* <code>false</code> otherwise
*/
public static boolean hasAnonymousClassesArguments(@NotNull PsiExpressionList expressionList, int count) {
int found = 0;
for (PsiExpression expression : expressionList.getExpressions()) {
ASTNode node = expression.getNode();
if (isAnonymousClass(node)) {
found++;
}
if (found >= count) {
public static boolean hasMultilineArguments(@NotNull PsiExpressionList list) {
PsiExpression[] arguments = list.getExpressions();
for (PsiExpression argument: arguments) {
ASTNode node = argument.getNode();
if (node.textContains('\n'))
return true;
}
}
return false;
}
private static boolean isAnonymousClass(@Nullable final ASTNode node) {
if (node == null) {
return false;
public static boolean isMultilineExceptArguments(@NotNull PsiExpressionList list) {
PsiExpression[] arguments = list.getExpressions();
for (PsiExpression argument : arguments) {
ASTNode beforeArgument = argument.getNode().getTreePrev();
if (isWhiteSpaceWithLineFeed(beforeArgument))
return true;
}
ASTNode nodeToCheck = node;
if (node.getElementType() == JavaElementType.NEW_EXPRESSION) {
nodeToCheck = node.getLastChildNode();
}
return nodeToCheck != null && nodeToCheck.getElementType() == JavaElementType.ANONYMOUS_CLASS;
PsiExpression lastArgument = arguments[arguments.length - 1];
ASTNode afterLastArgument = lastArgument.getNode().getTreeNext();
return isWhiteSpaceWithLineFeed(afterLastArgument);
}
private static boolean isWhiteSpaceWithLineFeed(@NotNull ASTNode node) {
return node instanceof PsiWhiteSpace
&& node.textContains('\n');
}
}
@@ -1135,7 +1135,7 @@ public class JavaSpacePropertyProcessor extends JavaElementVisitor {
createParenthSpace(mySettings.CALL_PARAMETERS_LPAREN_ON_NEXT_LINE, mySettings.SPACE_WITHIN_EMPTY_METHOD_CALL_PARENTHESES);
}
else if (myRole2 == ChildRole.RPARENTH) {
if (JavaFormatterUtil.hasAnonymousClassesArguments(list, 2)) {
if (JavaFormatterUtil.hasMultilineArguments(list) && JavaFormatterUtil.isMultilineExceptArguments(list)) {
myResult = Spacing.createSpacing(0, 0, 1, mySettings.KEEP_LINE_BREAKS, 0);
}
else {
@@ -382,7 +382,10 @@ public class PsiLiteralExpressionImpl
@Override
@NotNull
public PsiReference[] getReferences() {
if (textMatches(PsiKeyword.NULL)) return PsiReference.EMPTY_ARRAY;
IElementType type = getLiteralElementType();
if (type != JavaTokenType.STRING_LITERAL && type != JavaTokenType.INTEGER_LITERAL) {
return PsiReference.EMPTY_ARRAY; // there are references in int literals in SQL API parameters
}
return PsiReferenceService.getService().getContributedReferences(this);
}
@@ -1,7 +1,8 @@
class For {
void f(List<String> list) {
for (Iterator<String> it = list.iterator(); it.hasNext();) { // 'it' can be final but not reported
for (Iterator<String> it = list.iterator(); it.hasNext();) {
}
for (int i = 0; i < 10; i++) {}
for (int i = 0, length = 10; i < length; i++) {}
}
}
@@ -7,6 +7,7 @@ class Foo {
settings,
indentOptions,
child2.getTextRange(),
false);
false
);
}
}
@@ -127,12 +127,14 @@ public class LocalCanBeFinalTest extends InspectionTestCase {
public void testForeachNotReported() throws Exception {
myTool.REPORT_PARAMETERS = true;
myTool.REPORT_VARIABLES = false;
myTool.REPORT_FOREACH_PARAMETERS = false;
doTest();
}
public void testNestedForeach() throws Exception {
myTool.REPORT_PARAMETERS = false;
myTool.REPORT_VARIABLES = true;
myTool.REPORT_FOREACH_PARAMETERS = true;
doTest();
}
@@ -413,6 +413,9 @@ public class DirectoryIndexTest extends IdeaTestCase {
checkInfoNull(module2TestOutput);
assertFalse(myIndex.isProjectExcludeRoot(excluded));
assertTrue(myIndex.isProjectExcludeRoot(projectOutput));
assertTrue(myIndex.isProjectExcludeRoot(module2Output));
assertFalse(myIndex.isProjectExcludeRoot(module2TestOutput));
excluded.delete(this);
projectOutput.delete(this);
@@ -426,14 +429,34 @@ public class DirectoryIndexTest extends IdeaTestCase {
VirtualFile file = e.getFile();
checkInfoNull(file);
created.add(file);
String fileName = e.getFileName();
if (fileName.equals("projectOutput")) {
//todo fix and uncomment
// assertTrue(myIndex.isProjectExcludeRoot(file));
}
if (fileName.equals("module2Output")) {
//todo fix and uncomment
// assertTrue(myIndex.isProjectExcludeRoot(file));
}
if (fileName.equals("module2TestOutput")) {
assertFalse(myIndex.isProjectExcludeRoot(file));
}
}
};
VirtualFileManager.getInstance().addVirtualFileListener(l, getTestRootDisposable());
excluded = myModule1Dir.createChildDirectory(this, excluded.getName());
assertFalse(myIndex.isProjectExcludeRoot(excluded));
projectOutput = myModule1Dir.createChildDirectory(this, projectOutput.getName());
assertTrue(myIndex.isProjectExcludeRoot(projectOutput));
module2Output = myModule1Dir.createChildDirectory(this, module2Output.getName());
assertTrue(myIndex.isProjectExcludeRoot(module2Output));
module2TestOutput = myModule2Dir.createChildDirectory(this, module2TestOutput.getName());
assertFalse(myIndex.isProjectExcludeRoot(module2TestOutput));
checkInfoNull(excluded);
checkInfoNull(projectOutput);
@@ -443,6 +466,9 @@ public class DirectoryIndexTest extends IdeaTestCase {
assertEquals(created.toString(), 4, created.size());
assertFalse(myIndex.isProjectExcludeRoot(excluded));
assertTrue(myIndex.isProjectExcludeRoot(projectOutput));
assertTrue(myIndex.isProjectExcludeRoot(module2Output));
assertFalse(myIndex.isProjectExcludeRoot(module2TestOutput));
}
public void testExcludesShouldBeRecognizedRightOnRefresh() throws Exception {
@@ -539,6 +565,28 @@ public class DirectoryIndexTest extends IdeaTestCase {
assertTrue(myIndex.isProjectExcludeRoot(myOutputDir));
assertTrue(myIndex.isProjectExcludeRoot(myModule1OutputDir));
assertTrue(fileIndex.isIgnored(myModule1OutputDir));
PsiTestUtil.setCompilerOutputPath(myModule, moduleOutputUrl, true);
PsiTestUtil.setCompilerOutputPath(myModule2, moduleOutputUrl, false);
PsiTestUtil.setCompilerOutputPath(myModule2, moduleOutputUrl, true);
PsiTestUtil.setCompilerOutputPath(myModule3, moduleOutputUrl, false);
PsiTestUtil.setCompilerOutputPath(myModule3, moduleOutputUrl, true);
// now no module inherits project output dir, but it still should be project-excluded
assertTrue(myIndex.isProjectExcludeRoot(myOutputDir));
// project output inside module content shouldn't be projectExcludeRoot
VirtualFile projectOutputUnderContent = myModule1Dir.createChildDirectory(this, "projectOutputUnderContent");
getCompilerProjectExtension().setCompilerOutputUrl(projectOutputUnderContent.getUrl());
fireRootsChanged();
assertFalse(myIndex.isProjectExcludeRoot(myOutputDir));
//todo uncomment assertFalse(myIndex.isProjectExcludeRoot(projectOutputUnderContent));
projectOutputUnderContent.delete(this);
projectOutputUnderContent = myModule1Dir.createChildDirectory(this, "projectOutputUnderContent");
assertFalse(myIndex.isProjectExcludeRoot(myOutputDir));
//todo uncomment assertFalse(myIndex.isProjectExcludeRoot(projectOutputUnderContent));
}
private void checkInfo(VirtualFile dir,
@@ -39,7 +39,7 @@ public class ClsDuplicatesTest extends PsiTestCase {
JavaRecursiveElementVisitor visitor = new JavaRecursiveElementVisitor() {
@Override
public void visitPackage(PsiPackage aPackage) {
System.out.println(aPackage.getQualifiedName());
// System.out.println(aPackage.getQualifiedName());
visit(aPackage);
for (PsiPackage subPackage : aPackage.getSubPackages(scope)) {
@@ -65,7 +65,7 @@ public class ClsDuplicatesTest extends PsiTestCase {
}
super.visitClass(aClass);
PsiElement parent = aClass.getParent();
if (!(parent instanceof PsiClass)){
if (parent instanceof PsiFile){
uniques.clear();
}
}
@@ -84,8 +84,8 @@ public class CodeFormatTest {
public static String TEST = "OK!";
public static String BOOK = "ATLAS";
private static String PREFIX = "prefix.";
private static String PRIVATE_NAME = PREFIX + "private name";
public static String NAME = PREFIX + "name";
private static String PRIVATE_NAME = PREFIX + "private name";
}
''',
rules: defaultFieldsArrangement
@@ -126,7 +126,8 @@ class Sub extends Base {
void test2() {}
}''')
}
void "test overriden and utility methods"() {
void "do not test overriden and utility methods"() {
doTest(
initial: '''\
class Base {
@@ -188,4 +189,51 @@ class Test {
}'''
)
}
void "test keep dependent methods together multiple times produce same result"() {
def groups = [group(DEPENDENT_METHODS, BREADTH_FIRST)]
def before = "public class SuperClass {\n" +
"\n" +
" public void doSmth1() {\n" +
" }\n" +
"\n" +
" public void doSmth2() {\n" +
" }\n" +
"\n" +
" public void doSmth3() {\n" +
" }\n" +
"\n" +
" public void doSmth4() {\n" +
" }\n" +
"\n" +
" public void doSmth() {\n" +
" this.doSmth1();\n" +
" this.doSmth2();\n" +
" this.doSmth3();\n" +
" this.doSmth4();\n" +
" }\n" +
"}"
def after = "public class SuperClass {\n" +
"\n" +
" public void doSmth() {\n" +
" this.doSmth1();\n" +
" this.doSmth2();\n" +
" this.doSmth3();\n" +
" this.doSmth4();\n" +
" }\n" +
" public void doSmth1() {\n" +
" }\n" +
" public void doSmth2() {\n" +
" }\n" +
" public void doSmth3() {\n" +
" }\n" +
" public void doSmth4() {\n" +
" }\n" +
"}"
doTest(initial: before, expected: after, groups: groups)
doTest(initial: after, expected: after, groups: groups)
}
}
@@ -340,10 +340,11 @@ public class JavaFormatterIndentationTest extends AbstractJavaFormatterTest {
"});",
"foo(1,\n" +
" 2, new Runnable() {\n" +
" @Override\n" +
" public void run() {\n" +
" }\n" +
"});"
" @Override\n" +
" public void run() {\n" +
" }\n" +
" }\n" +
");"
);
doMethodTest(
@@ -446,16 +447,95 @@ public class JavaFormatterIndentationTest extends AbstractJavaFormatterTest {
" }\n" +
" });",
"foo(new Runnable() {\n" +
" public void run() {\n" +
" }\n" +
" }, new Runnable() {\n" +
" public void run() {\n" +
" }\n" +
" public void run() {\n" +
" }\n" +
");"
"}, new Runnable() {\n" +
" public void run() {\n" +
" }\n" +
"});"
);
}
public void testAlignMultipleAnonymousClasses_PassedAsMethodParameters() throws Exception {
String text = "test(new Runnable() {\n" +
" @Override\n" +
" public void run() {\n" +
" System.out.println(\"AAA!\");\n" +
" }\n" +
"}, new Runnable() {\n" +
" @Override\n" +
" public void run() {\n" +
" System.out.println(\"BBB!\");\n" +
" }\n" +
"});\n";
doMethodTest(text, text);
}
public void testAlignmentAdditionalParamsWithMultipleAnonymousClasses_PassedAsMethodParameters() throws Exception {
String text = "foo(1221, new Runnable() {\n" +
" @Override\n" +
" public void run() {\n" +
" System.out.println(\"A\");\n" +
" }\n" +
"}, new Runnable() {\n" +
" @Override\n" +
" public void run() {\n" +
" System.out.println(\"BB\");\n" +
" }\n" +
"});";
doMethodTest(text, text);
}
public void testAlignmentMultipleParamsWithAnonymousClass_PassedAsMethodParams() throws Exception {
getSettings().ALIGN_MULTILINE_PARAMETERS_IN_CALLS = true;
String text = "test(1000,\n" +
" new Runnable() {\n" +
" @Override\n" +
" public void run() {\n" +
" System.out.println(\"BBB\");\n" +
" }\n" +
" }\n" +
");";
doMethodTest(text, text);
}
public void testAlignmentMultipleAnonymousClassesOnNewLines() throws Exception {
getSettings().ALIGN_MULTILINE_PARAMETERS_IN_CALLS = true;
String text = "test(1000,\n" +
" new Runnable() {\n" +
" @Override\n" +
" public void run() {\n" +
" System.out.println(\"BBB\");\n" +
" }\n" +
" },\n" +
" new Runnable() {\n" +
" @Override\n" +
" public void run() {\n" +
" System.out.println(\"BBB\");\n" +
" }\n" +
" }\n" +
");";
doMethodTest(text, text);
}
public void testEnforceChildrenIndent_OfAnonymousClasses_IfAnyOfParamsIsLocatedOnNewLine() throws Exception {
getSettings().ALIGN_MULTILINE_PARAMETERS_IN_CALLS = true;
String text = "test(\"Suuuuuuuuuuuuuuuuuper loooooooooooong string\",\n" +
" \"Next loooooooooooooooooooooong striiiiiiiiiiing\", new Runnable() {\n" +
" @Override\n" +
" public void run() {\n" +
"\n" +
" }\n" +
" }, new Runnable() {\n" +
" @Override\n" +
" public void run() {\n" +
"\n" +
" }\n" +
" }\n" +
");\n";
doMethodTest(text, text);
}
public void testPackagePrivateAnnotation() {
// Inspired by IDEA-67294
@@ -480,13 +560,12 @@ public class JavaFormatterIndentationTest extends AbstractJavaFormatterTest {
" }\n" +
" }, )",
"test(new Runnable() {\n" +
" public void run() {\n" +
" }\n" +
" }, new Runnable() {\n" +
" public void run() {\n" +
" }\n" +
" },\n" +
")"
" public void run() {\n" +
" }\n" +
"}, new Runnable() {\n" +
" public void run() {\n" +
" }\n" +
"}, )"
);
}
@@ -325,7 +325,8 @@ public class JavaFormatterWrapTest extends AbstractJavaFormatterTest {
"test(1,\n" +
" 2,\n" +
" Test.\n" +
" loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooongMethod());\n" +
" loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooongMethod()\n" +
");\n" +
"int i = 1;\n" +
"int j = 2;";
doMethodTest(text, text);
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2012 JetBrains s.r.o.
* Copyright 2000-2013 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.
@@ -25,7 +25,7 @@ public abstract class BaseActionRunnable<T> {
return mySilentExecution;
}
protected abstract void run(Result<T> result) throws Throwable;
protected abstract void run(@NotNull Result<T> result) throws Throwable;
@NotNull
public abstract RunResult<T> execute();
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2012 JetBrains s.r.o.
* Copyright 2000-2013 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.
@@ -17,6 +17,7 @@ package com.intellij.openapi.application;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.progress.ProcessCanceledException;
import org.jetbrains.annotations.NotNull;
public class RunResult<T> extends Result<T> {
@@ -28,7 +29,7 @@ public class RunResult<T> extends Result<T> {
protected RunResult() {
}
public RunResult(BaseActionRunnable<T> action) {
public RunResult(@NotNull BaseActionRunnable<T> action) {
myActionRunnable = action;
}
@@ -19,7 +19,6 @@ import com.intellij.diagnostic.Dumpable;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.event.DocumentEvent;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.ArrayUtil;
import com.intellij.util.LocalTimeCounter;
import com.intellij.util.text.CharArrayCharSequence;
import com.intellij.util.text.CharArrayUtil;
@@ -468,7 +467,7 @@ abstract class CharArray implements CharSequenceBackedByArray, Dumpable {
try {
flushDeferredChanged();
if (myOriginalSequence != null && myArray == null) {
myArray = array = ArrayUtil.realloc(CharArrayUtil.fromSequence(myOriginalSequence), myOriginalSequence.length());
myArray = array = CharArrayUtil.fromSequence(myOriginalSequence);
myStringRef = null;
}
}
@@ -18,7 +18,6 @@ package com.intellij.psi.impl;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.progress.EmptyProgressIndicator;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.project.Project;
@@ -26,7 +25,6 @@ import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.util.UnfairTextRange;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.pom.PomManager;
import com.intellij.pom.PomModel;
import com.intellij.pom.event.PomModelEvent;
@@ -41,15 +39,12 @@ import com.intellij.psi.impl.source.PsiFileImpl;
import com.intellij.psi.impl.source.text.DiffLog;
import com.intellij.psi.impl.source.tree.FileElement;
import com.intellij.psi.text.BlockSupport;
import com.intellij.util.FileContentUtilCore;
import com.intellij.util.IncorrectOperationException;
import com.intellij.util.Processor;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Arrays;
public abstract class DocumentCommitProcessor {
private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.DocumentCommitThread");
@@ -108,35 +103,26 @@ public abstract class DocumentCommitProcessor {
@NotNull final PsiFile file,
final boolean synchronously) {
Document document = task.document;
if (PsiDocumentManager.getInstance(task.project).isCommitted(document)) return null;
final TextBlock textBlock = TextBlock.get(file);
if (textBlock.isEmpty()) return null;
final long startDocModificationTimeStamp = document.getModificationStamp();
final FileElement myTreeElementBeingReparsedSoItWontBeCollected = ((PsiFileImpl)file).calcTreeElement();
if (textBlock.isEmpty()) return null; // if tree was just loaded above textBlock will be cleared by contentsLoaded
final CharSequence chars = document.getCharsSequence();
final Boolean data = document.getUserData(BlockSupport.DO_NOT_REPARSE_INCREMENTALLY);
if (data != null) {
document.putUserData(BlockSupport.DO_NOT_REPARSE_INCREMENTALLY, null);
file.putUserData(BlockSupport.DO_NOT_REPARSE_INCREMENTALLY, data);
}
final String oldPsiText = ApplicationManager.getApplication().isInternal() && ApplicationManager.getApplication().isUnitTestMode()
? myTreeElementBeingReparsedSoItWontBeCollected.getText()
: null;
final TextRange changedPsiRange =
getChangedPsiRange(file, textBlock.getStartOffset(), textBlock.getPsiEndOffset(), document.getTextLength());
if (!assertBeforeCommit(document, file, textBlock, chars, oldPsiText, myTreeElementBeingReparsedSoItWontBeCollected)) {
return new Processor<Document>() {
@Override
public boolean process(Document document) {
VirtualFile vFile = FileDocumentManager.getInstance().getFile(document);
log("Recovering from assertBeforeCommit", task, synchronously, vFile, vFile != null && vFile.isValid());
if (vFile != null && vFile.isValid()) {
FileContentUtilCore.reparseFiles(Arrays.asList(vFile));
}
return true;
}
};
final String oldPsiText = myTreeElementBeingReparsedSoItWontBeCollected.getText();
int commonPrefixLength = StringUtil.commonPrefixLength(oldPsiText, chars);
final TextRange changedPsiRange;
if (commonPrefixLength == chars.length()) {
changedPsiRange = getChangedPsiRange(file, 0, 0, chars.length());
} else {
int commonSuffixLength = StringUtil.commonSuffixLength(oldPsiText, chars);
changedPsiRange = getChangedPsiRange(file, commonPrefixLength, oldPsiText.length() - commonSuffixLength, chars.length());
}
BlockSupport blockSupport = BlockSupport.getInstance(file.getProject());
final DiffLog diffLog = blockSupport.reparseRange(file, changedPsiRange, chars, task.indicator);
@@ -206,45 +192,6 @@ public abstract class DocumentCommitProcessor {
}
}
private static boolean assertBeforeCommit(@NotNull Document document,
@NotNull PsiFile file,
@NotNull TextBlock textBlock,
@NotNull CharSequence chars,
String oldPsiText,
@NotNull FileElement myTreeElementBeingReparsedSoItWontBeCollected) {
int startOffset = textBlock.getStartOffset();
int psiEndOffset = textBlock.getPsiEndOffset();
if (oldPsiText != null) {
@NonNls String msg = "PSI/document inconsistency before reparse: file=" + file + " of class " + file.getClass();
if (startOffset >= oldPsiText.length()) {
msg += "\nstartOffset=" + oldPsiText + " while text length is " + oldPsiText.length() + "; ";
startOffset = oldPsiText.length();
}
String psiPrefix = oldPsiText.substring(0, startOffset);
String docPrefix = chars.subSequence(0, startOffset).toString();
String psiSuffix = psiEndOffset > oldPsiText.length() ? "<psiEndOffset too large>" : oldPsiText.substring(psiEndOffset);
String docSuffix = chars.subSequence(textBlock.getTextEndOffset(), chars.length()).toString();
if (!psiPrefix.equals(docPrefix) || !psiSuffix.equals(docSuffix)) {
if (!psiPrefix.equals(docPrefix)) {
msg = msg + "\n\npsiPrefix=" + psiPrefix + "\n\ndocPrefix=" + docPrefix;
}
if (!psiSuffix.equals(docSuffix)) {
msg = msg + "\n\npsiSuffix=" + psiSuffix + "\n\ndocSuffix=" + docSuffix;
}
LOG.error(msg);
return false;
}
}
else if (document.getTextLength() - textBlock.getTextEndOffset() !=
myTreeElementBeingReparsedSoItWontBeCollected.getTextLength() - psiEndOffset) {
LOG.error("PSI/document inconsistency before reparse: file=" + file);
return false;
}
return true;
}
private void assertAfterCommit(Document document,
final PsiFile file,
String oldPsiText,
@@ -617,7 +617,7 @@ public abstract class PsiFileImpl extends ElementBase implements PsiFileEx, PsiF
@Override
@NotNull
public char[] textToCharArray() {
return CharArrayUtil.fromSequenceStrict(getViewProvider().getContents());
return CharArrayUtil.fromSequence(getViewProvider().getContents());
}
@NotNull
@@ -1000,11 +1000,13 @@ public abstract class PsiFileImpl extends ElementBase implements PsiFileEx, PsiF
IElementType contentElementType = getContentElementType();
if (!(contentElementType instanceof IStubFileElementType)) {
VirtualFile vFile = getVirtualFile();
throw new AssertionError("ContentElementType: " + contentElementType + "; file: " + this +
"\n\t" + "Boolean.TRUE.equals(getUserData(BUILDING_STUB)) = " + Boolean.TRUE.equals(getUserData(BUILDING_STUB)) +
"\n\t" + "getTreeElement() = " + getTreeElement() +
"\n\t" + "vFile instanceof VirtualFileWithId = " + (vFile instanceof VirtualFileWithId) +
"\n\t" + "StubUpdatingIndex.canHaveStub(vFile) = " + StubTreeLoader.getInstance().canHaveStub(vFile));
String message = "ContentElementType: " + contentElementType + "; file: " + this +
"\n\t" + "Boolean.TRUE.equals(getUserData(BUILDING_STUB)) = " + Boolean.TRUE.equals(getUserData(BUILDING_STUB)) +
"\n\t" + "getTreeElement() = " + getTreeElement() +
"\n\t" + "vFile instanceof VirtualFileWithId = " + (vFile instanceof VirtualFileWithId) +
"\n\t" + "StubUpdatingIndex.canHaveStub(vFile) = " + StubTreeLoader.getInstance().canHaveStub(vFile);
rebuildStub();
throw new AssertionError(message);
}
StubElement currentStubTree = ((IStubFileElementType)contentElementType).getBuilder().buildStubTree(this);
@@ -16,19 +16,31 @@
package com.intellij.dvcs;
import com.intellij.dvcs.repo.Repository;
import com.intellij.dvcs.repo.RepositoryManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vcs.AbstractVcs;
import com.intellij.openapi.vcs.ProjectLevelVcsManager;
import com.intellij.openapi.vcs.VcsKey;
import com.intellij.openapi.vfs.VfsUtilCore;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.wm.StatusBar;
import com.intellij.openapi.wm.StatusBarWidget;
import com.intellij.openapi.wm.WindowManager;
import com.intellij.util.Function;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.vcs.log.VcsLog;
import com.intellij.vcs.log.VcsLogProvider;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.File;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
/**
* @author Kirill Likhodedov
@@ -97,4 +109,33 @@ public class DvcsUtil {
}
return false;
}
/**
* Report a warning that the given root has no associated Repositories.
*/
public static void noVcsRepositoryForRoot(@NotNull Logger log,
@NotNull VirtualFile root,
@NotNull Project project,
@NotNull RepositoryManager repositoryManager,
@Nullable AbstractVcs vcs) {
if (vcs == null) {
return;
}
ProjectLevelVcsManager vcsManager = ProjectLevelVcsManager.getInstance(project);
List<VirtualFile> roots = Arrays.asList(vcsManager.getRootsUnderVcs(vcs));
log.warn(String.format("Repository not found for root: %s. All roots: %s, all repositories: %s", root, roots,
repositoryManager.getRepositories()));
}
/**
* Checks if there are hg roots in the VCS log.
*/
public static boolean logHasRootForVcs(@NotNull VcsLog log, @Nullable final VcsKey vcsKey) {
return ContainerUtil.find(log.getLogProviders(), new Condition<VcsLogProvider>() {
@Override
public boolean value(VcsLogProvider logProvider) {
return logProvider.getSupportedVcs().equals(vcsKey);
}
}) != null;
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 724 B

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 562 B

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 352 B

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 492 B

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1016 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 329 B

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 468 B

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 219 B

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 143 B

After

Width:  |  Height:  |  Size: 978 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1002 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1002 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 217 B

After

Width:  |  Height:  |  Size: 978 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 168 B

After

Width:  |  Height:  |  Size: 1004 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 272 B

After

Width:  |  Height:  |  Size: 1004 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

@@ -22,13 +22,18 @@ import com.intellij.openapi.application.ReadAction;
import com.intellij.openapi.application.Result;
import com.intellij.openapi.application.ex.ApplicationEx;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.fileEditor.impl.LoadTextUtil;
import com.intellij.openapi.progress.ProcessCanceledException;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.ProgressIndicatorProvider;
import com.intellij.openapi.progress.util.TooManyUsagesStatus;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.FileIndexFacade;
import com.intellij.openapi.util.*;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.*;
@@ -40,6 +45,7 @@ import com.intellij.psi.search.*;
import com.intellij.psi.util.PsiUtilCore;
import com.intellij.util.CommonProcessors;
import com.intellij.util.Processor;
import com.intellij.util.SmartList;
import com.intellij.util.codeInsight.CommentUtilCore;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.MultiMap;
@@ -344,13 +350,14 @@ public class PsiSearchHelperImpl implements PsiSearchHelper {
final AtomicBoolean canceled = new AtomicBoolean(false);
AsyncFutureResult<Boolean> asyncFutureResult = AsyncFutureFactory.getInstance().createAsyncFutureResult();
final List<VirtualFile> failedFiles = new ArrayList<VirtualFile>();
final List<VirtualFile> failedFiles = Collections.synchronizedList(new SmartList<VirtualFile>());
try {
boolean completed =
JobLauncher.getInstance().invokeConcurrentlyUnderProgress(files, progress, false, false, new Processor<VirtualFile>() {
@Override
public boolean process(final VirtualFile vfile) {
try {
TooManyUsagesStatus.getFrom(progress).pauseProcessingIfTooManyUsages();
processVirtualFile(vfile, progress, localProcessor, canceled, counter, totalSize);
}
catch (CannotRunReadActionException action) {
@@ -361,6 +368,7 @@ public class PsiSearchHelperImpl implements PsiSearchHelper {
});
if (!failedFiles.isEmpty()) {
for (final VirtualFile vfile : failedFiles) {
TooManyUsagesStatus.getFrom(progress).pauseProcessingIfTooManyUsages();
// we failed to run read action in job launcher thread
// run read action in our thread instead
ApplicationManager.getApplication().runReadAction(new Runnable() {
@@ -381,10 +389,12 @@ public class PsiSearchHelperImpl implements PsiSearchHelper {
return asyncFutureResult;
}
private void processVirtualFile(final VirtualFile vfile,
private void processVirtualFile(@NotNull final VirtualFile vfile,
final ProgressIndicator progress,
final Processor<? super PsiFile> localProcessor,
final AtomicBoolean canceled, AtomicInteger counter, int totalSize) {
@NotNull final Processor<? super PsiFile> localProcessor,
@NotNull final AtomicBoolean canceled,
@NotNull AtomicInteger counter,
int totalSize) {
final PsiFile file = tryRead(new Computable<PsiFile>() {
@Override
public PsiFile compute() {
@@ -392,19 +402,16 @@ public class PsiSearchHelperImpl implements PsiSearchHelper {
}
});
if (file != null && !(file instanceof PsiBinaryFile)) {
file.getViewProvider().getContents(); // load contents outside read action
if (myManager.getProject().isDisposed()) throw new ProcessCanceledException();
final List<PsiFile> psiRoots = tryRead(new Computable<List<PsiFile>>() {
@Override
public List<PsiFile> compute() {
return file.getViewProvider().getAllFiles();
}
});
final Set<PsiElement> processed = new THashSet<PsiElement>(psiRoots.size() * 2, (float)0.5);
TooManyUsagesStatus.getFrom(progress).pauseProcessingIfTooManyUsages();
// load contents outside read action
if (FileDocumentManager.getInstance().getCachedDocument(vfile) == null) {
LoadTextUtil.loadText(vfile); // cache bytes in vfs
}
tryRead(new Computable<Void>() {
@Override
public Void compute() {
if (myManager.getProject().isDisposed()) throw new ProcessCanceledException();
List<PsiFile> psiRoots = file.getViewProvider().getAllFiles();
Set<PsiElement> processed = new THashSet<PsiElement>(psiRoots.size() * 2, (float)0.5);
for (final PsiFile psiRoot : psiRoots) {
checkCanceled(progress);
assert psiRoot != null : "One of the roots of file " + file + " is null. All roots: " + psiRoots +
@@ -23,6 +23,7 @@ import org.jetbrains.annotations.NotNull;
* Describes logic for injecting language inside hosting PSI element.
* E.g. "inject XPath language into all XML attributes named 'select' that sit inside XML tag prefixed with 'xsl:'".
* @see com.intellij.psi.PsiLanguageInjectionHost
* @see com.intellij.lang.injection.MultiHostInjector
*/
public interface LanguageInjector {
ExtensionPointName<LanguageInjector> EXTENSION_POINT_NAME = ExtensionPointName.create("com.intellij.languageInjector");
@@ -110,11 +110,13 @@ public class ShowParameterInfoContext implements CreateParameterInfoContext {
showMethodInfo(getProject(), getEditor(), element, getHighlightedElement(), itemsToShow, offset, handler);
}
private static void showParameterHint(final PsiElement element, final Editor editor, final Object[] descriptors,
final Project project, final ShowParameterInfoHandler.BestLocationPointProvider provider,
private static void showParameterHint(final PsiElement element,
final Editor editor,
final Object[] descriptors,
final Project project,
@Nullable PsiElement highlighted,
final int elementStart, final ParameterInfoHandler handler
) {
final int elementStart,
final ParameterInfoHandler handler) {
if (ParameterInfoController.isAlreadyShown(editor, elementStart)) return;
if (editor.isDisposed() || !editor.getComponent().isVisible()) return;
@@ -129,6 +131,7 @@ public class ShowParameterInfoContext implements CreateParameterInfoContext {
final LightweightHint hint = new LightweightHint(component);
hint.setSelectingHint(true);
final HintManagerImpl hintManager = HintManagerImpl.getInstanceImpl();
final ShowParameterInfoHandler.BestLocationPointProvider provider = new MyBestLocationPointProvider(editor);
final Pair<Point, Short> pos = provider.getBestPointPosition(hint, element, elementStart, true, HintManager.UNDER);
ApplicationManager.getApplication().invokeLater(new Runnable() {
@@ -143,6 +146,8 @@ public class ShowParameterInfoContext implements CreateParameterInfoContext {
hintHint.setExplicitClose(true);
Editor editorToShow = editor instanceof EditorWindow ? ((EditorWindow)editor).getDelegate() : editor;
// is case of injection we need to calculate position for EditorWindow
// also we need to show the hint in the main editor because of intention bulb
hintManager.showEditorHint(hint, editorToShow, pos.getFirst(), HintManager.HIDE_BY_ESCAPE | HintManager.UPDATE_BY_SCROLLING, 0, false, hintHint);
new ParameterInfoController(project, editor, elementStart, hint, handler, provider);
}
@@ -156,8 +161,7 @@ public class ShowParameterInfoContext implements CreateParameterInfoContext {
int offset,
ParameterInfoHandler handler
) {
showParameterHint(list, editor, candidates, project, new MyBestLocationPointProvider(editor),
candidates.length > 1 ? highlighted: null,offset, handler);
showParameterHint(list, editor, candidates, project, candidates.length > 1 ? highlighted : null, offset, handler);
}
/**
@@ -115,7 +115,8 @@ public class TemplateBuilderImpl implements TemplateBuilder {
}
public void replaceElement(PsiElement element, TextRange textRange, String primaryVariableName, String otherVariableName, boolean alwaysStopAt) {
final RangeMarker key = myDocument.createRangeMarker(textRange.shiftRight(element.getTextRange().getStartOffset()));
final TextRange elementTextRange = InjectedLanguageManager.getInstance(element.getProject()).injectedToHost(element, element.getTextRange());
final RangeMarker key = myDocument.createRangeMarker(textRange.shiftRight(elementTextRange.getStartOffset()));
myAlwaysStopAtMap.put(key, alwaysStopAt ? Boolean.TRUE : Boolean.FALSE);
myVariableNamesMap.put(key, primaryVariableName);
myVariableExpressions.put(key, otherVariableName);
@@ -357,7 +357,7 @@ public class EditorSearchComponent extends EditorHeaderComponent implements Data
}
private void setupHistoryToSearchField(SearchTextField field, String[] strings) {
field.setHistorySize(strings.length);
field.setHistorySize(20);
field.setHistory(ContainerUtil.reverse(Arrays.asList(strings)));
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
* Copyright 2000-2013 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.
@@ -87,7 +87,7 @@ public class FindUsagesManager implements JDOMExternalizable {
@NonNls private static final String VALUE_START_USAGE_AGAIN = "START_AGAIN";
private final Project myProject;
private final com.intellij.usages.UsageViewManager myAnotherManager;
private boolean myToOpenInNewTab = false;
private boolean myToOpenInNewTab = true;
public static class SearchData {
public SmartPsiElementPointer[] myElements = null;
@@ -80,6 +80,7 @@ import com.intellij.ui.components.JBLabel;
import com.intellij.ui.components.JBList;
import com.intellij.ui.components.JBScrollPane;
import com.intellij.ui.components.OnOffButton;
import com.intellij.ui.components.panels.NonOpaquePanel;
import com.intellij.ui.popup.AbstractPopup;
import com.intellij.ui.popup.PopupPositionManager;
import com.intellij.util.*;
@@ -136,6 +137,7 @@ public class SearchEverywhereAction extends AnAction implements CustomComponentA
private Alarm myAlarm = new Alarm(Alarm.ThreadToUse.POOLED_THREAD, ApplicationManager.getApplication());
private Alarm myUpdateAlarm = new Alarm(ApplicationManager.getApplication());
private JBList myList = new JBList(myListModel);
private JCheckBox myNonProjectCheckBox = new JCheckBox();
private AnActionEvent myActionEvent;
private Component myContextComponent;
private CalcThread myCalcThread;
@@ -248,8 +250,8 @@ public class SearchEverywhereAction extends AnAction implements CustomComponentA
@Override
protected void paintComponent(Graphics g) {
if (myBalloon != null && !myBalloon.isDisposed() && myActionEvent != null && myActionEvent.getInputEvent() instanceof MouseEvent) {
((Graphics2D)g).setPaint(new GradientPaint(0,0, new JBColor(new Color(101, 136, 242), new Color(48, 87, 186)), 0, getHeight(),
new JBColor(new Color(44, 96, 238), new Color(48, 87, 186))));
((Graphics2D)g).setPaint(new GradientPaint(0,0, new JBColor(new Color(147, 162, 174), new Color(64, 80, 94)), 0, getHeight(),
new JBColor(new Color(116, 128, 143), new Color(53, 65, 87))));
g.fillRect(0,0,getWidth(), getHeight());
} else {
super.paintComponent(g);
@@ -311,6 +313,30 @@ public class SearchEverywhereAction extends AnAction implements CustomComponentA
}
}
});
myNonProjectCheckBox.setOpaque(false);
myNonProjectCheckBox.setAlignmentX(1.0f);
myNonProjectCheckBox.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (showAll.get() != myNonProjectCheckBox.isSelected()) {
showAll.set(!showAll.get());
final JTextField editor = UIUtil.findComponentOfType(myBalloon.getContent(), JTextField.class);
if (editor != null) {
final String pattern = editor.getText();
myAlarm.cancelAllRequests();
myAlarm.addRequest(new Runnable() {
@Override
public void run() {
if (editor.hasFocus()) {
rebuildList(pattern);
}
}
}, 30);
}
}
}
});
//noinspection SSBasedInspection
SwingUtilities.invokeLater(new Runnable() {
public void run() {
@@ -321,13 +347,8 @@ public class SearchEverywhereAction extends AnAction implements CustomComponentA
}
private void initTooltip(JLabel label) {
final Shortcut[] shortcuts = KeymapManager.getInstance().getActiveKeymap().getShortcuts(IdeActions.ACTION_SEARCH_EVERYWHERE);
final String shortcutText;
if (shortcuts.length == 0) {
shortcutText = "Double " + (SystemInfo.isMac ? MacKeymapUtil.SHIFT : "Shift");
} else {
shortcutText = KeymapUtil.getShortcutsText(shortcuts);
}
shortcutText = getShortcut();
label.setToolTipText("<html><body>Search Everywhere<br/>Press <b>"
+ shortcutText
@@ -335,6 +356,17 @@ public class SearchEverywhereAction extends AnAction implements CustomComponentA
}
private static String getShortcut() {
String shortcutText;
final Shortcut[] shortcuts = KeymapManager.getInstance().getActiveKeymap().getShortcuts(IdeActions.ACTION_SEARCH_EVERYWHERE);
if (shortcuts.length == 0) {
shortcutText = "Double " + (SystemInfo.isMac ? MacKeymapUtil.SHIFT : "Shift");
} else {
shortcutText = KeymapUtil.getShortcutsText(shortcuts);
}
return shortcutText;
}
private void initSearchField(final MySearchTextField search) {
final JTextField editor = search.getTextEditor();
// onFocusLost();
@@ -355,8 +387,14 @@ public class SearchEverywhereAction extends AnAction implements CustomComponentA
}
});
editor.addFocusListener(new FocusAdapter() {
boolean skip = false;
@Override
public void focusGained(FocusEvent e) {
if (skip) {
skip = false;
return;
}
search.setText("");
search.getTextEditor().setForeground(UIUtil.getLabelForeground());
myTitleIndexes = new TitleIndexes();
@@ -384,6 +422,11 @@ public class SearchEverywhereAction extends AnAction implements CustomComponentA
&& ((myList == e.getOppositeComponent()) || ((AbstractPopup)myPopup).getPopupWindow() == e.getOppositeComponent())) {
return;
}
if (myNonProjectCheckBox == e.getOppositeComponent()) {
skip = true;
editor.requestFocus();
return;
}
onFocusLost();
}
});
@@ -535,7 +578,8 @@ public class SearchEverywhereAction extends AnAction implements CustomComponentA
public void actionPerformed(AnActionEvent e, MouseEvent me) {
if (myBalloon != null && myBalloon.isVisible()) {
showAll.set(!showAll.get());
myPopupField.getTextEditor().setBackground(showAll.get() ? new JBColor(new Color(0xffffe4), new Color(0x494539)) : UIUtil.getTextFieldBackground());
myNonProjectCheckBox.setSelected(showAll.get());
// myPopupField.getTextEditor().setBackground(showAll.get() ? new JBColor(new Color(0xffffe4), new Color(0x494539)) : UIUtil.getTextFieldBackground());
rebuildList(myPopupField.getText());
return;
}
@@ -561,20 +605,24 @@ public class SearchEverywhereAction extends AnAction implements CustomComponentA
final JPanel panel = new JPanel(new BorderLayout()) {
@Override
protected void paintComponent(Graphics g) {
((Graphics2D)g).setPaint(new GradientPaint(0,0, new JBColor(new Color(211, 232, 253), new Color(64, 80, 94)), 0, getHeight(),
new JBColor(new Color(200, 215, 239), new Color(53, 65, 87))));
((Graphics2D)g).setPaint(new GradientPaint(0,0, new JBColor(new Color(147, 162, 174), new Color(64, 80, 94)), 0, getHeight(),
new JBColor(new Color(116, 128, 143), new Color(53, 65, 87))));
g.fillRect(0, 0, getWidth(), getHeight());
}
};
final JLabel title = new JLabel(" Search Everywhere:");
final JLabel title = new JLabel(" Search Everywhere: ");
final JPanel topPanel = new NonOpaquePanel(new BorderLayout());
title.setForeground(new JBColor(Gray._50, Gray._180));
if (SystemInfo.isMac) {
title.setFont(title.getFont().deriveFont(Font.BOLD, title.getFont().getSize() - 1f));
} else {
title.setFont(title.getFont().deriveFont(Font.BOLD));
}
panel.add(title, BorderLayout.WEST);
topPanel.add(title, BorderLayout.WEST);
myNonProjectCheckBox.setText("Include non-project items (" + getShortcut() + ")");
topPanel.add(myNonProjectCheckBox, BorderLayout.EAST);
panel.add(myPopupField, BorderLayout.CENTER);
panel.add(topPanel, BorderLayout.NORTH);
panel.setBorder(IdeBorderFactory.createEmptyBorder(3, 5, 4, 5));
final ComponentPopupBuilder builder = JBPopupFactory.getInstance().createComponentPopupBuilder(panel, myPopupField.getTextEditor());
myBalloon = builder
@@ -595,7 +643,7 @@ public class SearchEverywhereAction extends AnAction implements CustomComponentA
showPoint = new RelativePoint(button, new Point(button.getWidth() - panel.getPreferredSize().width, button.getHeight()));
} else {
if (parent != null) {
int height = UISettings.getInstance().SHOW_MAIN_TOOLBAR ? 95 : 75;
int height = UISettings.getInstance().SHOW_MAIN_TOOLBAR ? 135 : 115;
if (parent instanceof IdeFrameImpl && ((IdeFrameImpl)parent).isInFullScreen()) {
height -= 20;
}
@@ -1165,6 +1213,11 @@ public class SearchEverywhereAction extends AnAction implements CustomComponentA
}
private void buildClasses(String pattern, boolean includeLibraries) {
if (pattern.indexOf('.') != -1) {
//todo[kb] it's not a mistake. If we search for "*.png" or "index.xml" in SearchEverywhere
//todo[kb] we don't want to see Java classes started with Png or Xml. This approach should be reworked someday.
return;
}
boolean includeLibs = includeLibraries || showAll.get();
int clsCounter = 0;
final int maxCount = includeLibraries ? 5 : MAX_CLASSES;
@@ -1435,6 +1488,7 @@ public class SearchEverywhereAction extends AnAction implements CustomComponentA
myCalcThread = null;
myPopup = null;
showAll.set(false);
myNonProjectCheckBox.setSelected(false);
ActionToolbarImpl.updateAllToolbarsImmediately();
if (myActionEvent != null && myActionEvent.getInputEvent() instanceof MouseEvent) {
final Component component = myActionEvent.getInputEvent().getComponent();
@@ -36,6 +36,7 @@ import com.intellij.openapi.editor.ex.util.EditorUtil;
import com.intellij.openapi.editor.highlighter.EditorHighlighter;
import com.intellij.openapi.editor.highlighter.LightHighlighterClient;
import com.intellij.openapi.editor.impl.EditorImpl;
import com.intellij.openapi.editor.impl.SoftWrapModelImpl;
import com.intellij.openapi.editor.impl.TextDrawingCallback;
import com.intellij.openapi.editor.impl.softwrap.SoftWrapAppliancePlaces;
import com.intellij.openapi.editor.markup.MarkupModel;
@@ -73,6 +74,7 @@ public class EditorWindow extends UserDataHolderBase implements EditorEx {
private boolean myDisposed;
private final MarkupModelWindow myMarkupModelDelegate;
private final FoldingModelWindow myFoldingModelWindow;
private final SoftWrapModelImpl mySoftWrapModel;
public static Editor create(@NotNull final DocumentWindowImpl documentRange, @NotNull final EditorImpl editor, @NotNull final PsiFile injectedFile) {
assert documentRange.isValid();
@@ -106,6 +108,8 @@ public class EditorWindow extends UserDataHolderBase implements EditorEx {
mySelectionModelDelegate = new SelectionModelWindow(myDelegate, myDocumentWindow,this);
myMarkupModelDelegate = new MarkupModelWindow((MarkupModelEx)myDelegate.getMarkupModel(), myDocumentWindow);
myFoldingModelWindow = new FoldingModelWindow(delegate.getFoldingModel(), documentWindow, this);
mySoftWrapModel = new SoftWrapModelImpl(this);
Disposer.register(myDocumentWindow, mySoftWrapModel);
}
public static void disposeInvalidEditors() {
@@ -167,12 +171,8 @@ public class EditorWindow extends UserDataHolderBase implements EditorEx {
else {
int offset = lineStartOffset + column;
int hostOffset = getDocument().injectedToHost(offset);
int hostLineNumber = getDocument().getDelegate().getLineNumber(hostOffset);
int hostLineStart = getDocument().getDelegate().getLineStartOffset(hostLineNumber);
return new LogicalPosition(hostLineNumber, hostOffset - hostLineStart);
return myDelegate.offsetToLogicalPosition(hostOffset);
}
}
private void dispose() {
@@ -266,7 +266,7 @@ public class EditorWindow extends UserDataHolderBase implements EditorEx {
@Override
@NotNull
public SoftWrapModelEx getSoftWrapModel() {
return myDelegate.getSoftWrapModel();
return mySoftWrapModel;
}
@Override
@@ -35,11 +35,18 @@ import java.util.LinkedList;
/**
* @author gregsh
*/
@SuppressWarnings("StringEquality")
public class GeneratedParserUtilBase {
private static final Logger LOG = Logger.getInstance("org.intellij.grammar.parser.GeneratedParserUtilBase");
private static final int MAX_RECURSION_LEVEL = 1000;
private static final int MAX_VARIANTS_SIZE = 10000;
private static final int MAX_VARIANTS_TO_DISPLAY = 50;
private static final int INITIAL_VARIANTS_SIZE = 1000;
private static final int VARIANTS_POOL_SIZE = 10000;
private static final int FRAMES_POOL_SIZE = 500;
public static final IElementType DUMMY_BLOCK = new DummyBlockElementType();
public interface Parser {
@@ -66,16 +73,29 @@ public class GeneratedParserUtilBase {
return builder_.eof();
}
public static int current_position_(PsiBuilder builder_) {
return builder_.rawTokenIndex();
}
public static boolean recursion_guard_(PsiBuilder builder_, int level_, String funcName_) {
if (level_ > 1000) {
builder_.error("Maximum recursion level (" + 1000 + ") reached in " + funcName_);
if (level_ > MAX_RECURSION_LEVEL) {
builder_.error("Maximum recursion level (" + MAX_RECURSION_LEVEL + ") reached in '" + funcName_ + "'");
return false;
}
return true;
}
@Deprecated
public static void empty_element_parsed_guard_(PsiBuilder builder_, int offset_, String funcName_) {
builder_.error("Empty element parsed in " + funcName_ +" at offset " + offset_);
builder_.error("Empty element parsed in '" + funcName_ + "' at offset " + offset_);
}
public static boolean empty_element_parsed_guard_(PsiBuilder builder_, String funcName_, int prev_position_) {
if (prev_position_ == current_position_(builder_)) {
builder_.error("Empty element parsed in '" + funcName_ + "' at offset " + builder_.getCurrentOffset());
return false;
}
return true;
}
public static boolean invalid_left_marker_guard_(PsiBuilder builder_, PsiBuilder.Marker marker_, String funcName_) {
@@ -153,6 +173,33 @@ public class GeneratedParserUtilBase {
return builder_.getTokenType() == token;
}
public static boolean nextTokenIsFast(PsiBuilder builder_, IElementType... tokens) {
IElementType tokenType = builder_.getTokenType();
for (IElementType token : tokens) {
if (token == tokenType) return true;
}
return false;
}
public static boolean nextTokenIs(PsiBuilder builder_, String frameName, IElementType... tokens) {
ErrorState state = ErrorState.get(builder_);
if (state.completionState != null) return true;
boolean track = !state.suppressErrors && state.predicateCount < 2 && state.predicateSign;
if (!track) return nextTokenIsFast(builder_, tokens);
boolean useFrameName = StringUtil.isNotEmpty(frameName);
IElementType tokenType = builder_.getTokenType();
if (tokenType == null) return false;
boolean result = false;
for (IElementType token : tokens) {
if (!useFrameName) addVariant(builder_, state, token);
result |= tokenType == token;
}
if (useFrameName) {
addVariantInner(state, builder_.getCurrentOffset(), frameName);
}
return result;
}
public static boolean nextTokenIs(PsiBuilder builder_, IElementType token) {
return nextTokenIsInner(builder_, token, false);
}
@@ -167,6 +214,7 @@ public class GeneratedParserUtilBase {
return token == tokenType;
}
@Deprecated
public static boolean replaceVariants(PsiBuilder builder_, int variantCount, String frameName) {
ErrorState state = ErrorState.get(builder_);
if (!state.suppressErrors && state.predicateCount < 2 && state.predicateSign) {
@@ -282,6 +330,8 @@ public class GeneratedParserUtilBase {
public static final String _SECTION_RECOVER_ = "_SECTION_RECOVER_";
public static final String _SECTION_GENERAL_ = "_SECTION_GENERAL_";
@SuppressWarnings("StringEquality")
@Deprecated
public static void enterErrorRecordingSection(PsiBuilder builder_, int level, @NotNull String sectionType, @Nullable String frameName) {
int modifiers = sectionType == _SECTION_GENERAL_ ? _NONE_ :
sectionType == _SECTION_NOT_ ? _NOT_ :
@@ -289,6 +339,7 @@ public class GeneratedParserUtilBase {
enter_section_impl_(builder_, level, modifiers, frameName);
}
@Deprecated
public static boolean exitErrorRecordingSection(PsiBuilder builder_,
int level,
boolean result,
@@ -356,7 +407,7 @@ public class GeneratedParserUtilBase {
public static void exit_section_(PsiBuilder builder_,
int level,
PsiBuilder.Marker marker,
IElementType elementType,
@Nullable IElementType elementType,
boolean result,
boolean pinned,
@Nullable Parser eatMore) {
@@ -464,7 +515,9 @@ public class GeneratedParserUtilBase {
if ((frame.modifiers & _COLLAPSE_) != 0) {
LighterASTNode last = result || pinned? builder_.getLatestDoneMarker() : null;
if (last != null && last.getStartOffset() == frame.offset && state.typeExtends(last.getTokenType(), elementType)) {
marker.drop();
IElementType resultType = last.getTokenType();
((PsiBuilder.Marker)last).drop();
marker.done(resultType);
return;
}
}
@@ -527,7 +580,7 @@ public class GeneratedParserUtilBase {
public static void report_error_(PsiBuilder builder_, ErrorState state, boolean advance) {
Frame frame = state.frameStack.isEmpty()? null : state.frameStack.getLast();
if (frame == null) {
LOG.error("Unbalanced error section: got null , expected " + frame);
LOG.error("unbalanced enter/exit section call: got null");
return;
}
int offset = builder_.getCurrentOffset();
@@ -628,10 +681,10 @@ public class GeneratedParserUtilBase {
public boolean altMode;
private int lastExpectedVariantOffset = -1;
public MyList<Variant> variants = new MyList<Variant>(500);
public MyList<Variant> unexpected = new MyList<Variant>(10);
public MyList<Variant> variants = new MyList<Variant>(INITIAL_VARIANTS_SIZE);
public MyList<Variant> unexpected = new MyList<Variant>(INITIAL_VARIANTS_SIZE / 10);
final LimitedPool<Variant> VARIANTS = new LimitedPool<Variant>(1000, new LimitedPool.ObjectFactory<Variant>() {
final LimitedPool<Variant> VARIANTS = new LimitedPool<Variant>(VARIANTS_POOL_SIZE, new LimitedPool.ObjectFactory<Variant>() {
@Override
public Variant create() {
return new Variant();
@@ -641,7 +694,7 @@ public class GeneratedParserUtilBase {
public void cleanup(final Variant o) {
}
});
final LimitedPool<Frame> FRAMES = new LimitedPool<Frame>(100, new LimitedPool.ObjectFactory<Frame>() {
final LimitedPool<Frame> FRAMES = new LimitedPool<Frame>(FRAMES_POOL_SIZE, new LimitedPool.ObjectFactory<Frame>() {
@Override
public Frame create() {
return new Frame();
@@ -677,7 +730,6 @@ public class GeneratedParserUtilBase {
return sb.toString();
}
private static final int MAX_VARIANTS_TO_DISPLAY = Integer.MAX_VALUE;
private boolean addExpected(StringBuilder sb, int offset, boolean expected) {
MyList<Variant> list = expected ? variants : unexpected;
String[] strings = new String[list.size()];
@@ -729,14 +781,13 @@ public class GeneratedParserUtilBase {
}
boolean typeExtends(IElementType child_, IElementType parent_) {
if (extendsSets == null) {
return child_ == parent_ ||
altExtendsChecker != null && altExtendsChecker.process(child_, parent_);
if (child_ == parent_) return true;
if (extendsSets != null) {
for (TokenSet set : extendsSets) {
if (set.contains(child_) && set.contains(parent_)) return true;
}
}
for (TokenSet set : extendsSets) {
if (set.contains(child_) && set.contains(parent_)) return true;
}
return false;
return altExtendsChecker != null && altExtendsChecker.process(child_, parent_);
}
}
@@ -816,15 +867,6 @@ public class GeneratedParserUtilBase {
}
}
@Nullable
private static IElementType getClosingBracket(ErrorState state, IElementType type) {
if (state.braces == null) return null;
for (BracePair pair : state.braces) {
if (type == pair.getLeftBraceType()) return pair.getRightBraceType();
}
return null;
}
private static final int MAX_CHILDREN_IN_TREE = 10;
public static boolean parseAsTree(ErrorState state, final PsiBuilder builder_, int level, final IElementType chunkType,
@@ -961,7 +1003,16 @@ public class GeneratedParserUtilBase {
}
protected void setSize(int fromIndex) {
super.removeRange(fromIndex, size());
removeRange(fromIndex, size());
}
@Override
public void ensureCapacity(int minCapacity) {
int size = size();
if (size >= MAX_VARIANTS_SIZE) {
removeRange(MAX_VARIANTS_SIZE / 4, size - MAX_VARIANTS_SIZE / 4);
}
super.ensureCapacity(minCapacity);
}
}
}
@@ -24,14 +24,12 @@ import com.intellij.openapi.options.ConfigurationException;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.ModifiableRootModel;
import com.intellij.openapi.roots.ModuleRootManager;
import com.intellij.openapi.roots.ui.configuration.ModulesProvider;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.platform.WebProjectGenerator;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.util.List;
/**
* @author Dmitry Avdeev
@@ -72,13 +70,14 @@ public class WebModuleBuilder extends ModuleBuilder {
return myTemplate != null ? myTemplate.getIcon() : ICON;
}
@Nullable
@Override
public List<Module> commit(Project project, ModifiableModuleModel model, ModulesProvider modulesProvider) {
List<Module> modules = super.commit(project, model, modulesProvider);
if (modules != null && !modules.isEmpty() && myTemplate != null) {
doGenerate(myTemplate, modules.get(0));
public Module commitModule(@NotNull Project project, @Nullable ModifiableModuleModel model) {
Module module = super.commitModule(project, model);
if (module != null && myTemplate != null) {
doGenerate(myTemplate, module);
}
return modules;
return module;
}
private static <T> void doGenerate(@NotNull WebProjectTemplate<T> template, @NotNull Module module) {
@@ -657,15 +657,10 @@ public class DirectoryIndexImpl extends DirectoryIndex {
return getRootIndex().isProjectExcludeRoot(dir);
}
//noinspection UnnecessaryLocalVariable
boolean standardResult = myState.myProjectExcludeRoots.contains(((NewVirtualFile)dir).getId());
/* todo
RootIndex rootIndex = getRootIndex();
Boolean riResult = rootIndex != null ? rootIndex.isProjectExcludeRoot(dir) : null;
return assertConsistentResult(dir, riResult, standardResult);
*/
return standardResult;
}
private VirtualFile findFileById(int dir) {
@@ -25,6 +25,7 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.*;
import com.intellij.openapi.roots.impl.libraries.LibraryEx;
import com.intellij.openapi.roots.libraries.Library;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VfsUtilCore;
import com.intellij.openapi.vfs.VirtualFile;
@@ -32,6 +33,7 @@ import com.intellij.openapi.vfs.newvfs.events.VFileEvent;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.MultiMap;
import gnu.trove.TObjectIntHashMap;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jps.model.java.JavaSourceRootType;
@@ -44,6 +46,7 @@ class RootIndex {
private static final DirectoryInfo NULL_INFO = DirectoryInfo.createNew();
private final Set<VirtualFile> myProjectExcludedRoots = ContainerUtil.newHashSet();
private final Set<VirtualFile> myModuleExcludedRoots = ContainerUtil.newHashSet();
private final Set<VirtualFile> myLibraryExcludedRoots = ContainerUtil.newHashSet();
private final Map<VirtualFile, DirectoryInfo> myRoots = ContainerUtil.newTroveMap();
private final Map<String, HashSet<VirtualFile>> myPackagePrefixRoots = ContainerUtil.newHashMap();
@@ -71,7 +74,13 @@ class RootIndex {
for (ContentEntry contentEntry : contentEntries) {
// Init excluded roots
Collections.addAll(myProjectExcludedRoots, contentEntry.getExcludeFolderFiles());
VirtualFile[] excluded = contentEntry.getExcludeFolderFiles();
for (VirtualFile excludeRoot : excluded) {
if (!FileUtil.startsWith(excludeRoot.getUrl(), contentEntry.getUrl())) {
myProjectExcludedRoots.add(excludeRoot);
}
myModuleExcludedRoots.add(excludeRoot);
}
// Init module sources
SourceFolder[] sourceFolders = contentEntry.getSourceFolders();
@@ -157,7 +166,9 @@ class RootIndex {
}
for (DirectoryIndexExcludePolicy policy : Extensions.getExtensions(DirectoryIndexExcludePolicy.EP_NAME, project)) {
Collections.addAll(myProjectExcludedRoots, policy.getExcludeRootsForProject());
VirtualFile[] excludeRoots = policy.getExcludeRootsForProject();
Collections.addAll(myModuleExcludedRoots, excludeRoots);
Collections.addAll(myProjectExcludedRoots, excludeRoots);
}
// fill ordered entries
@@ -224,7 +235,10 @@ class RootIndex {
}
public void checkConsistency() {
for (VirtualFile file : myProjectExcludedRoots) {
for (VirtualFile file : myLibraryExcludedRoots) {
assert file.exists() : file.getPath() + " does not exist";
}
for (VirtualFile file : myModuleExcludedRoots) {
assert file.exists() : file.getPath() + " does not exist";
}
for (VirtualFile file : myLibraryExcludedRoots) {
@@ -346,7 +360,7 @@ class RootIndex {
}
private boolean isAnyExcludeRoot(VirtualFile root) {
return myProjectExcludedRoots.contains(root) || myLibraryExcludedRoots.contains(root);
return myModuleExcludedRoots.contains(root) || myLibraryExcludedRoots.contains(root);
}
public boolean isProjectExcludeRoot(@NotNull final VirtualFile dir) {
@@ -390,6 +404,7 @@ class RootIndex {
return result;
}
@Contract("_,null->false")
private boolean isValidPackageDirectory(boolean includeLibrarySources, @Nullable VirtualFile file) {
if (file != null) {
DirectoryInfo info = getInfoForDirectory(file);
@@ -273,14 +273,18 @@ public class ArrangementEngine {
for (int i = 0; i < arranged.size() && !dependent.isEmpty(); i++) {
E e = arranged.get(i);
List<E> shouldBeAddedAfterCurrentElement = ContainerUtil.newArrayList();
for (Iterator<Pair<Set<ArrangementEntry>, E>> iterator = dependent.iterator(); iterator.hasNext(); ) {
Pair<Set<ArrangementEntry>, E> pair = iterator.next();
pair.first.remove(e);
if (pair.first.isEmpty()) {
iterator.remove();
arranged.add(i + 1, pair.second);
shouldBeAddedAfterCurrentElement.add(pair.second);
}
}
arranged.addAll(i + 1, shouldBeAddedAfterCurrentElement);
}
return arranged;

Some files were not shown because too many files have changed in this diff Show More