Merge remote-tracking branch 'origin/master'
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
After Width: | Height: | Size: 1.3 KiB |
|
After Width: | Height: | Size: 1.3 KiB |
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 1.7 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 724 B After Width: | Height: | Size: 1.5 KiB |
|
After Width: | Height: | Size: 2.2 KiB |
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 2.3 KiB |
|
After Width: | Height: | Size: 2.3 KiB |
|
After Width: | Height: | Size: 1.4 KiB |
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 1.7 KiB |
|
After Width: | Height: | Size: 2.0 KiB |
|
After Width: | Height: | Size: 2.0 KiB |
|
After Width: | Height: | Size: 1.3 KiB |
|
After Width: | Height: | Size: 1.7 KiB |
|
After Width: | Height: | Size: 1.7 KiB |
|
After Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 562 B After Width: | Height: | Size: 1.2 KiB |
|
After Width: | Height: | Size: 1.4 KiB |
|
After Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 352 B After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 1.4 KiB |
|
After Width: | Height: | Size: 1.3 KiB |
|
After Width: | Height: | Size: 1.2 KiB |
|
After Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 2.1 KiB |
|
After Width: | Height: | Size: 3.6 KiB |
|
After Width: | Height: | Size: 1.8 KiB |
|
Before Width: | Height: | Size: 492 B After Width: | Height: | Size: 1.0 KiB |
|
After Width: | Height: | Size: 1.0 KiB |
|
After Width: | Height: | Size: 1.0 KiB |
|
After Width: | Height: | Size: 1016 B |
|
Before Width: | Height: | Size: 329 B After Width: | Height: | Size: 1.2 KiB |
|
After Width: | Height: | Size: 1.5 KiB |
|
After Width: | Height: | Size: 1.7 KiB |
|
Before Width: | Height: | Size: 468 B After Width: | Height: | Size: 1.3 KiB |
|
After Width: | Height: | Size: 1.8 KiB |
|
Before Width: | Height: | Size: 219 B After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 2.2 KiB |
|
After Width: | Height: | Size: 4.2 KiB |
|
After Width: | Height: | Size: 4.2 KiB |
|
After Width: | Height: | Size: 2.2 KiB |
|
Before Width: | Height: | Size: 143 B After Width: | Height: | Size: 978 B |
|
After Width: | Height: | Size: 1002 B |
|
After Width: | Height: | Size: 1002 B |
|
Before Width: | Height: | Size: 217 B After Width: | Height: | Size: 978 B |
|
Before Width: | Height: | Size: 168 B After Width: | Height: | Size: 1004 B |
|
After Width: | Height: | Size: 1.0 KiB |
|
After Width: | Height: | Size: 1.0 KiB |
|
Before Width: | Height: | Size: 272 B After Width: | Height: | Size: 1004 B |
|
After Width: | Height: | Size: 1.7 KiB |
|
After Width: | Height: | Size: 1.8 KiB |
|
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;
|
||||
|
||||