final Pair<Date, File> usageData = readUsageFile(usageFile);
if (usageData != null) {
final File projectFile = usageData.second;
- if ((projectFile != null && !projectFile.exists()) || DateFormatUtil.getDifferenceInDays(usageData.first, now) > unusedThresholdDays) {
+ if (projectFile != null && !projectFile.exists() || DateFormatUtil.getDifferenceInDays(usageData.first, now) > unusedThresholdDays) {
LOG.info("Clearing project build data because the project does not exist or was not opened for more than " + unusedThresholdDays + " days: " + buildDataProjectDir.getPath());
FileUtil.delete(buildDataProjectDir);
}
});
conn.subscribe(BatchFileChangeListener.TOPIC, new BatchFileChangeListener.Adapter() {
+ @Override
public void batchChangeStarted(Project project) {
cancelAutoMakeTasks(project);
}
}
});
- JobScheduler.getScheduler().scheduleWithFixedDelay(new Runnable() {
- @Override
- public void run() {
- runCommand(myGCTask);
- }
- }, 3, 180, TimeUnit.MINUTES);
+ ScheduledFuture<?> future = JobScheduler.getScheduler().scheduleWithFixedDelay((Runnable)() -> runCommand(myGCTask), 3, 180, TimeUnit.MINUTES);
+ Disposer.register(this, () -> future.cancel(false));
}
private List<Project> getOpenProjects() {
// For ordinary make all project, app settings and unsaved docs are always saved before build starts.
try {
SwingUtilities.invokeAndWait(new Runnable() {
+ @Override
public void run() {
project.save();
}
if (isProcessPreloadingEnabled(project)) {
runCommand(new Runnable() {
+ @Override
public void run() {
if (!myPreloadedBuilds.containsKey(projectPath)) {
try {
@NotNull
public static Pair<Sdk, JavaSdkVersion> getBuildProcessRuntimeSdk(Project project) {
- Sdk projectJdk = null;
- int sdkMinorVersion = 0;
- JavaSdkVersion sdkVersion = null;
-
final Set<Sdk> candidates = new LinkedHashSet<Sdk>();
final Sdk defaultSdk = ProjectRootManager.getInstance(project).getProjectSdk();
if (defaultSdk != null && defaultSdk.getSdkType() instanceof JavaSdkType) {
// now select the latest version from the sdks that are used in the project, but not older than the internal sdk version
final JavaSdk javaSdkType = JavaSdk.getInstance();
+ Sdk projectJdk = null;
+ int sdkMinorVersion = 0;
+ JavaSdkVersion sdkVersion = null;
for (Sdk candidate : candidates) {
final String vs = candidate.getVersionString();
if (vs != null) {
}
else {
final int result = candidateVersion.compareTo(sdkVersion);
- if (result > 0 || (result == 0 && candidateMinorVersion > sdkMinorVersion)) {
+ if (result > 0 || result == 0 && candidateMinorVersion > sdkMinorVersion) {
sdkVersion = candidateVersion;
sdkMinorVersion = candidateMinorVersion;
projectJdk = candidate;
// launching build process from projectTaskQueue ensures that no other build process for this project is currently running
return projectTaskQueue.submit(new Callable<Pair<RequestFuture<PreloadedProcessMessageHandler>, OSProcessHandler>>() {
+ @Override
public Pair<RequestFuture<PreloadedProcessMessageHandler>, OSProcessHandler> call() throws Exception {
if (project.isDisposed()) {
return null;
final ServerBootstrap bootstrap = NettyKt.serverBootstrap(new NioEventLoopGroup(1, ConcurrencyUtil.newNamedThreadFactory("External compiler")));
bootstrap.childHandler(new ChannelInitializer() {
@Override
- protected void initChannel(Channel channel) throws Exception {
+ protected void initChannel(@NotNull Channel channel) throws Exception {
channel.pipeline().addLast(myChannelRegistrar,
new ProtobufVarint32FrameDecoder(),
new ProtobufDecoder(CmdlineRemoteProto.Message.getDefaultInstance()),
}
}
- private static abstract class BuildManagerPeriodicTask implements Runnable {
+ private abstract static class BuildManagerPeriodicTask implements Runnable {
private final Alarm myAlarm = new Alarm(Alarm.ThreadToUse.SHARED_THREAD);
private final AtomicBoolean myInProgress = new AtomicBoolean(false);
private final Runnable myTaskRunnable = new Runnable() {
private static class NotifyingMessageHandler extends DelegatingMessageHandler {
private final Project myProject;
private final BuilderMessageHandler myDelegateHandler;
- private boolean myIsAutomake;
+ private final boolean myIsAutomake;
public NotifyingMessageHandler(@NotNull Project project, @NotNull BuilderMessageHandler delegateHandler, final boolean isAutomake) {
myProject = project;
private static final class StdOutputCollector extends ProcessAdapter {
private final Appendable myOutput;
- private int myStoredLength = 0;
+ private int myStoredLength;
public StdOutputCollector(Appendable outputSink) {
myOutput = outputSink;
}
final LocalFileSystem lfs = LocalFileSystem.getInstance();
final Set<VirtualFile> filesToRefresh = new HashSet<VirtualFile>();
ApplicationManager.getApplication().runReadAction(new Runnable() {
+ @Override
public void run() {
if (project.isDisposed()) {
return;
final SequentialTaskExecutor taskQueue;
private final Set<InternedPath> myChanged = new THashSet<InternedPath>();
private final Set<InternedPath> myDeleted = new THashSet<InternedPath>();
- private long myNextEventOrdinal = 0L;
+ private long myNextEventOrdinal;
private boolean myNeedRescan = true;
private ProjectData(@NotNull SequentialTaskExecutor taskQueue) {
}
}
- private static abstract class InternedPath {
+ private abstract static class InternedPath {
protected final int[] myPath;
/**
private static final class DelegateFuture<T> implements TaskFuture<T> {
@Nullable
private TaskFuture<? extends T> myDelegate;
- private Boolean myRequestedCancelState = null;
+ private Boolean myRequestedCancelState;
@NotNull
public synchronized TaskFuture<? extends T> getDelegate() {
return false;
}
+ @Override
public synchronized boolean cancel(boolean mayInterruptIfRunning) {
final TaskFuture<? extends T> delegate = myDelegate;
if (delegate == null) {
return delegate.cancel(mayInterruptIfRunning);
}
+ @Override
public void waitFor() {
getDelegate().waitFor();
}
+ @Override
public boolean waitFor(long timeout, TimeUnit unit) {
return getDelegate().waitFor(timeout, unit);
}
+ @Override
public boolean isCancelled() {
final TaskFuture<? extends T> delegate;
synchronized (this) {
return delegate.isCancelled();
}
+ @Override
public boolean isDone() {
final TaskFuture<? extends T> delegate;
synchronized (this) {
return delegate.isDone();
}
+ @Override
public T get() throws InterruptedException, java.util.concurrent.ExecutionException {
return getDelegate().get();
}
- public T get(long timeout, TimeUnit unit) throws InterruptedException, java.util.concurrent.ExecutionException, TimeoutException {
+ @Override
+ public T get(long timeout, @NotNull TimeUnit unit) throws InterruptedException, java.util.concurrent.ExecutionException, TimeoutException {
return getDelegate().get(timeout, unit);
}
}
myCurrentDocument = PsiDocumentManager.getInstance(getProject()).getDocument(codeFragment);
if (myCurrentDocument != null) {
- PsiDocumentManagerBase.cachePsi(myCurrentDocument, codeFragment);
+ ((PsiDocumentManagerBase)PsiDocumentManager.getInstance(getProject())).cachePsi(myCurrentDocument, codeFragment);
for (DocumentListener documentListener : myDocumentListeners) {
myCurrentDocument.addDocumentListener(documentListener);
}
import com.intellij.openapi.actionSystem.CommonDataKeys;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.actionSystem.LangDataKeys;
+import com.intellij.openapi.editor.Caret;
+import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Comparing;
import com.intellij.psi.search.PsiElementProcessor;
import com.intellij.psi.util.ClassUtil;
import com.intellij.psi.util.PsiTreeUtil;
+import com.intellij.util.containers.ContainerUtil;
import java.util.ArrayList;
import java.util.LinkedHashSet;
PsiElementProcessor.CollectElements<PsiElement> processor) {
PsiElement[] elements = LangDataKeys.PSI_ELEMENT_ARRAY.getData(dataContext);
if (elements != null) {
- collectTestMembers(elements, checkAbstract, checkIsTest, processor);
- for (PsiElement psiClass : processor.getCollection()) {
- classes.add(getQName(psiClass));
- }
- return true;
+ return collectTestMembers(elements, checkAbstract, checkIsTest, processor, classes);
}
else {
+ final Editor editor = CommonDataKeys.EDITOR.getData(dataContext);
+ if (editor != null) {
+ final List<Caret> allCarets = editor.getCaretModel().getAllCarets();
+ if (allCarets.size() > 1) {
+ final PsiFile editorFile = CommonDataKeys.PSI_FILE.getData(dataContext);
+ if (editorFile != null) {
+ final Set<PsiMethod> methods = new LinkedHashSet<PsiMethod>();
+ for (Caret caret : allCarets) {
+ ContainerUtil.addIfNotNull(methods, PsiTreeUtil.getParentOfType(editorFile.findElementAt(caret.getOffset()), PsiMethod.class));
+ }
+ if (!methods.isEmpty()) {
+ return collectTestMembers(methods.toArray(new PsiElement[0]), checkAbstract, checkIsTest, processor, classes);
+ }
+ }
+ }
+ }
final PsiElement element = CommonDataKeys.PSI_ELEMENT.getData(dataContext);
final VirtualFile[] files = CommonDataKeys.VIRTUAL_FILE_ARRAY.getData(dataContext);
if (files != null) {
return false;
}
+ private boolean collectTestMembers(PsiElement[] elements,
+ boolean checkAbstract,
+ boolean checkIsTest,
+ PsiElementProcessor.CollectElements<PsiElement> processor, LinkedHashSet<String> classes) {
+ collectTestMembers(elements, checkAbstract, checkIsTest, processor);
+ for (PsiElement psiClass : processor.getCollection()) {
+ classes.add(getQName(psiClass));
+ }
+ return true;
+ }
+
private static PsiElement[] collectLocationElements(LinkedHashSet<String> classes, DataContext dataContext) {
final Location<?>[] locations = Location.DATA_KEYS.getData(dataContext);
if (locations != null) {
final PsiLambdaExpression lambdaExpression = (PsiLambdaExpression)declarationScope;
final int parameterIndex = lambdaExpression.getParameterList().getParameterIndex((PsiParameter)resolve);
final Set<LookupElement> set = new LinkedHashSet<LookupElement>();
- final boolean overloadsFound = LambdaUtil.processParentOverloads(lambdaExpression, new Consumer<PsiType>() {
- @Override
- public void consume(PsiType functionalInterfaceType) {
- PsiType qualifierType = LambdaUtil.getLambdaParameterFromType(functionalInterfaceType, parameterIndex);
- PsiReferenceExpression fakeRef = createReference("xxx.xxx", createContextWithXxxVariable(element, qualifierType));
- set.addAll(processJavaQualifiedReference(fakeRef.getReferenceNameElement(), fakeRef, elementFilter, options, matcher, parameters));
- }
+ final boolean overloadsFound = LambdaUtil.processParentOverloads(lambdaExpression, functionalInterfaceType -> {
+ PsiType qualifierType = LambdaUtil.getLambdaParameterFromType(functionalInterfaceType, parameterIndex);
+ if (qualifierType == null) return;
+
+ PsiReferenceExpression fakeRef = createReference("xxx.xxx", createContextWithXxxVariable(element, qualifierType));
+ set.addAll(processJavaQualifiedReference(fakeRef.getReferenceNameElement(), fakeRef, elementFilter, options, matcher, parameters));
});
if (overloadsFound) return set;
}
return true;
}
- public static FakePsiElement createContextWithXxxVariable(final PsiElement place, final PsiType varType) {
+ public static FakePsiElement createContextWithXxxVariable(@NotNull PsiElement place, @NotNull PsiType varType) {
return new FakePsiElement() {
@Override
public boolean processDeclarations(@NotNull PsiScopeProcessor processor,
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.EditorModificationUtil;
-import com.intellij.openapi.util.Computable;
-import com.intellij.openapi.util.Key;
-import com.intellij.psi.*;
+import com.intellij.psi.PsiDocumentManager;
+import com.intellij.psi.PsiFile;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
public class JavaPostfixTemplateProvider implements PostfixTemplateProvider {
- public static final Key<SmartPsiElementPointer<PsiElement>> ADDED_SEMICOLON = Key.create("postfix_added_semicolon");
private final Set<PostfixTemplate> templates;
public void preExpand(@NotNull final PsiFile file, @NotNull final Editor editor) {
ApplicationManager.getApplication().assertIsDispatchThread();
- file.putUserData(ADDED_SEMICOLON, null);
if (isSemicolonNeeded(file, editor)) {
- ApplicationManager.getApplication().runWriteAction(new Runnable() {
- @Override
- public void run() {
- CommandProcessor.getInstance().runUndoTransparentAction(new Runnable() {
- public void run() {
- Document document = file.getViewProvider().getDocument();
- assert document != null;
- EditorModificationUtil.insertStringAtCaret(editor, ";", false, false);
- PsiDocumentManager.getInstance(file.getProject()).commitDocument(document);
- PsiElement at = file.findElementAt(editor.getCaretModel().getOffset());
- if (at != null && at.getNode().getElementType() == JavaTokenType.SEMICOLON) {
- file.putUserData(ADDED_SEMICOLON, SmartPointerManager.getInstance(file.getProject()).createSmartPsiElementPointer(at));
- }
- }
+ ApplicationManager.getApplication().runWriteAction(() -> {
+ CommandProcessor.getInstance().runUndoTransparentAction(
+ () -> {
+ EditorModificationUtil.insertStringAtCaret(editor, ";", false, false);
+ PsiDocumentManager.getInstance(file.getProject()).commitDocument(editor.getDocument());
});
- }
});
}
}
@Override
public void afterExpand(@NotNull final PsiFile file, @NotNull final Editor editor) {
- final SmartPsiElementPointer<PsiElement> pointer = file.getUserData(ADDED_SEMICOLON);
- if (pointer != null) {
- final PsiElement addedSemicolon = pointer.getElement();
- file.putUserData(ADDED_SEMICOLON, null);
- if (addedSemicolon != null && addedSemicolon.isValid() && addedSemicolon.getNode().getElementType() == JavaTokenType.SEMICOLON) {
- CommandProcessor.getInstance().runUndoTransparentAction(new Runnable() {
- @Override
- public void run() {
- ApplicationManager.getApplication().runWriteAction(new Runnable() {
- public void run() {
- addedSemicolon.delete();
- }
- });
- }
- });
- }
- }
}
@NotNull
@Override
public PsiFile preCheck(final @NotNull PsiFile copyFile, final @NotNull Editor realEditor, final int currentOffset) {
- return ApplicationManager.getApplication().runReadAction(new Computable<PsiFile>() {
- @Override
- public PsiFile compute() {
- Document document = copyFile.getViewProvider().getDocument();
- assert document != null;
- CharSequence sequence = document.getCharsSequence();
- StringBuilder fileContentWithSemicolon = new StringBuilder(sequence);
- if (isSemicolonNeeded(copyFile, realEditor)) {
- fileContentWithSemicolon.insert(currentOffset, ';');
- return PostfixLiveTemplate.copyFile(copyFile, fileContentWithSemicolon);
- }
+ Document document = copyFile.getViewProvider().getDocument();
+ assert document != null;
+ CharSequence sequence = document.getCharsSequence();
+ StringBuilder fileContentWithSemicolon = new StringBuilder(sequence);
+ if (isSemicolonNeeded(copyFile, realEditor)) {
+ fileContentWithSemicolon.insert(currentOffset, ';');
+ return PostfixLiveTemplate.copyFile(copyFile, fileContentWithSemicolon);
+ }
- return copyFile;
- }
- });
+ return copyFile;
}
private static boolean isSemicolonNeeded(@NotNull PsiFile file, @NotNull Editor editor) {
return new PsiClassType[]{getAnnotationSuperType(psiClass, JavaPsiFacade.getInstance(psiClass.getProject()).getElementFactory())};
}
PsiType upperBound = psiClass.getUserData(InferenceSession.UPPER_BOUND);
+ if (upperBound == null && psiClass instanceof PsiTypeParameter) {
+ upperBound = LambdaUtil.getFunctionalTypeMap().get(psiClass);
+ }
if (upperBound instanceof PsiIntersectionType) {
final PsiType[] conjuncts = ((PsiIntersectionType)upperBound).getConjuncts();
final List<PsiClassType> result = new ArrayList<PsiClassType>();
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2016 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.
import com.intellij.util.IncorrectOperationException;
import com.intellij.util.PlatformIcons;
import gnu.trove.THashSet;
-import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
final PsiClass containingClass = getContainingClass();
final String qName = containingClass != null ? containingClass.getQualifiedName() : null;
if ("java.lang.Float".equals(qName)) {
- @NonNls final String name = getName();
- if ("POSITIVE_INFINITY".equals(name)) return new Float(Float.POSITIVE_INFINITY);
- if ("NEGATIVE_INFINITY".equals(name)) return new Float(Float.NEGATIVE_INFINITY);
- if ("NaN".equals(name)) return new Float(Float.NaN);
+ String name = getName();
+ if ("POSITIVE_INFINITY".equals(name)) return Float.POSITIVE_INFINITY;
+ if ("NEGATIVE_INFINITY".equals(name)) return Float.NEGATIVE_INFINITY;
+ if ("NaN".equals(name)) return Float.NaN;
}
else if ("java.lang.Double".equals(qName)) {
- @NonNls final String name = getName();
- if ("POSITIVE_INFINITY".equals(name)) return new Double(Double.POSITIVE_INFINITY);
- if ("NEGATIVE_INFINITY".equals(name)) return new Double(Double.NEGATIVE_INFINITY);
- if ("NaN".equals(name)) return new Double(Double.NaN);
+ String name = getName();
+ if ("POSITIVE_INFINITY".equals(name)) return Double.POSITIVE_INFINITY;
+ if ("NEGATIVE_INFINITY".equals(name)) return Double.NEGATIVE_INFINITY;
+ if ("NaN".equals(name)) return Double.NaN;
}
return PsiConstantEvaluationHelperImpl.computeCastTo(initializer, getType(), visitedVars);
public String toString() {
return "PsiField:" + getName();
}
-}
+}
\ No newline at end of file
final PsiElement context,
final boolean varargs) {
try {
- //push site substitutor to parameter bounds
- final String text;
- if (m1 instanceof ClsMethodImpl) {
- final StringBuilder builder = new StringBuilder();
- ((ClsMethodImpl)m1).appendMirrorText(0, builder);
- text = builder.toString();
- }
- else {
- text = m1.getText();
- }
-
- m1 = JavaPsiFacade.getElementFactory(m1.getProject()).createMethodFromText(text, m1);
for (PsiTypeParameter parameter : m1.getTypeParameters()) {
final PsiClassType[] types = parameter.getExtendsListTypes();
if (types.length > 0) {
//don't glb to avoid flattening = Object&Interface would be preserved
//otherwise methods with different signatures could get same erasure
final PsiType upperBound = PsiIntersectionType.createIntersection(false, conjuncts.toArray(new PsiType[conjuncts.size()]));
- parameter.putUserData(UPPER_BOUND, upperBound);
+ LambdaUtil.getFunctionalTypeMap().put(parameter, upperBound);
}
}
return isMoreSpecificInternal(m1, m2, siteSubstitutor1, args, context, varargs);
}
finally {
- for (PsiTypeParameter parameter : PsiUtil.typeParametersIterable(m1)) {
- parameter.putUserData(UPPER_BOUND, null);
+ for (PsiTypeParameter parameter : m1.getTypeParameters()) {
+ LambdaUtil.getFunctionalTypeMap().remove(parameter);
}
}
}
public Set<InferenceVariable> getDependencies(InferenceSession session) {
final Set<InferenceVariable> dependencies = new LinkedHashSet<InferenceVariable>();
- for (Collection<PsiType> boundTypes : myBounds.values()) {
- if (boundTypes != null) {
- for (PsiType bound : boundTypes) {
- session.collectDependencies(bound, dependencies);
- }
- }
- }
-
+ collectBoundDependencies(session, dependencies);
+ collectTransitiveDependencies(session, dependencies, dependencies);
+
if (!session.hasCapture(this) && dependencies.isEmpty()) {
return dependencies;
}
return dependencies;
}
+ private void collectTransitiveDependencies(InferenceSession session,
+ Set<InferenceVariable> dependencies,
+ Set<InferenceVariable> rootDependencies) {
+ final LinkedHashSet<InferenceVariable> newDependencies = new LinkedHashSet<InferenceVariable>();
+
+ for (InferenceVariable dependency : dependencies) {
+ dependency.collectBoundDependencies(session, newDependencies);
+ }
+ newDependencies.removeAll(rootDependencies);
+ newDependencies.remove(this);
+
+ if (!newDependencies.isEmpty()) {
+ rootDependencies.addAll(newDependencies);
+ collectTransitiveDependencies(session, newDependencies, rootDependencies);
+ }
+ }
+
+ private void collectBoundDependencies(InferenceSession session, Set<InferenceVariable> dependencies) {
+ for (Collection<PsiType> boundTypes : myBounds.values()) {
+ if (boundTypes != null) {
+ for (PsiType bound : boundTypes) {
+ session.collectDependencies(bound, dependencies);
+ }
+ }
+ }
+ }
+
public boolean hasInstantiation(InferenceSession session) {
List<PsiType> bounds = getBounds(InferenceBound.EQ);
if (bounds != null) {
--- /dev/null
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+class Test {
+ private void foo(final Stream<String> stream) {
+ stream.collect(Collectors.collectingAndThen(Collectors.toList(), list -> list)).get(0).length();
+ }
+}
final int[] count = {0};
MarkupModelEx modelEx = (MarkupModelEx)DocumentMarkupModel.forDocument(getDocument(getFile()), getProject(), true);
- modelEx.addMarkupModelListener(getTestRootDisposable(), new MarkupModelListener() {
+ modelEx.addMarkupModelListener(getTestRootDisposable(), new MarkupModelListener.Adapter() {
@Override
public void afterAdded(@NotNull RangeHighlighterEx highlighter) {
count[0]++;
public void beforeRemoved(@NotNull RangeHighlighterEx highlighter) {
count[0]++;
}
-
- @Override
- public void attributesChanged(@NotNull RangeHighlighterEx highlighter, boolean renderersChanged) {
- }
});
type(' ');
}
@Override
- public void attributesChanged(@NotNull RangeHighlighterEx highlighter, boolean renderersChanged) {
+ public void attributesChanged(@NotNull RangeHighlighterEx highlighter, boolean renderersChanged, boolean fontStyleChanged) {
changed(highlighter, ExceptionUtil.getThrowableText(new Throwable("changed")));
}
}
@Override
- public void attributesChanged(@NotNull RangeHighlighterEx highlighter, boolean renderersChanged) {
+ public void attributesChanged(@NotNull RangeHighlighterEx highlighter, boolean renderersChanged, boolean fontStyleChanged) {
changed(highlighter, ExceptionUtil.getThrowableText(new Throwable("changed")));
}
doTest();
}
+ public void testTransitiveInferenceVariableDependencies() throws Exception {
+ doTest();
+ }
+
private void doTest() throws Exception {
doTest(false);
}
Expression e = MacroParser.parse(" variableOfType( \"java.util.Collection\" ) ");
assertTrue(e instanceof MacroCallNode);
MacroCallNode n = (MacroCallNode) e;
- assertTrue(n.getMacro(new TemplateContextType[0]) instanceof VariableOfTypeMacro);
+ assertTrue(n.getMacro() instanceof VariableOfTypeMacro);
Expression[] parameters = n.getParameters();
assertEquals(1, parameters.length);
assertTrue(parameters [0] instanceof ConstantNode);
Expression e = MacroParser.parse("variableOfType(\"A\", \"B\")");
assertTrue(e instanceof MacroCallNode);
MacroCallNode n = (MacroCallNode) e;
- assertTrue(n.getMacro(new TemplateContextType[0]) instanceof VariableOfTypeMacro);
+ assertTrue(n.getMacro() instanceof VariableOfTypeMacro);
Expression[] parameters = n.getParameters();
assertEquals(2, parameters.length);
assertTrue(parameters [0] instanceof ConstantNode);
/*
- * Copyright 2000-2015 JetBrains s.r.o.
+ * Copyright 2000-2016 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.
import com.intellij.psi.stubs.PsiFileStub;
import com.intellij.psi.stubs.StubBase;
import com.intellij.testFramework.LightIdeaTestCase;
-import com.intellij.util.cls.ClsFormatException;
import java.io.File;
-import java.io.IOException;
/**
* @author max
assertEquals(expected, actual);
}
- catch (ClsFormatException e) {
- throw new RuntimeException(e);
- }
- catch (IOException e) {
+ catch (Exception e) {
throw new RuntimeException(e);
}
}
fail("Cannot file class file for: " + className);
return null;
}
-}
+}
\ No newline at end of file
/*
- * Copyright 2000-2015 JetBrains s.r.o.
+ * Copyright 2000-2016 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.
assertEquals("pack.$Weird$Name.Inner", aClass.getQualifiedName());
}
+ public void testFieldConstantValue() {
+ PsiClass dbl = getJavaFacade().findClass(Double.class.getName(), myScope);
+ assertNotNull(dbl);
+ PsiField dnn = dbl.findFieldByName("NaN", false);
+ assertNotNull(dnn);
+ assertEquals(Double.NaN, dnn.computeConstantValue());
+
+ PsiClass cls = getFile("../../mirror/pkg/Primitives").getClasses()[0];
+ PsiField lng = cls.findFieldByName("LONG", false);
+ assertNotNull(lng);
+ assertEquals(42L, lng.computeConstantValue());
+ }
+
private PsiJavaFile getFile() {
return getFile(getTestName(false));
}
/*
- * Copyright 2000-2014 JetBrains s.r.o.
+ * Copyright 2000-2016 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.
package com.intellij.psi;
import com.intellij.JavaTestUtil;
-import com.intellij.openapi.application.ApplicationManager;
-import com.intellij.openapi.command.WriteCommandAction;
-import com.intellij.openapi.fileTypes.StdFileTypes;
-import com.intellij.openapi.roots.ModuleRootModificationUtil;
-import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.impl.JavaConstantExpressionEvaluator;
-import com.intellij.psi.search.GlobalSearchScope;
-import com.intellij.testFramework.PsiTestCase;
-import com.intellij.testFramework.PsiTestUtil;
-import org.jetbrains.annotations.NotNull;
+import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase;
-import java.io.IOException;
-
-public class ConstantValuesTest extends PsiTestCase{
+public class ConstantValuesTest extends LightCodeInsightFixtureTestCase {
private PsiClass myClass;
@Override
- protected void setUp() throws Exception {
- super.setUp();
-
- ApplicationManager.getApplication().runWriteAction(
- new Runnable() {
- @Override
- public void run() {
- try{
- String rootPath = JavaTestUtil.getJavaTestDataPath() + "/psi/constantValues";
- VirtualFile root = PsiTestUtil.createTestProjectStructure(myProject, myModule, rootPath, myFilesToDelete, true);
- ModuleRootModificationUtil.addModuleLibrary(myModule, root.getUrl());
- }
- catch(Exception e){
- LOG.error(e);
- }
- }
- }
- );
-
- myClass = myJavaFacade.findClass("ClassWithConstants", GlobalSearchScope.allScope(getProject()));
- assertNotNull(myClass);
- assertEquals(StdFileTypes.JAVA, myClass.getContainingFile().getVirtualFile().getFileType());
+ protected String getTestDataPath() {
+ return JavaTestUtil.getJavaTestDataPath() + "/psi/constantValues";
}
@Override
- protected void invokeTestRunnable(@NotNull Runnable runnable) throws Exception {
- super.invokeTestRunnable(runnable);
- final PsiJavaFile file = (PsiJavaFile)myClass.getContainingFile();
-
- WriteCommandAction.runWriteCommandAction(
- null, new Runnable() {
- @Override
- public void run() {
- try {
- file.getVirtualFile().setBinaryContent(file.getVirtualFile().contentsToByteArray());
- }
- catch (IOException e) {
- LOG.error(e);
- }
- }
- }
- );
-
- LOG.assertTrue(file.isValid());
- myClass = file.getClasses()[0];
-
- LOG.assertTrue(myClass.isValid());
- super.invokeTestRunnable(runnable);
+ protected void setUp() throws Exception {
+ super.setUp();
+ myClass = ((PsiJavaFile)myFixture.configureByFile("ClassWithConstants.java")).getClasses()[0];
}
- public void testInt1(){
+ public void testInt1() {
PsiField field = myClass.findFieldByName("INT_CONST1", false);
assertNotNull(field);
PsiLiteralExpression initializer = (PsiLiteralExpression)field.getInitializer();
assertEquals(Integer.valueOf(1), field.computeConstantValue());
}
- public void testInt2(){
+ public void testInt2() {
PsiField field = myClass.findFieldByName("INT_CONST2", false);
assertNotNull(field);
PsiPrefixExpression initializer = (PsiPrefixExpression)field.getInitializer();
assertNotNull(initializer);
assertEquals(PsiType.INT, initializer.getType());
PsiLiteralExpression operand = (PsiLiteralExpression)initializer.getOperand();
+ assertNotNull(operand);
assertEquals(Integer.valueOf(1), operand.getValue());
assertEquals("-1", initializer.getText());
assertEquals(Integer.valueOf(-1), field.computeConstantValue());
}
- public void testInt3(){
+ public void testInt3() {
PsiField field = myClass.findFieldByName("INT_CONST3", false);
assertNotNull(field);
PsiPrefixExpression initializer = (PsiPrefixExpression)field.getInitializer();
assertEquals(Integer.valueOf(value), field.computeConstantValue());
}
- public void testLong1(){
+ public void testLong1() {
PsiField field = myClass.findFieldByName("LONG_CONST1", false);
assertNotNull(field);
PsiLiteralExpression initializer = (PsiLiteralExpression)field.getInitializer();
assertEquals(Long.valueOf(2), field.computeConstantValue());
}
- public void testLong2(){
+ public void testLong2() {
PsiField field = myClass.findFieldByName("LONG_CONST2", false);
assertNotNull(field);
PsiLiteralExpression initializer = (PsiLiteralExpression)field.getInitializer();
assertEquals(Long.valueOf(1000000000000L), field.computeConstantValue());
}
- public void testLong3(){
+ public void testLong3() {
PsiField field = myClass.findFieldByName("LONG_CONST3", false);
assertNotNull(field);
PsiPrefixExpression initializer = (PsiPrefixExpression)field.getInitializer();
assertEquals(Long.valueOf(value), field.computeConstantValue());
}
- public void testShort(){
+ public void testShort() {
PsiField field = myClass.findFieldByName("SHORT_CONST", false);
assertNotNull(field);
PsiLiteralExpression initializer = (PsiLiteralExpression)field.getInitializer();
assertEquals(Short.valueOf((short)3), field.computeConstantValue());
}
- public void testByte(){
+ public void testByte() {
PsiField field = myClass.findFieldByName("BYTE_CONST", false);
assertNotNull(field);
PsiLiteralExpression initializer = (PsiLiteralExpression)field.getInitializer();
assertEquals(Byte.valueOf((byte)4), field.computeConstantValue());
}
- public void testChar(){
+ public void testChar() {
PsiField field = myClass.findFieldByName("CHAR_CONST", false);
assertNotNull(field);
PsiLiteralExpression initializer = (PsiLiteralExpression)field.getInitializer();
assertEquals(new Character('5'), field.computeConstantValue());
}
- public void testBoolean(){
+ public void testBoolean() {
PsiField field = myClass.findFieldByName("BOOL_CONST", false);
assertNotNull(field);
PsiLiteralExpression initializer = (PsiLiteralExpression)field.getInitializer();
assertEquals(Boolean.TRUE, field.computeConstantValue());
}
- public void testFloat(){
+ public void testFloat() {
PsiField field = myClass.findFieldByName("FLOAT_CONST", false);
assertNotNull(field);
PsiLiteralExpression initializer = (PsiLiteralExpression)field.getInitializer();
assertEquals(new Float(1.234f), field.computeConstantValue());
}
- public void testDouble(){
+ public void testDouble() {
PsiField field = myClass.findFieldByName("DOUBLE_CONST", false);
assertNotNull(field);
PsiLiteralExpression initializer = (PsiLiteralExpression)field.getInitializer();
assertEquals(new Double(3.456), field.computeConstantValue());
}
- public void testString(){
+ public void testString() {
PsiField field = myClass.findFieldByName("STRING_CONST", false);
assertNotNull(field);
PsiLiteralExpression initializer = (PsiLiteralExpression)field.getInitializer();
assertNotNull(initializer);
- assertTrue(initializer.getType().equalsToText("java.lang.String"));
+ PsiType type = initializer.getType();
+ assertNotNull(type);
+ assertTrue(type.equalsToText("java.lang.String"));
assertEquals("a\r\n\"bcd", initializer.getValue());
assertEquals("\"a\\r\\n\\\"bcd\"", initializer.getText());
assertEquals("a\r\n\"bcd", field.computeConstantValue());
}
- public void testInfinity(){
+ public void testInfinity() {
PsiField field1 = myClass.findFieldByName("d1", false);
assertNotNull(field1);
PsiReferenceExpression initializer1 = (PsiReferenceExpression)field1.getInitializer();
}
public void testConstantEvaluatorStackOverflowResistance() {
- String text ="class X { String s = \"\" ";
- for (int i=0;i<10000;i++) {
- text += "+ \"\"";
- }
- text += "; }";
- PsiJavaFile file = (PsiJavaFile)createDummyFile("a.java", text);
-
- PsiExpression expression = file.getClasses()[0].findFieldByName("s", false).getInitializer();
+ StringBuilder text = new StringBuilder(65536).append("class X { String s = \"\"");
+ for (int i = 0; i < 10000; i++) text.append(" + \"\"");
+ text.append("; }");
- Object o = JavaConstantExpressionEvaluator.computeConstantExpression(expression, false);
-
- assertEquals("", o);
+ PsiJavaFile file = (PsiJavaFile)myFixture.configureByText("a.java", text.toString());
+ PsiField field = file.getClasses()[0].findFieldByName("s", false);
+ assertNotNull(field);
+ assertEquals("", JavaConstantExpressionEvaluator.computeConstantExpression(field.getInitializer(), false));
}
-}
+}
\ No newline at end of file
/*
- * Copyright 2000-2015 JetBrains s.r.o.
+ * Copyright 2000-2016 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.
}
});
if (!myModuleOutputDir.exists()) {
+ VirtualFile vDir = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(ourOutputRoot);
+ assertNotNull(ourOutputRoot.getAbsolutePath(), vDir);
+ vDir.getChildren();//we need this to load children to VFS to fire VFileCreatedEvent for the output directory
+
myCompilerTester = new CompilerTester(myProject, Arrays.asList(ModuleManager.getInstance(myProject).getModules()));
List<CompilerMessage> messages = myCompilerTester.rebuild();
for (CompilerMessage message : messages) {
public abstract class PsiDocumentManagerBase extends PsiDocumentManager implements DocumentListener, ProjectComponent {
static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.PsiDocumentManagerImpl");
private static final Key<Document> HARD_REF_TO_DOCUMENT = Key.create("HARD_REFERENCE_TO_DOCUMENT");
- private static final Key<PsiFile> HARD_REF_TO_PSI = Key.create("HARD_REFERENCE_TO_PSI");
+ private final Key<PsiFile> HARD_REF_TO_PSI = Key.create("HARD_REFERENCE_TO_PSI"); // has to be different for each project to avoid mixups
private static final Key<List<Runnable>> ACTION_AFTER_COMMIT = Key.create("ACTION_AFTER_COMMIT");
protected final Project myProject;
return psiFile;
}
- public static void cachePsi(@NotNull Document document, @Nullable PsiFile file) {
+ public void cachePsi(@NotNull Document document, @Nullable PsiFile file) {
document.putUserData(HARD_REF_TO_PSI, file);
}
// public for Upsource
public boolean finishCommit(@NotNull final Document document,
- @NotNull final List<Processor<Document>> finishProcessors,
- final boolean synchronously,
- @NotNull final Object reason) {
+ @NotNull final List<Processor<Document>> finishProcessors,
+ final boolean synchronously,
+ @NotNull final Object reason) {
assert !myProject.isDisposed() : "Already disposed";
final boolean[] ok = {true};
ApplicationManager.getApplication().runWriteAction(new CommitToPsiFileAction(document, myProject) {
action.run();
}
catch (Throwable e) {
- LOG.error("During running "+action, e);
+ LOG.error("During running " + action, e);
}
}
}
/*
- * Copyright 2000-2015 JetBrains s.r.o.
+ * Copyright 2000-2016 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.
Document document = FileDocumentManager.getInstance().getCachedDocument(virtualFile);
if (document != null) {
- PsiDocumentManagerBase.cachePsi(document, null);
+ ((PsiDocumentManagerBase)PsiDocumentManager.getInstance(myManager.getProject())).cachePsi(document, null);
}
virtualFile.putUserData(myPsiHardRefKey, null);
}
/*
- * Copyright 2000-2015 JetBrains s.r.o.
+ * Copyright 2000-2016 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.
return leafTextMatches(text, buffer, start);
}
- public static int leafTextMatches(@NotNull CharSequence text, @NotNull CharSequence buffer, int start) {
+ static int leafTextMatches(@NotNull CharSequence text, @NotNull CharSequence buffer, int start) {
assert start >= 0 : start;
final int length = text.length();
if(buffer.length() - start < length) {
import java.util.Iterator;
-@SuppressWarnings("ConstantConditions")
abstract class ChangeDiffIterableBase extends DiffIterableBase {
private final int myLength1;
private final int myLength2;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
-@SuppressWarnings("ConstantConditions")
class DiffChangeDiffIterable extends ChangeDiffIterableBase {
@Nullable private final Diff.Change myChange;
return new DiffChangeChangeIterable(myChange);
}
+ @SuppressWarnings("ConstantConditions")
private static class DiffChangeChangeIterable implements ChangeIterable {
@Nullable private Diff.Change myChange;
import java.util.List;
-@SuppressWarnings("ConstantConditions")
class DiffFragmentsDiffIterable extends ChangeDiffIterableBase {
@NotNull private final List<? extends DiffFragment> myFragments;
import java.util.Iterator;
-@SuppressWarnings("ConstantConditions")
abstract class DiffIterableBase implements DiffIterable {
@NotNull
@Override
import java.util.Iterator;
-@SuppressWarnings("ConstantConditions")
class FairDiffIterableWrapper extends DiffIterableBase implements FairDiffIterable {
@NotNull private final DiffIterable myIterable;
import java.util.Iterator;
-@SuppressWarnings("ConstantConditions")
class InvertedDiffIterableWrapper extends DiffIterableBase {
@NotNull private final DiffIterable myIterable;
import java.util.List;
-@SuppressWarnings("ConstantConditions")
class RangesDiffIterable extends ChangeDiffIterableBase {
@NotNull private final List<? extends Range> myRanges;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.WindowWrapper;
import com.intellij.openapi.ui.WindowWrapperBuilder;
+import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.Disposer;
import com.intellij.util.ImageLoader;
import org.jetbrains.annotations.NotNull;
.setProject(myProject)
.setParent(myHints.getParent())
.setDimensionServiceKey(dialogGroupKey)
+ .setPreferredFocusedComponent(new Computable<JComponent>() {
+ @Override
+ public JComponent compute() {
+ return myProcessor.getPreferredFocusedComponent();
+ }
+ })
.setOnShowCallback(new Runnable() {
@Override
public void run() {
myProcessor.updateRequest();
- myProcessor.requestFocus(); // TODO: not needed for modal dialogs. Make a flag in WindowWrapperBuilder ?
}
})
.build();
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.ex.EditorEx;
import com.intellij.openapi.editor.ex.EditorGutterComponentEx;
-import com.intellij.openapi.editor.markup.LineMarkerRenderer;
+import com.intellij.openapi.editor.markup.LineMarkerRendererEx;
import com.intellij.openapi.editor.markup.RangeHighlighter;
import org.jetbrains.annotations.NotNull;
import java.awt.*;
-public class DiffLineMarkerRenderer implements LineMarkerRenderer {
+public class DiffLineMarkerRenderer implements LineMarkerRendererEx {
@NotNull private final RangeHighlighter myHighlighter;
@NotNull private final TextDiffType myDiffType;
private final boolean myIgnoredFoldingOutline;
DiffDrawUtil.drawChunkBorderLine(g2, x1, x2, y - 1, color, true, myResolved);
}
}
+
+ @Override
+ public Position getPosition() {
+ return Position.CUSTOM;
+ }
}
import com.intellij.openapi.editor.colors.EditorColorsScheme;
import com.intellij.openapi.editor.ex.EditorEx;
import com.intellij.openapi.editor.ex.EditorGutterComponentEx;
-import com.intellij.openapi.editor.markup.LineMarkerRenderer;
+import com.intellij.openapi.editor.markup.LineMarkerRendererEx;
import com.intellij.openapi.editor.markup.LineSeparatorRenderer;
import com.intellij.openapi.ui.GraphicsConfig;
import com.intellij.openapi.util.BooleanGetter;
import java.awt.geom.AffineTransform;
import java.util.Arrays;
-public class DiffLineSeparatorRenderer implements LineMarkerRenderer, LineSeparatorRenderer {
+public class DiffLineSeparatorRenderer implements LineMarkerRendererEx, LineSeparatorRenderer {
@NotNull private final Editor myEditor;
@NotNull private final BooleanGetter myCondition;
draw(g, shiftX, y, lineHeight, myEditor.getColorsScheme());
}
+ @Override
+ public LineMarkerRendererEx.Position getPosition() {
+ return LineMarkerRendererEx.Position.CUSTOM;
+ }
+
private static void draw(@NotNull Graphics g,
int shiftX,
int shiftY,
editor.getSettings().setShowIntentionBulb(false);
((EditorMarkupModel)editor.getMarkupModel()).setErrorStripeVisible(true);
editor.getGutterComponentEx().setShowDefaultGutterPopup(false);
- editor.getGutterComponentEx().setShowRightFreePaintersArea(false);
if (enableFolding) {
setFoldingModelSupport(editor);
/*
- * Copyright 2000-2014 JetBrains s.r.o.
+ * Copyright 2000-2016 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.
}
@Override
- public void fireAttributesChanged(@NotNull RangeHighlighterEx segmentHighlighter, boolean renderersChanged) {
+ public void fireAttributesChanged(@NotNull RangeHighlighterEx segmentHighlighter, boolean renderersChanged, boolean fontStyleChanged) {
}
/*
- * Copyright 2000-2014 JetBrains s.r.o.
+ * Copyright 2000-2016 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.
@Nullable
RangeHighlighterEx addPersistentLineHighlighter(int lineNumber, int layer, TextAttributes textAttributes);
- void fireAttributesChanged(@NotNull RangeHighlighterEx segmentHighlighter, boolean renderersChanged);
+ void fireAttributesChanged(@NotNull RangeHighlighterEx segmentHighlighter, boolean renderersChanged, boolean fontStyleChanged);
void fireAfterAdded(@NotNull RangeHighlighterEx segmentHighlighter);
/*
- * Copyright 2000-2014 JetBrains s.r.o.
+ * Copyright 2000-2016 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.
}
@Override
- public void fireAttributesChanged(@NotNull RangeHighlighterEx segmentHighlighter, boolean renderersChanged) {
+ public void fireAttributesChanged(@NotNull RangeHighlighterEx segmentHighlighter, boolean renderersChanged, boolean fontStyleChanged) {
}
/*
- * Copyright 2000-2014 JetBrains s.r.o.
+ * Copyright 2000-2016 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.
public void changeAttributesInBatch(@NotNull RangeHighlighterEx highlighter,
@NotNull Consumer<RangeHighlighterEx> changeAttributesAction) {
ApplicationManager.getApplication().assertIsDispatchThread();
- RangeHighlighterImpl.ChangeResult changed = ((RangeHighlighterImpl)highlighter).changeAttributesNoEvents(changeAttributesAction);
- if (changed != RangeHighlighterImpl.ChangeResult.NOT_CHANGED) {
- fireAttributesChanged(highlighter, changed == RangeHighlighterImpl.ChangeResult.RENDERERS_CHANGED);
+ byte changeStatus = ((RangeHighlighterImpl)highlighter).changeAttributesNoEvents(changeAttributesAction);
+ if ((changeStatus & RangeHighlighterImpl.CHANGED_MASK) != 0) {
+ fireAttributesChanged(highlighter,
+ (changeStatus & RangeHighlighterImpl.RENDERERS_CHANGED_MASK) != 0,
+ (changeStatus & RangeHighlighterImpl.FONT_STYLE_CHANGED_MASK) != 0);
}
}
}
@Override
- public void fireAttributesChanged(@NotNull RangeHighlighterEx segmentHighlighter, boolean renderersChanged) {
+ public void fireAttributesChanged(@NotNull RangeHighlighterEx segmentHighlighter, boolean renderersChanged, boolean fontStyleChanged) {
for (MarkupModelListener listener : myListeners) {
- listener.attributesChanged(segmentHighlighter, renderersChanged);
+ listener.attributesChanged(segmentHighlighter, renderersChanged, fontStyleChanged);
}
}
/*
- * Copyright 2000-2014 JetBrains s.r.o.
+ * Copyright 2000-2016 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.
private static final byte ERROR_STRIPE_IS_THIN_MASK = 2;
private static final byte TARGET_AREA_IS_EXACT_MASK = 4;
private static final byte IN_BATCH_CHANGE_MASK = 8;
- private static final byte CHANGED_MASK = 16;
- private static final byte RENDERERS_CHANGED_MASK = 32;
+ static final byte CHANGED_MASK = 16;
+ static final byte RENDERERS_CHANGED_MASK = 32;
+ static final byte FONT_STYLE_CHANGED_MASK = 64;
- @MagicConstant(intValues = {AFTER_END_OF_LINE_MASK, ERROR_STRIPE_IS_THIN_MASK, TARGET_AREA_IS_EXACT_MASK, IN_BATCH_CHANGE_MASK, CHANGED_MASK, RENDERERS_CHANGED_MASK})
+ @MagicConstant(intValues = {AFTER_END_OF_LINE_MASK, ERROR_STRIPE_IS_THIN_MASK, TARGET_AREA_IS_EXACT_MASK, IN_BATCH_CHANGE_MASK,
+ CHANGED_MASK, RENDERERS_CHANGED_MASK, FONT_STYLE_CHANGED_MASK})
private @interface FlagConstant {}
+ @MagicConstant(flags = {CHANGED_MASK, RENDERERS_CHANGED_MASK, FONT_STYLE_CHANGED_MASK})
+ private @interface ChangeStatus {}
+
RangeHighlighterImpl(@NotNull MarkupModel model,
int start,
int end,
TextAttributes old = myTextAttributes;
myTextAttributes = textAttributes;
if (!Comparing.equal(old, textAttributes)) {
- fireChanged(false);
+ fireChanged(false, getFontStyle(old) != getFontStyle(textAttributes));
}
}
+
+ private static int getFontStyle(TextAttributes textAttributes) {
+ return textAttributes == null ? Font.PLAIN : textAttributes.getFontType();
+ }
@Override
@NotNull
LineMarkerRenderer old = myLineMarkerRenderer;
myLineMarkerRenderer = renderer;
if (!Comparing.equal(old, renderer)) {
- fireChanged(true);
+ fireChanged(true, false);
}
}
CustomHighlighterRenderer old = myCustomRenderer;
myCustomRenderer = renderer;
if (!Comparing.equal(old, renderer)) {
- fireChanged(true);
+ fireChanged(true, false);
}
}
GutterMark old = myGutterIconRenderer;
myGutterIconRenderer = renderer;
if (!Comparing.equal(old, renderer)) {
- fireChanged(true);
+ fireChanged(true, false);
}
}
Color old = myErrorStripeColor;
myErrorStripeColor = color;
if (!Comparing.equal(old, color)) {
- fireChanged(false);
+ fireChanged(false, false);
}
}
Object old = myErrorStripeTooltip;
myErrorStripeTooltip = tooltipObject;
if (!Comparing.equal(old, tooltipObject)) {
- fireChanged(false);
+ fireChanged(false, false);
}
}
boolean old = isThinErrorStripeMark();
setFlag(ERROR_STRIPE_IS_THIN_MASK, value);
if (old != value) {
- fireChanged(false);
+ fireChanged(false, false);
}
}
Color old = myLineSeparatorColor;
myLineSeparatorColor = color;
if (!Comparing.equal(old, color)) {
- fireChanged(false);
+ fireChanged(false, false);
}
}
SeparatorPlacement old = mySeparatorPlacement;
mySeparatorPlacement = placement;
if (!Comparing.equal(old, placement)) {
- fireChanged(false);
+ fireChanged(false, false);
}
}
@Override
public void setEditorFilter(@NotNull MarkupEditorFilter filter) {
myFilter = filter;
- fireChanged(false);
+ fireChanged(false, false);
}
@Override
boolean old = isAfterEndOfLine();
setFlag(AFTER_END_OF_LINE_MASK, afterEndOfLine);
if (old != afterEndOfLine) {
- fireChanged(false);
+ fireChanged(false, false);
}
}
- private void fireChanged(boolean renderersChanged) {
+ private void fireChanged(boolean renderersChanged, boolean fontStyleChanged) {
if (myModel instanceof MarkupModelEx) {
if (isFlagSet(IN_BATCH_CHANGE_MASK)) {
setFlag(CHANGED_MASK, true);
- if (renderersChanged) {
- setFlag(RENDERERS_CHANGED_MASK, true);
- }
+ if (renderersChanged) setFlag(RENDERERS_CHANGED_MASK, true);
+ if (fontStyleChanged) setFlag(FONT_STYLE_CHANGED_MASK, true);
}
else {
- ((MarkupModelEx)myModel).fireAttributesChanged(this, renderersChanged);
+ ((MarkupModelEx)myModel).fireAttributesChanged(this, renderersChanged, fontStyleChanged);
}
}
}
}
- enum ChangeResult { NOT_CHANGED, MINOR_CHANGE, RENDERERS_CHANGED }
- @NotNull
- ChangeResult changeAttributesNoEvents(@NotNull Consumer<RangeHighlighterEx> change) {
+ @ChangeStatus
+ byte changeAttributesNoEvents(@NotNull Consumer<RangeHighlighterEx> change) {
assert !isFlagSet(IN_BATCH_CHANGE_MASK);
assert !isFlagSet(CHANGED_MASK);
setFlag(IN_BATCH_CHANGE_MASK, true);
setFlag(RENDERERS_CHANGED_MASK, false);
- ChangeResult result;
+ setFlag(FONT_STYLE_CHANGED_MASK, false);
+ byte result = 0;
try {
change.consume(this);
}
finally {
setFlag(IN_BATCH_CHANGE_MASK, false);
- boolean changed = isFlagSet(CHANGED_MASK);
- boolean renderersChanged = isFlagSet(RENDERERS_CHANGED_MASK);
- result = changed ? renderersChanged ? ChangeResult.RENDERERS_CHANGED : ChangeResult.MINOR_CHANGE : ChangeResult.NOT_CHANGED;
+ if (isFlagSet(CHANGED_MASK)) {
+ result |= CHANGED_MASK;
+ if (isFlagSet(RENDERERS_CHANGED_MASK)) result |= RENDERERS_CHANGED_MASK;
+ if (isFlagSet(FONT_STYLE_CHANGED_MASK)) result |= FONT_STYLE_CHANGED_MASK;
+ }
setFlag(CHANGED_MASK, false);
setFlag(RENDERERS_CHANGED_MASK, false);
+ setFlag(FONT_STYLE_CHANGED_MASK, false);
}
return result;
}
LineSeparatorRenderer old = myLineSeparatorRenderer;
myLineSeparatorRenderer = renderer;
if (!Comparing.equal(old, renderer)) {
- fireChanged(true);
+ fireChanged(true, false);
}
}
/*
- * Copyright 2000-2014 JetBrains s.r.o.
+ * Copyright 2000-2016 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.
void beforeRemoved(@NotNull RangeHighlighterEx highlighter);
- void attributesChanged(@NotNull RangeHighlighterEx highlighter, boolean renderersChanged);
+ void attributesChanged(@NotNull RangeHighlighterEx highlighter, boolean renderersChanged, boolean fontStyleChanged);
abstract class Adapter implements MarkupModelListener {
@Override
}
@Override
- public void attributesChanged(@NotNull RangeHighlighterEx highlighter, boolean renderersChanged) {
+ public void attributesChanged(@NotNull RangeHighlighterEx highlighter, boolean renderersChanged, boolean fontStyleChanged) {
}
}
}
import com.intellij.openapi.util.Key;
import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.NonNls;
-import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public interface ExpressionContext {
<T> T getProperty(Key<T> key);
@Nullable
PsiElement getPsiElementAtStartOffset();
-
- /**
- * @return all template context types matching the template invocation place
- */
- @NotNull
- TemplateContextType[] getCompatibleContexts();
}
import com.intellij.openapi.options.ConfigurationException;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ProjectManager;
+import com.intellij.openapi.util.Comparing;
import com.intellij.ui.CheckBoxList;
import com.intellij.ui.SeparatorWithText;
import com.intellij.util.Function;
import java.awt.*;
import java.util.*;
import java.util.List;
-import java.util.concurrent.atomic.AtomicBoolean;
/**
* @author Dmitry Avdeev
}
};
MultiMap<PluginDescriptor, LanguageExtensionPoint<LineMarkerProvider>> map = ContainerUtil.groupBy(Arrays.asList(extensions), function);
+ Map<GutterIconDescriptor, PluginDescriptor> pluginDescriptorMap = ContainerUtil.newHashMap();
myDescriptors = new ArrayList<GutterIconDescriptor>();
for (final PluginDescriptor descriptor : map.keySet()) {
Collection<LanguageExtensionPoint<LineMarkerProvider>> points = map.get(descriptor);
- final AtomicBoolean first = new AtomicBoolean(true);
for (LanguageExtensionPoint<LineMarkerProvider> extensionPoint : points) {
GutterIconDescriptor instance = (GutterIconDescriptor)extensionPoint.getInstance();
if (instance.getOptions().length > 0) {
for (GutterIconDescriptor option : instance.getOptions()) {
- if (first.getAndSet(false)) {
- myFirstDescriptors.put(instance, descriptor);
- }
myDescriptors.add(option);
+ pluginDescriptorMap.put(option, descriptor);
}
}
else {
- if (first.getAndSet(false)) {
- myFirstDescriptors.put(instance, descriptor);
- }
myDescriptors.add(instance);
+ pluginDescriptorMap.put(instance, descriptor);
}
}
}
}
}
myDescriptors.addAll(options);
+ myDescriptors.sort(new Comparator<GutterIconDescriptor>() {
+ @Override
+ public int compare(GutterIconDescriptor o1, GutterIconDescriptor o2) {
+ if (pluginDescriptorMap.get(o1) != pluginDescriptorMap.get(o2)) return 0;
+ return Comparing.compare(o1.getName(), o2.getName());
+ }
+ });
+ PluginDescriptor current = null;
+ for (GutterIconDescriptor descriptor : myDescriptors) {
+ PluginDescriptor pluginDescriptor = pluginDescriptorMap.get(descriptor);
+ if (pluginDescriptor != current) {
+ myFirstDescriptors.put(descriptor, pluginDescriptor);
+ current = pluginDescriptor;
+ }
+ }
+
myList.setItems(myDescriptors, new Function<GutterIconDescriptor, String>() {
@Override
public String fun(GutterIconDescriptor descriptor) {
import java.util.Collections;
import java.util.List;
+@SuppressWarnings("MethodOverridesStaticMethodOfSuperclass")
public class TargetElementUtil extends TargetElementUtilBase {
+ /**
+ * A flag used in {@link #findTargetElement(Editor, int, int)} indicating that if a reference is found at the specified offset,
+ * it should be resolved and the result returned.
+ */
public static final int REFERENCED_ELEMENT_ACCEPTED = 0x01;
+
+ /**
+ * A flag used in {@link #findTargetElement(Editor, int, int)} indicating that if a element declaration name (e.g. class name identifier)
+ * is found at the specified offset, the declared element should be returned.
+ */
public static final int ELEMENT_NAME_ACCEPTED = 0x02;
+
+ /**
+ * A flag used in {@link #findTargetElement(Editor, int, int)} indicating that if a lookup (e.g. completion) is shown in the editor,
+ * the PSI element corresponding to the selected lookup item should be returned.
+ */
public static final int LOOKUP_ITEM_ACCEPTED = 0x08;
public static TargetElementUtil getInstance() {
&& EditorUtil.inVirtualSpace(editor, editor.getCaretModel().getLogicalPosition());
}
+ /**
+ * Note: this method can perform slow PSI activity (e.g. {@link PsiReference#resolve()}, so please avoid calling it from Swing thread.
+ * @param editor editor
+ * @param flags a combination of {@link #REFERENCED_ELEMENT_ACCEPTED}, {@link #ELEMENT_NAME_ACCEPTED}, {@link #LOOKUP_ITEM_ACCEPTED}
+ * @return a PSI element declared or referenced at the editor caret position, or selected in the {@link Lookup} if shown in the editor,
+ * depending on the flags passed.
+ * @see #findTargetElement(Editor, int, int)
+ */
@Nullable
public static PsiElement findTargetElement(Editor editor, int flags) {
ApplicationManager.getApplication().assertIsDispatchThread();
return null;
}
+ /**
+ * Note: this method can perform slow PSI activity (e.g. {@link PsiReference#resolve()}, so please avoid calling it from Swing thread.
+ * @param editor editor
+ * @param flags a combination of {@link #REFERENCED_ELEMENT_ACCEPTED}, {@link #ELEMENT_NAME_ACCEPTED}, {@link #LOOKUP_ITEM_ACCEPTED}
+ * @param offset offset in the editor's document f? yt jlby dfh
+ * @return a PSI element declared or referenced at the specified offset in the editor, or selected in the {@link Lookup} if shown in the editor,
+ * depending on the flags passed.
+ * @see #findTargetElement(Editor, int)
+ */
@Override
@Nullable
public PsiElement findTargetElement(@NotNull Editor editor, int flags, int offset) {
private static TextRange getReferenceRange(@NotNull PsiElement elementAtPointer) {
int textOffset = elementAtPointer.getTextOffset();
final TextRange range = elementAtPointer.getTextRange();
+ if (range == null) {
+ throw new AssertionError("Null range for " + elementAtPointer + " of " + elementAtPointer.getClass());
+ }
if (textOffset < range.getStartOffset() || textOffset < 0) {
LOG.error("Invalid text offset " + textOffset + " of element " + elementAtPointer + " of " + elementAtPointer.getClass());
textOffset = range.getStartOffset();
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-import java.util.function.Predicate;
public class MacroCallNode extends Expression {
- private final List<Macro> myMacros;
+ private final Macro myMacro;
private final ArrayList<Expression> myParameters = new ArrayList<>();
public MacroCallNode(@NotNull Macro macro) {
- this(Collections.singletonList(macro));
- }
-
- public MacroCallNode(List<Macro> macros) {
- myMacros = macros;
- assert macros.size() > 0;
+ myMacro = macro;
}
public void addParameter(Expression node) {
myParameters.add(node);
}
- public Macro getMacro(TemplateContextType[] context) {
- Predicate<Macro> isAcceptableInContext = macro -> Arrays.stream(context).anyMatch(macro::isAcceptableInContext);
- return myMacros.stream().filter(isAcceptableInContext).findFirst().orElse(myMacros.get(0));
+ public Macro getMacro() {
+ return myMacro;
}
@Override
public Result calculateResult(ExpressionContext context) {
Expression[] parameters = myParameters.toArray(new Expression[myParameters.size()]);
- return getMacro(context.getCompatibleContexts()).calculateResult(parameters, context);
+ return getMacro().calculateResult(parameters, context);
}
@Override
public Result calculateQuickResult(ExpressionContext context) {
Expression[] parameters = myParameters.toArray(new Expression[myParameters.size()]);
- return getMacro(context.getCompatibleContexts()).calculateQuickResult(parameters, context);
+ return getMacro().calculateQuickResult(parameters, context);
}
@Override
public LookupElement[] calculateLookupItems(ExpressionContext context) {
Expression[] parameters = myParameters.toArray(new Expression[myParameters.size()]);
- return getMacro(context.getCompatibleContexts()).calculateLookupItems(parameters, context);
+ return getMacro().calculateLookupItems(parameters, context);
}
public Expression[] getParameters() {
}
advance(lexer);
- MacroCallNode macroCallNode = new MacroCallNode(macros);
+ MacroCallNode macroCallNode = new MacroCallNode(macros.get(0));
if (lexer.getTokenType() == null) {
return macroCallNode;
}
@Nullable private PairProcessor<String, String> myProcessor;
private boolean mySelectionCalculated = false;
private boolean myStarted;
- private final TemplateContextType[] myCompatibleContexts;
TemplateState(@NotNull Project project, @NotNull final Editor editor) {
myProject = project;
myEditor = editor;
myDocument = myEditor.getDocument();
-
- PsiFile file = getPsiFile();
- if (file != null) {
- myCompatibleContexts = TemplateManagerImpl.getApplicableContextTypes(file, editor.getCaretModel().getOffset()).toArray(new TemplateContextType[0]);
- } else {
- myCompatibleContexts = new TemplateContextType[0];
- }
}
private void initListeners() {
PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument());
return file == null ? null : file.findElementAt(offset);
}
-
- @NotNull
- @Override
- public TemplateContextType[] getCompatibleContexts() {
- return myCompatibleContexts;
- }
};
}
Expression e = myTemplate.getExpressionAt(j);
@NonNls String marker = "a";
if (e instanceof MacroCallNode) {
- marker = ((MacroCallNode)e).getMacro(myCompatibleContexts).getDefaultValue();
+ marker = ((MacroCallNode)e).getMacro().getDefaultValue();
}
replaceString(marker, mySegments.getSegmentStart(i), mySegments.getSegmentEnd(i), i);
indices.add(i);
/*
- * Copyright 2000-2015 JetBrains s.r.o.
+ * Copyright 2000-2016 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.
import com.intellij.openapi.roots.OrderEntry;
import com.intellij.openapi.roots.OrderRootType;
import com.intellij.openapi.roots.ProjectFileIndex;
-import com.intellij.openapi.util.*;
+import com.intellij.openapi.util.Computable;
+import com.intellij.openapi.util.Condition;
+import com.intellij.openapi.util.Conditions;
+import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.*;
pattern = PatternUtil.convertToRegex(filter.trim());
}
else {
- pattern = StringUtil.join(strings, new Function<String, String>() {
- @NotNull
- @Override
- public String fun(@NotNull String s) {
- return "(" + PatternUtil.convertToRegex(s.trim()) + ")";
- }
- }, "|");
+ pattern = StringUtil.join(strings, s -> "(" + PatternUtil.convertToRegex(s.trim()) + ")", "|");
}
return Pattern.compile(pattern, Pattern.CASE_INSENSITIVE);
}
@NotNull final Project project,
@NotNull final Processor<UsageInfo> consumer,
@NotNull FindUsagesProcessPresentation processPresentation) {
- findUsages(findModel, project, consumer, processPresentation, Collections.<VirtualFile>emptySet());
+ findUsages(findModel, project, consumer, processPresentation, Collections.emptySet());
}
public static void findUsages(@NotNull FindModel findModel,
@NotNull final FindModel findModel,
@NotNull final Processor<UsageInfo> consumer) {
if (findModel.getStringToFind().isEmpty()) {
- if (!ApplicationManager.getApplication().runReadAction(new Computable<Boolean>() {
- @Override
- public Boolean compute() {
- return consumer.process(new UsageInfo(psiFile));
- }
- })) {
+ if (!ApplicationManager.getApplication().runReadAction((Computable<Boolean>)() -> consumer.process(new UsageInfo(psiFile)))) {
throw new ProcessCanceledException();
}
return 1;
final VirtualFile virtualFile = psiFile.getVirtualFile();
if (virtualFile == null) return 0;
if (virtualFile.getFileType().isBinary()) return 0; // do not decompile .class files
- final Document document = ApplicationManager.getApplication().runReadAction(new Computable<Document>() {
- @Override
- public Document compute() {
- return virtualFile.isValid() ? FileDocumentManager.getInstance().getDocument(virtualFile) : null;
- }
- });
+ final Document document = ApplicationManager.getApplication().runReadAction(
+ (Computable<Document>)() -> virtualFile.isValid() ? FileDocumentManager.getInstance().getDocument(virtualFile) : null);
if (document == null) return 0;
final int[] offset = {0};
int count = 0;
TooManyUsagesStatus tooManyUsagesStatus = TooManyUsagesStatus.getFrom(indicator);
do {
tooManyUsagesStatus.pauseProcessingIfTooManyUsages(); // wait for user out of read action
- found = ApplicationManager.getApplication().runReadAction(new Computable<Integer>() {
- @Override
- @NotNull
- public Integer compute() {
- if (!psiFile.isValid()) return 0;
- return addToUsages(document, consumer, findModel, psiFile, offset, USAGES_PER_READ_ACTION);
- }
+ found = ApplicationManager.getApplication().runReadAction((Computable<Integer>)() -> {
+ if (!psiFile.isValid()) return 0;
+ return addToUsages(document, consumer, findModel, psiFile, offset, USAGES_PER_READ_ACTION);
});
count += found;
}
processPresentation.setShowNotFoundMessage(true);
processPresentation.setShowPanelIfOnlyOneUsage(showPanelIfOnlyOneUsage);
processPresentation.setProgressIndicatorFactory(
- new Factory<ProgressIndicator>() {
- @NotNull
- @Override
- public ProgressIndicator create() {
- return new FindProgressIndicator(project, presentation.getScopeText());
- }
- }
+ () -> new FindProgressIndicator(project, presentation.getScopeText())
);
return processPresentation;
}
if (grandChildren.length != 1) return Collections.emptyList(); // a | b, more than one branch, can not predict in current way
for(PsiElement grandGrandChild:grandChildren[0].getChildren()) {
- if (result == null) result = new ArrayList<PsiElement>();
+ if (result == null) result = new ArrayList<>();
result.add(grandGrandChild);
}
}
return result != null ? result : Collections.<PsiElement>emptyList();
}
- public static @NotNull String buildStringToFindForIndicesFromRegExp(@NotNull String stringToFind, @NotNull Project project) {
+ @NotNull
+ public static String buildStringToFindForIndicesFromRegExp(@NotNull String stringToFind, @NotNull Project project) {
if (!Registry.is("idea.regexp.search.uses.indices")) return "";
final AccessToken accessToken = ReadAction.start();
}
private static void addSourceDirectoriesFromLibraries(@NotNull Project project,
- @NotNull VirtualFile file,
+ @NotNull VirtualFile directory,
@NotNull Collection<VirtualFile> outSourceRoots) {
ProjectFileIndex index = ProjectFileIndex.SERVICE.getInstance(project);
- // if we already are in the sources, search just in this directory only
- if (index.isInLibrarySource(file)) return;
- VirtualFile classRoot = index.getClassRootForFile(file);
+ VirtualFile classRoot = index.getClassRootForFile(directory);
if (classRoot == null) return;
- String relativePath = VfsUtilCore.getRelativePath(file, classRoot);
+ String relativePath = VfsUtilCore.getRelativePath(directory, classRoot);
if (relativePath == null) return;
- for (OrderEntry orderEntry : index.getOrderEntriesForFile(file)) {
+ for (OrderEntry orderEntry : index.getOrderEntriesForFile(directory)) {
for (VirtualFile sourceRoot : orderEntry.getFiles(OrderRootType.SOURCES)) {
VirtualFile sourceFile = sourceRoot.findFileByRelativePath(relativePath);
if (sourceFile != null) {
private static GlobalSearchScope forDirectory(@NotNull Project project,
boolean withSubdirectories,
@NotNull VirtualFile directory) {
- Set<VirtualFile> result = new LinkedHashSet<VirtualFile>();
+ Set<VirtualFile> result = new LinkedHashSet<>();
result.add(directory);
addSourceDirectoriesFromLibraries(project, directory, result);
VirtualFile[] array = result.toArray(new VirtualFile[result.size()]);
/*
- * Copyright 2000-2015 JetBrains s.r.o.
+ * Copyright 2000-2016 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.
}
psiFile.putUserData(FileContextUtil.INJECTED_IN_ELEMENT, pointer);
- PsiDocumentManagerBase.cachePsi(documentWindow, psiFile);
+ ((PsiDocumentManagerBase)PsiDocumentManager.getInstance(psiFile.getProject())).cachePsi(documentWindow, psiFile);
keepTreeFromChameleoningBack(psiFile);
/*
- * Copyright 2000-2014 JetBrains s.r.o.
+ * Copyright 2000-2016 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.
*/
package com.intellij.internal.focus;
+import com.intellij.execution.filters.TextConsoleBuilderFactory;
+import com.intellij.execution.ui.ConsoleView;
+import com.intellij.execution.ui.ConsoleViewContentType;
import com.intellij.openapi.ide.CopyPasteManager;
import com.intellij.openapi.project.Project;
+import com.intellij.openapi.project.ProjectManager;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.wm.impl.FocusRequestInfo;
import com.intellij.ui.JBColor;
* @author Konstantin Bulenkov
*/
public class FocusTracesDialog extends DialogWrapper {
- private final JTextPane myStacktrace = new JTextPane();
private final JBTable myRequestsTable;
private final List<FocusRequestInfo> myRequests;
private static final String[] COLUMNS = {"Time", "Forced", "Component"};
+ private final ConsoleView consoleView;
public FocusTracesDialog(Project project, ArrayList<FocusRequestInfo> requests) {
super(project);
final ListSelectionListener selectionListener = new ListSelectionListener() {
@Override
public void valueChanged(ListSelectionEvent e) {
+ if (consoleView == null) return;
final int index = myRequestsTable.getSelectedRow();
+ consoleView.clear();
if (-1 < index && index < myRequests.size()) {
- myStacktrace.setText(myRequests.get(index).getStackTrace());
- myStacktrace.setCaretPosition(0);
- }
- else {
- myStacktrace.setText("");
+ consoleView.print(myRequests.get(index).getStackTrace(), ConsoleViewContentType.NORMAL_OUTPUT);
}
}
};
columnModel.getColumn(1).setPreferredWidth(60);
myRequestsTable.getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
myRequestsTable.changeSelection(0, 0, false, true);
+
+ consoleView = TextConsoleBuilderFactory.getInstance().createBuilder(ProjectManager.getInstance().getDefaultProject()).getConsole();
+
init();
}
JPanel panel = new JPanel(new BorderLayout());
JBSplitter splitter = new JBSplitter(true, .5F, .2F, .8F);
splitter.setFirstComponent(new JBScrollPane(myRequestsTable, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER));
+
+ final JComponent consoleComponent = new JPanel(new BorderLayout());
+ consoleComponent.add(consoleView.getComponent(), BorderLayout.CENTER);
+ consoleView.print(myRequests.get(myRequestsTable.getSelectedRow()).getStackTrace(), ConsoleViewContentType.NORMAL_OUTPUT);
+
splitter.setSecondComponent(
- new JBScrollPane(myStacktrace, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER));
+ new JBScrollPane(consoleComponent, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER));
panel.add(splitter, BorderLayout.CENTER);
return panel;
}
return new AbstractAction("&Copy stacktrace") {
@Override
public void actionPerformed(ActionEvent e) {
- CopyPasteManager.getInstance().setContents(new StringSelection(myStacktrace.getText()));
+ CopyPasteManager.getInstance().setContents(new StringSelection(myRequests.get(myRequestsTable.getSelectedRow()).getStackTrace()));
}
};
}
private final JEditorPane myText;
private final BalloonLayoutData myLayoutData;
private Component myTitleComponent;
- private Component myCenteredComponent;
+ private JScrollPane myCenteredComponent;
private JPanel myActionPanel;
private Component myExpandAction;
if (myTitleComponent != null) {
return myTitleComponent;
}
- if (myCenteredComponent instanceof JScrollPane) {
- return ((JScrollPane)myCenteredComponent).getViewport().getView();
+ if (myCenteredComponent != null) {
+ return myCenteredComponent.getViewport().getView();
}
return null;
}
myTitleComponent = comp;
}
else if (BorderLayout.CENTER.equals(constraints)) {
- myCenteredComponent = comp;
+ myCenteredComponent = (JScrollPane)comp;
}
else if (BorderLayout.SOUTH.equals(constraints)) {
myActionPanel = (JPanel)comp;
if (myCenteredComponent != null) {
myCenteredComponent.setBounds(0, top, width, centeredSize.height);
+ myCenteredComponent.revalidate();
}
if (myExpandAction != null) {
int x = width - size.width - myLayoutData.configuration.rightActionsOffset.width;
if (myLayoutData.showMinSize) {
- if (myText.getWidth() < 0 || myText.getHeight() < 0) {
- myCenteredComponent.doLayout();
- ((JScrollPane)myCenteredComponent).getViewport().doLayout();
- }
Point location = getCollapsedTextEndLocation(myText, myLayoutData);
if (location != null) {
int y = SwingUtilities.convertPoint(myText, location.x, location.y, parent).y;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.ex.EditorEx;
import com.intellij.openapi.editor.ex.EditorGutterComponentEx;
-import com.intellij.openapi.editor.markup.LineMarkerRenderer;
+import com.intellij.openapi.editor.markup.LineMarkerRendererEx;
import org.jetbrains.annotations.NotNull;
import java.awt.*;
* <p>Draws the diff change highlighters on the editor's gutter.</p>
* <p>Has ability to draw applied changes (used in the merge tool).</p>
*/
-public class DiffLineMarkerRenderer implements LineMarkerRenderer {
+public class DiffLineMarkerRenderer implements LineMarkerRendererEx {
@NotNull private final TextDiffType myDiffType;
}
}
+ @Override
+ public LineMarkerRendererEx.Position getPosition() {
+ return LineMarkerRendererEx.Position.CUSTOM;
+ }
}
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.ex.EditorEx;
import com.intellij.openapi.editor.impl.EditorImpl;
-import com.intellij.openapi.editor.markup.LineMarkerRenderer;
+import com.intellij.openapi.editor.markup.LineMarkerRendererEx;
import com.intellij.openapi.editor.markup.LineSeparatorRenderer;
import com.intellij.openapi.util.Couple;
import com.intellij.util.Consumer;
-import com.intellij.util.containers.Convertor;
import com.intellij.util.ui.UIUtil;
import java.awt.*;
* Date: 7/6/11
* Time: 7:44 PM
*/
-public class FragmentBoundRenderer implements LineMarkerRenderer, LineSeparatorRenderer {
+public class FragmentBoundRenderer implements LineMarkerRendererEx, LineSeparatorRenderer {
private final int myLineHeight;
private final Editor myEditor;
private final Consumer<Integer> myOffsetsConsumer;
((Graphics2D) gr).setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
gr.setColor(getColor());
- int y = r.y;
final int width = ((EditorEx)editor).getGutterComponentEx().getWidth();
final int editorWidth = editor.getScrollingModel().getVisibleArea().width;
myShoeneLine.ensureLastX(editorWidth + width + width);
}
}
+ @Override
+ public Position getPosition() {
+ return Position.CUSTOM;
+ }
+
public Color getColor() {
return myMainColor;
}
public abstract void setPaintBackground(boolean value);
- public abstract void setShowRightFreePaintersArea(boolean value);
+ public abstract void setForceShowLeftFreePaintersArea(boolean value);
+
+ public abstract void setForceShowRightFreePaintersArea(boolean value);
}
@NonNls
public static void throwNotReleasedError(@NotNull Editor editor) {
if (editor instanceof EditorImpl) {
- ((EditorImpl)editor).throwDisposalError("Editor of " + editor.getClass() + " hasn't been released:");
+ ((EditorImpl)editor).throwEditorNotDisposedError("Editor of " + editor.getClass() + " hasn't been released:");
}
else {
throw new RuntimeException("Editor of " + editor.getClass() +
/*
- * Copyright 2000-2015 JetBrains s.r.o.
+ * Copyright 2000-2016 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.
}
@Override
- public void fireAttributesChanged(@NotNull RangeHighlighterEx segmentHighlighter, boolean renderersChanged) {
- myDelegate.fireAttributesChanged(segmentHighlighter, renderersChanged);
+ public void fireAttributesChanged(@NotNull RangeHighlighterEx segmentHighlighter, boolean renderersChanged, boolean fontStyleChanged) {
+ myDelegate.fireAttributesChanged(segmentHighlighter, renderersChanged, fontStyleChanged);
}
@Override
import com.intellij.ui.HintHint;
import com.intellij.ui.JBColor;
import com.intellij.ui.awt.RelativePoint;
-import com.intellij.util.Function;
-import com.intellij.util.IconUtil;
-import com.intellij.util.NullableFunction;
-import com.intellij.util.SmartList;
+import com.intellij.util.*;
import com.intellij.util.containers.HashMap;
import com.intellij.util.ui.JBUI;
import com.intellij.util.ui.UIUtil;
private TIntObjectHashMap<Color> myTextFgColors = new TIntObjectHashMap<Color>();
private boolean myPaintBackground = true;
private boolean myLeftFreePaintersAreaShown;
- private boolean myRightFreePaintersAreaShown = true;
+ private boolean myRightFreePaintersAreaShown;
+ private boolean myForceLeftFreePaintersAreaShown = false;
+ private boolean myForceRightFreePaintersAreaShown = false;
private int myLastNonDumbModeIconAreaWidth = 0;
@SuppressWarnings("unchecked")
int startX = myEditor.isInDistractionFreeMode() ? 0 : getWhitespaceSeparatorOffset() + (isFoldingOutlineShown() ? 1 : 0);
if (myEditor.myUseNewRendering) {
com.intellij.openapi.editor.impl.view.IterationState state =
- new com.intellij.openapi.editor.impl.view.IterationState(myEditor, firstVisibleOffset, lastVisibleOffset, false, true, true, false);
+ new com.intellij.openapi.editor.impl.view.IterationState(myEditor, firstVisibleOffset, lastVisibleOffset,
+ false, true, false, true, false);
while (!state.atEnd()) {
drawEditorBackgroundForRange(g, state.getStartOffset(), state.getEndOffset(), state.getMergedAttributes(),
defaultBackgroundColor, defaultForegroundColor, startX);
private void calcLineMarkerAreaWidth() {
myLineToGutterRenderers = new TIntObjectHashMap<List<GutterMark>>();
- myLeftFreePaintersAreaShown = false;
+ myLeftFreePaintersAreaShown = myForceLeftFreePaintersAreaShown;
+ myRightFreePaintersAreaShown = myForceRightFreePaintersAreaShown;
processRangeHighlighters(0, myEditor.getDocument().getTextLength(), new RangeHighlighterProcessor() {
@Override
public void process(@NotNull RangeHighlighter highlighter) {
LineMarkerRenderer lineMarkerRenderer = highlighter.getLineMarkerRenderer();
- if (lineMarkerRenderer instanceof LineMarkerRendererEx &&
- ((LineMarkerRendererEx)lineMarkerRenderer).getPosition() == LineMarkerRendererEx.Position.LEFT &&
- isLineMarkerVisible(highlighter)) {
- myLeftFreePaintersAreaShown = true;
+ if (lineMarkerRenderer != null) {
+ LineMarkerRendererEx.Position position = getLineMarkerPosition(lineMarkerRenderer);
+ if (position == LineMarkerRendererEx.Position.LEFT && isLineMarkerVisible(highlighter)) myLeftFreePaintersAreaShown = true;
+ if (position == LineMarkerRendererEx.Position.RIGHT && isLineMarkerVisible(highlighter)) myRightFreePaintersAreaShown = true;
}
-
+
GutterMark renderer = highlighter.getGutterIconRenderer();
if (renderer == null) {
return;
endY += myEditor.getLineHeight();
}
- LineMarkerRenderer renderer = highlighter.getLineMarkerRenderer();
- boolean leftPosition = renderer instanceof LineMarkerRendererEx &&
- ((LineMarkerRendererEx)renderer).getPosition() == LineMarkerRendererEx.Position.LEFT;
+ LineMarkerRenderer renderer = ObjectUtils.assertNotNull(highlighter.getLineMarkerRenderer());
+ LineMarkerRendererEx.Position position = getLineMarkerPosition(renderer);
+
+ int w;
+ int x;
+ switch (position) {
+ case LEFT:
+ w = getLeftFreePaintersAreaWidth();
+ x = getLeftFreePaintersAreaOffset();
+ break;
+ case RIGHT:
+ w = getRightFreePaintersAreaWidth();
+ x = getLineMarkerFreePaintersAreaOffset() - 1;
+ break;
+ case CUSTOM:
+ w = getWidth();
+ x = 0;
+ break;
+ default:
+ throw new IllegalArgumentException(position.name());
+ }
int height = endY - startY;
- int w = leftPosition ? getLeftFreePaintersAreaWidth() : getRightFreePaintersAreaWidth();
- int x = leftPosition ? getLeftFreePaintersAreaOffset() : getLineMarkerFreePaintersAreaOffset() - 1;
return new Rectangle(x, startY, w, height);
}
}
@Override
- public void setShowRightFreePaintersArea(boolean value) {
- myRightFreePaintersAreaShown = value;
+ public void setForceShowLeftFreePaintersArea(boolean value) {
+ myForceLeftFreePaintersAreaShown = value;
+ }
+
+ @Override
+ public void setForceShowRightFreePaintersArea(boolean value) {
+ myForceRightFreePaintersAreaShown = value;
}
private void invokePopup(MouseEvent e) {
return (GutterIconRenderer)getGutterRenderer(e.getPoint());
}
+ @NotNull
+ private static LineMarkerRendererEx.Position getLineMarkerPosition(@NotNull LineMarkerRenderer renderer) {
+ if (renderer instanceof LineMarkerRendererEx) {
+ return ((LineMarkerRendererEx)renderer).getPosition();
+ }
+ return LineMarkerRendererEx.Position.RIGHT;
+ }
+
public int convertX(int x) {
if (!isMirrored()) return x;
return getWidth() - x;
}
@Override
public void afterAdded(@NotNull RangeHighlighterEx highlighter) {
- attributesChanged(highlighter, areRenderersInvolved(highlighter));
+ attributesChanged(highlighter, areRenderersInvolved(highlighter), false);
}
@Override
public void beforeRemoved(@NotNull RangeHighlighterEx highlighter) {
- attributesChanged(highlighter, areRenderersInvolved(highlighter));
+ attributesChanged(highlighter, areRenderersInvolved(highlighter), false);
}
@Override
- public void attributesChanged(@NotNull RangeHighlighterEx highlighter, boolean renderersChanged) {
+ public void attributesChanged(@NotNull RangeHighlighterEx highlighter, boolean renderersChanged, boolean fontStyleChanged) {
if (myDocument.isInBulkUpdate()) return; // bulkUpdateFinished() will repaint anything
if (myUseNewRendering && renderersChanged) {
int startLine = start == -1 ? 0 : myDocument.getLineNumber(start);
int endLine = end == -1 ? myDocument.getLineCount() : myDocument.getLineNumber(end);
TextAttributes attributes = highlighter.getTextAttributes();
- if (myUseNewRendering && start != end && attributes != null && attributes.getFontType() != Font.PLAIN) {
+ if (myUseNewRendering && start != end && (fontStyleChanged || attributes != null && attributes.getFontType() != Font.PLAIN)) {
myView.invalidateRange(start, end);
}
repaintLines(Math.max(0, startLine - 1), Math.min(endLine + 1, getDocument().getLineCount()));
);
}
+ /**
+ * To be called when editor was not disposed while it should
+ */
+ public void throwEditorNotDisposedError(@NonNls @NotNull final String msg) {
+ myTraceableDisposable.throwObjectNotDisposedError(msg);
+ }
+
+ /**
+ * In case of "editor not disposed error" use {@link #throwEditorNotDisposedError(String)}
+ */
public void throwDisposalError(@NonNls @NotNull String msg) {
myTraceableDisposable.throwDisposalError(msg);
}
private long mySleepTime = 500;
private boolean myIsBlinkCaret = true;
@Nullable private EditorImpl myEditor;
- @NotNull private final MyRepaintRunnable myRepaintRunnable;
+ @NotNull private final MyRepaintRunnable myRepaintRunnable = new MyRepaintRunnable();
private ScheduledFuture<?> mySchedulerHandle;
- private RepaintCursorCommand() {
- myRepaintRunnable = new MyRepaintRunnable();
- }
-
private class MyRepaintRunnable implements Runnable {
@Override
public void run() {
for (RangeHighlighter highlighter : myDocumentMarkupModel.getDelegate().getAllHighlighters()) {
boolean oldAvailable = oldFilter == null || oldFilter.value(highlighter);
boolean newAvailable = filter == null || filter.value(highlighter);
- if (oldAvailable != newAvailable) myMarkupModelListener.attributesChanged((RangeHighlighterEx)highlighter, true);
+ if (oldAvailable != newAvailable) myMarkupModelListener.attributesChanged((RangeHighlighterEx)highlighter, true, false);
}
}
SoftWrap softWrap = myEditor.getSoftWrapModel().getSoftWrap(offset);
if (softWrap != null) {
prevEndOffset = offset;
- it = new IterationState(myEditor, offset == 0 ? 0 : offset - 1, visualLineEndOffset, true, false, false, false);
+ it = new IterationState(myEditor, offset == 0 ? 0 : offset - 1, visualLineEndOffset, true, false, false, false, false);
if (it.getEndOffset() <= offset) {
it.advance();
}
FoldRegion foldRegion = fragment.getCurrentFoldRegion();
if (foldRegion == null) {
if (start != prevEndOffset) {
- it = new IterationState(myEditor, start, fragment.isRtl() ? offset : visualLineEndOffset, true, false, false, fragment.isRtl());
+ it = new IterationState(myEditor, start, fragment.isRtl() ? offset : visualLineEndOffset,
+ true, false, false, false, fragment.isRtl());
}
prevEndOffset = end;
assert it != null;
else {
float xNew = fragment.getEndX();
if (xNew >= clip.getMinX()) {
- painter.paint(g, fragment, 0, fragment.getEndVisualColumn() - fragment.getStartVisualColumn(), getFoldRegionAttributes(foldRegion),
- x, xNew, y);
+ painter.paint(g, fragment, 0, fragment.getEndVisualColumn() - fragment.getStartVisualColumn(),
+ getFoldRegionAttributes(foldRegion), x, xNew, y);
}
x = xNew;
prevEndOffset = -1;
}
if (it == null || it.getEndOffset() != visualLineEndOffset) {
it = new IterationState(myEditor, visualLineEndOffset == offset ? visualLineEndOffset : visualLineEndOffset - 1, visualLineEndOffset,
- true, false, false, false);
+ true, false, false, false, false);
}
if (!it.atEnd()) {
it.advance();
/*
- * Copyright 2000-2015 JetBrains s.r.o.
+ * Copyright 2000-2016 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.
private final boolean myReverseIteration;
public IterationState(@NotNull EditorEx editor, int start, int end, boolean useCaretAndSelection, boolean useOnlyFullLineHighlighters,
- boolean useFoldRegions, boolean iterateBackwards) {
+ boolean useOnlyFontAffectingHighlighters, boolean useFoldRegions, boolean iterateBackwards) {
ApplicationManager.getApplication().assertReadAccessAllowed();
myDocument = editor.getDocument();
myStartOffset = start;
myCaretRowEndsWithSoftWrap = editor.getSoftWrapModel().getSoftWrap(myCaretRowEnd) != null;
MarkupModelEx editorMarkup = editor.getMarkupModel();
- myView = new HighlighterSweep(editorMarkup, start, myEnd, useOnlyFullLineHighlighters);
+ myView = new HighlighterSweep(editorMarkup, start, myEnd, useOnlyFullLineHighlighters, useOnlyFontAffectingHighlighters);
MarkupModelEx docMarkup = editor.getFilteredDocumentMarkupModel();
- myDoc = new HighlighterSweep(docMarkup, start, myEnd, useOnlyFullLineHighlighters);
+ myDoc = new HighlighterSweep(docMarkup, start, myEnd, useOnlyFullLineHighlighters, useOnlyFontAffectingHighlighters);
myEndOffset = myStartOffset;
int i;
private final RangeHighlighterEx[] highlighters;
- private HighlighterSweep(@NotNull MarkupModelEx markupModel, int start, int end, final boolean onlyFullLine) {
+ private HighlighterSweep(@NotNull MarkupModelEx markupModel, int start, int end,
+ final boolean onlyFullLine, final boolean onlyFontAffecting) {
// we have to get all highlighters in advance and sort them by affected offsets
// since these can be different from the real offsets the highlighters are sorted by in the tree. (See LINES_IN_RANGE perverts)
final List<RangeHighlighterEx> list = new ArrayList<RangeHighlighterEx>();
- markupModel.processRangeHighlightersOverlappingWith(myReverseIteration ? end : start,
- myReverseIteration ? start : end,
+ markupModel.processRangeHighlightersOverlappingWith(myReverseIteration ? end : start, myReverseIteration ? start : end,
new CommonProcessors.CollectProcessor<RangeHighlighterEx>(list) {
@Override
protected boolean accept(RangeHighlighterEx ex) {
- return !onlyFullLine || ex.getTargetArea() == HighlighterTargetArea.LINES_IN_RANGE;
+ return (!onlyFullLine ||
+ ex.getTargetArea() == HighlighterTargetArea.LINES_IN_RANGE) &&
+ (!onlyFontAffecting ||
+ ex.getTextAttributes() != null &&
+ ex.getTextAttributes().getFontType() != Font.PLAIN);
}
});
highlighters = list.isEmpty() ? RangeHighlighterEx.EMPTY_ARRAY : list.toArray(new RangeHighlighterEx[list.size()]);
int lineStartOffset = view.getEditor().getDocument().getLineStartOffset(line);
int start = lineStartOffset + startOffset;
int end = lineStartOffset + endOffset;
- IterationState it = new IterationState(view.getEditor(), start, end, false, false, false, false);
+ IterationState it = new IterationState(view.getEditor(), start, end, false, false, true, false, false);
FontPreferences fontPreferences = view.getEditor().getColorsScheme().getFontPreferences();
char[] chars = CharArrayUtil.fromSequence(view.getEditor().getDocument().getImmutableCharSequence(), start, end);
while (!it.atEnd()) {
package com.intellij.openapi.editor.markup;
import com.intellij.openapi.editor.Editor;
+import org.jetbrains.annotations.NotNull;
import java.awt.*;
public interface LineMarkerRendererEx extends LineMarkerRenderer {
- enum Position {LEFT, RIGHT}
+ enum Position {LEFT, RIGHT, CUSTOM}
/**
- * Determines whether line marker should be rendered to the left or to the right of icon area in gutter.
+ * Determines where in gutter the line marker should be rendered.
+ *
+ * LEFT - to the left of icon area
+ * RIGHT - to the right of icon area
+ * CUSTOM - over whole gutter area
+ * If renderer does not implement LineMarkerRendererEx the RIGHT position will be used.
+ *
* Corresponding rectangle will be passed to renderer in {@link #paint(Editor, Graphics, Rectangle)} method.
*/
+ @NotNull
Position getPosition();
}
private Editor createEditor(){
Editor editor = EditorFactory.getInstance().createEditor(myDocument, myProject);
((EditorMarkupModel) editor.getMarkupModel()).setErrorStripeVisible(true);
+ ((EditorEx) editor).getGutterComponentEx().setForceShowRightFreePaintersArea(true);
+
EditorHighlighter highlighter = EditorHighlighterFactory.getInstance().createEditorHighlighter(myFile, EditorColorsManager.getInstance().getGlobalScheme(), myProject);
((EditorEx) editor).setHighlighter(highlighter);
((EditorEx) editor).setFile(myFile);
final WindowAdapter focusListener = new WindowAdapter() {
public void windowOpened(WindowEvent e) {
IdeFocusManager fm = IdeFocusManager.getInstance(myProject);
- JComponent toFocus = myPreferedFocus;
+ JComponent toFocus = getPreferredFocusedComponent();
if (toFocus == null) {
toFocus = fm.getFocusTargetFor(myComponent);
}
myPreferedFocus = preferedFocus;
}
+ public JComponent getPreferredFocusedComponent() {
+ return myPreferedFocus;
+ }
+
public void closeOnEsc() {
myCloseOnEsc = true;
}
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.WindowWrapper.Mode;
+import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.text.StringUtil;
+import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@Nullable private Project myProject;
@Nullable private Component myParent;
@Nullable private String myTitle;
- @Nullable private JComponent myPreferredFocusedComponent;
+ @Nullable private Computable<JComponent> myPreferredFocusedComponent;
@Nullable private String myDimensionServiceKey;
@Nullable private Runnable myOnShowCallback;
@NotNull
public WindowWrapperBuilder setPreferredFocusedComponent(@Nullable JComponent preferredFocusedComponent) {
- myPreferredFocusedComponent = preferredFocusedComponent;
+ myPreferredFocusedComponent = new Computable.PredefinedValueComputable<JComponent>(preferredFocusedComponent);
+ return this;
+ }
+
+ @NotNull
+ public WindowWrapperBuilder setPreferredFocusedComponent(@Nullable Computable<JComponent> computable) {
+ myPreferredFocusedComponent = computable;
return this;
}
}
}
+ private static void installOnShowCallback(@Nullable Window window, @Nullable final Runnable onShowCallback) {
+ if (window == null || onShowCallback == null) return;
+ window.addWindowListener(new WindowAdapter() {
+ @Override
+ public void windowOpened(WindowEvent e) {
+ onShowCallback.run();
+ }
+ });
+ }
+
private static class DialogWindowWrapper implements WindowWrapper {
@Nullable private final Project myProject;
@NotNull private final JComponent myComponent;
: new MyDialogWrapper(builder.myProject, builder.myComponent);
myDialog.setParameters(builder.myDimensionServiceKey, builder.myPreferredFocusedComponent);
- final Runnable onShowCallback = builder.myOnShowCallback;
- if (onShowCallback != null) {
- myDialog.getWindow().addWindowListener(new WindowAdapter() {
- @Override
- public void windowOpened(WindowEvent e) {
- onShowCallback.run();
- }
- });
- }
+ installOnShowCallback(myDialog.getWindow(), builder.myOnShowCallback);
setTitle(builder.myTitle);
switch (builder.myMode) {
private static class MyDialogWrapper extends DialogWrapper {
@NotNull private JComponent myComponent;
@Nullable private String myDimensionServiceKey;
- @Nullable private JComponent myPreferredFocusedComponent;
+ @Nullable private Computable<JComponent> myPreferredFocusedComponent;
public MyDialogWrapper(@Nullable Project project, @NotNull JComponent component) {
super(project, true);
}
public void setParameters(@Nullable String dimensionServiceKey,
- @Nullable JComponent preferredFocusedComponent) {
+ @Nullable Computable<JComponent> preferredFocusedComponent) {
myDimensionServiceKey = dimensionServiceKey;
myPreferredFocusedComponent = preferredFocusedComponent;
}
@Nullable
@Override
public JComponent getPreferredFocusedComponent() {
- return myPreferredFocusedComponent;
+ if (myPreferredFocusedComponent != null) return myPreferredFocusedComponent.compute();
+ return super.getPreferredFocusedComponent();
}
}
}
@NotNull private final Mode myMode;
@Nullable private final Runnable myOnShowCallback;
- @NotNull private final FrameWrapper myFrame;
+ @NotNull private final MyFrameWrapper myFrame;
public FrameWindowWrapper(@NotNull WindowWrapperBuilder builder) {
assert builder.myMode == Mode.FRAME;
myProject = builder.myProject;
myComponent = builder.myComponent;
myMode = builder.myMode;
- myOnShowCallback = builder.myOnShowCallback;
- myFrame = new FrameWrapper(builder.myProject, builder.myDimensionServiceKey);
+ myFrame = new MyFrameWrapper(builder.myProject, builder.myDimensionServiceKey);
+ myFrame.setParameters(builder.myPreferredFocusedComponent);
+
+ myOnShowCallback = builder.myOnShowCallback;
myFrame.setComponent(builder.myComponent);
- myFrame.setPreferredFocusedComponent(builder.myPreferredFocusedComponent);
myFrame.setTitle(builder.myTitle);
myFrame.closeOnEsc();
Disposer.register(myFrame, this);
public void dispose() {
Disposer.dispose(myFrame);
}
+
+ private static class MyFrameWrapper extends FrameWrapper {
+ private Computable<JComponent> myPreferredFocusedComponent;
+
+ public MyFrameWrapper(Project project, @Nullable @NonNls String dimensionServiceKey) {
+ super(project, dimensionServiceKey);
+ }
+
+ public void setParameters(@Nullable Computable<JComponent> preferredFocusedComponent) {
+ myPreferredFocusedComponent = preferredFocusedComponent;
+ }
+
+ @Override
+ public JComponent getPreferredFocusedComponent() {
+ if (myPreferredFocusedComponent != null) return myPreferredFocusedComponent.compute();
+ return super.getPreferredFocusedComponent();
+ }
+ }
}
}
import javax.swing.*;
import javax.swing.border.Border;
-import javax.swing.border.EmptyBorder;
import java.awt.*;
import java.awt.event.*;
import java.util.Map;
innerPanel.add(toolWindowComponent, BorderLayout.CENTER);
final NonOpaquePanel inner = new NonOpaquePanel(innerPanel);
- inner.setBorder(new EmptyBorder(-1, 0, 0, 0));
contentPane.add(inner, BorderLayout.CENTER);
add(contentPane, BorderLayout.CENTER);
Dart
IdeaVIM
IDETalk
-Commander
+com.intellij.commander
SourceSafe
TFS
ro.redeul.google.go
-LiveEdit
\ No newline at end of file
+com.intellij.plugins.html.instantEditing
\ No newline at end of file
}
}
- public void testStressPlainTextFileWithEverIncreasingLength() throws IOException, InterruptedException {
+ public void _testStressPlainTextFileWithEverIncreasingLength() throws IOException, InterruptedException {
FrequentEventDetector.disableUntil(myTestRootDisposable);
String stillText = StringUtil.repeatSymbol(' ', (int)PersistentFSConstants.FILE_LENGTH_TO_CACHE_THRESHOLD);
if (exception.get() != null) throw new RuntimeException(exception.get());
}
- public void testStressPlainTextFileWithEverIncreasingLength2() throws IOException, InterruptedException {
+ public void _testStressPlainTextFileWithEverIncreasingLength2() throws IOException, InterruptedException {
FrequentEventDetector.disableUntil(myTestRootDisposable);
File f = createTempFile("xx.asdkjfhlkasjdhf", StringUtil.repeatSymbol(' ', (int)PersistentFSConstants.FILE_LENGTH_TO_CACHE_THRESHOLD - 100));
@Override
public void loadState(TestModulePropertiesState state) {
-
+ setProductionModuleName(state.moduleName);
}
public static class TestModulePropertiesState {
import com.intellij.ide.util.treeView.AbstractTreeNode;
import com.intellij.openapi.project.Project;
import com.intellij.remoteServer.configuration.RemoteServer;
+import com.intellij.remoteServer.impl.runtime.ui.tree.ServersTreeNodeSelector;
import com.intellij.remoteServer.impl.runtime.ui.tree.ServersTreeStructure;
import com.intellij.remoteServer.runtime.ServerConnection;
import org.jetbrains.annotations.NotNull;
return !getRemoteServers().isEmpty();
}
- public ServersTreeStructure createTreeStructure(@NotNull final Project project) {
- return new ServersTreeStructure(project, this);
+ public ServersTreeStructure createTreeStructure(@NotNull Project project, @NotNull ServersTreeNodeSelector nodeSelector) {
+ return new ServersTreeStructure(project, this, nodeSelector);
}
public TreeNodeSelector createLogNodeSelector(final ServerConnection<?> connection,
import com.intellij.openapi.ui.Splitter;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Disposer;
+import com.intellij.remoteServer.impl.runtime.ui.tree.ServersTreeNodeSelector;
import com.intellij.remoteServer.impl.runtime.ui.tree.ServersTreeStructure;
import com.intellij.remoteServer.impl.runtime.ui.tree.TreeBuilderBase;
import com.intellij.remoteServer.runtime.ConnectionStatus;
/**
* @author michael.golubev
*/
-public class ServersToolWindowContent extends JPanel implements Disposable {
+public class ServersToolWindowContent extends JPanel implements Disposable, ServersTreeNodeSelector {
public static final DataKey<ServersToolWindowContent> KEY = DataKey.create("serversToolWindowContent");
@NonNls private static final String PLACE_TOOLBAR = "ServersToolWindowContent#Toolbar";
@NonNls private static final String SERVERS_TOOL_WINDOW_TOOLBAR = "RemoteServersViewToolbar";
}
private void setupBuilder(final @NotNull Project project) {
- ServersTreeStructure structure = myContribution.createTreeStructure(project);
+ ServersTreeStructure structure = myContribution.createTreeStructure(project, this);
myBuilder = new TreeBuilderBase(myTree, structure, myTreeModel) {
@Override
protected boolean isAutoExpandNode(NodeDescriptor nodeDescriptor) {
--- /dev/null
+/*
+ * Copyright 2000-2016 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.remoteServer.impl.runtime.ui.tree;
+
+import com.intellij.remoteServer.runtime.ServerConnection;
+import org.jetbrains.annotations.NotNull;
+
+public interface ServersTreeNodeSelector {
+
+ void select(@NotNull ServerConnection<?> connection);
+
+ void select(@NotNull ServerConnection<?> connection, @NotNull String deploymentName);
+
+ void select(@NotNull ServerConnection<?> connection, @NotNull String deploymentName, @NotNull String logName);
+}
private final ServersTreeRootNode myRootElement;
private final Project myProject;
private final RemoteServersViewContribution myContribution;
+ private final ServersTreeNodeSelector myNodeSelector;
private final Map<RemoteServer, Map<String, DeploymentGroup>> myServer2DeploymentGroups
= new HashMap<RemoteServer, Map<String, DeploymentGroup>>();
- public ServersTreeStructure(@NotNull Project project, @NotNull RemoteServersViewContribution contribution) {
+ public ServersTreeStructure(@NotNull Project project,
+ @NotNull RemoteServersViewContribution contribution,
+ @NotNull ServersTreeNodeSelector nodeSelector) {
super(project);
myProject = project;
myContribution = contribution;
+ myNodeSelector = nodeSelector;
myRootElement = new ServersTreeRootNode();
}
return myRootElement;
}
+ protected ServersTreeNodeSelector getNodeSelector() {
+ return myNodeSelector;
+ }
+
@Override
public void commit() {
}
package com.intellij.openapi.util;
import com.intellij.openapi.util.objectTree.ThrowableInterner;
+import com.intellij.openapi.util.text.StringUtil;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.io.StringWriter;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
/**
* Traces creation and disposal by storing corresponding stacktraces.
}
}
+ /**
+ * Call when object is not disposed while it should
+ */
+ public void throwObjectNotDisposedError(@NonNls @NotNull final String msg) {
+ throw new ObjectNotDisposedException(msg);
+ }
+
+ private class ObjectNotDisposedException extends AbstractDisposalException {
+
+ ObjectNotDisposedException(@Nullable @NonNls final String msg) {
+ super(msg);
+ }
+
+
+ @SuppressWarnings("HardCodedStringLiteral")
+ @Override
+ public void printStackTrace(PrintWriter s) {
+ final List<StackTraceElement> stack = new ArrayList<StackTraceElement>(Arrays.asList(CREATE_TRACE.getStackTrace()));
+ stack.remove(0); // this line is useless it stack
+ s.write(ObjectNotDisposedException.class.getCanonicalName() + ": See stack trace responsible for creation of unreleased object below \n\tat " + StringUtil.join(stack, "\n\tat "));
+ }
+ }
+
+ /**
+ * in case of "object not disposed" use {@link #throwObjectNotDisposedError(String)} instead
+ */
public void throwDisposalError(@NonNls String msg) throws RuntimeException {
throw new DisposalException(msg);
}
- private class DisposalException extends RuntimeException {
- private DisposalException(String message) {
+ private abstract class AbstractDisposalException extends RuntimeException {
+ protected AbstractDisposalException(String message) {
super(message);
}
printStackTrace(writer);
writer.flush();
}
+ }
+
+ private class DisposalException extends AbstractDisposalException {
+ private DisposalException(String message) {
+ super(message);
+ }
@SuppressWarnings("HardCodedStringLiteral")
@Override
package com.intellij.ui;
-import com.intellij.openapi.util.SystemInfo;
-import com.intellij.util.ui.JBUI;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NotNull;
public void addSettingsComponent(Component component) {
if (mySettingComponent == null) {
- mySettingComponent = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, 0));
- mySettingComponent.setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);
- add(mySettingComponent, BorderLayout.WEST);
+ mySettingComponent = new JPanel();
mySettingComponent.setOpaque(false);
- if (!SystemInfo.isMacOSLion || UIUtil.isUnderDarcula()) {
- mySettingComponent.setBorder(JBUI.Borders.emptyBottom(4));
- }
+ mySettingComponent.setLayout(new BoxLayout(mySettingComponent, BoxLayout.X_AXIS));
+ add(mySettingComponent, BorderLayout.WEST);
}
mySettingComponent.add(component);
}
*/
package com.intellij.openapi.vcs.changes;
+import com.intellij.diagnostic.ThreadDumper;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.project.Project;
+import com.intellij.util.concurrency.Semaphore;
+import org.jetbrains.annotations.TestOnly;
/**
* for non-AWT threads, synchronously waits for completion of ChanegListManager update
*/
+@TestOnly
public class EnsureUpToDateFromNonAWTThread {
private final Project myProject;
private volatile boolean myDone;
public EnsureUpToDateFromNonAWTThread(final Project project) {
- //assert ApplicationManager.getApplication().isUnitTestMode();
- assert ! ApplicationManager.getApplication().isDispatchThread();
myProject = project;
- myDone = false;
}
public void execute() {
- assert ! ApplicationManager.getApplication().isDispatchThread();
- final Object lock = new Object();
-
- synchronized (lock) {
- ChangeListManager.getInstance(myProject).invokeAfterUpdate(new Runnable() {
- public void run() {
- synchronized (lock) {
- myDone = true;
- lock.notifyAll();
- }
- }
- }, InvokeAfterUpdateMode.SILENT, null, null);
-
- while ((! myDone) && (! myProject.isDisposed())) {
- try {
- lock.wait();
- }
- catch (InterruptedException e) {
- //
- }
+ assert !ApplicationManager.getApplication().isDispatchThread();
+ final Semaphore lock = new Semaphore();
+
+ lock.down();
+
+ ChangeListManager.getInstance(myProject).invokeAfterUpdate(new Runnable() {
+ public void run() {
+ myDone = true;
+ lock.up();
}
+ }, InvokeAfterUpdateMode.SILENT, null, null);
+
+ if (myProject.isDisposed()) return;
+
+ if (!lock.waitFor(100 * 1000) && !myProject.isDisposed()) {
+ //noinspection UseOfSystemOutOrSystemErr
+ System.out.println(ThreadDumper.dumpThreadsToString());
+ throw new AssertionError("Couldn't wait for changes update");
}
}
}, "<br/>"));
}
- VcsConfirmationDialog dialog = new VcsConfirmationDialog(myProject, new VcsShowConfirmationOption() {
+ VcsConfirmationDialog dialog = new VcsConfirmationDialog(myProject, "Remove Empty Changelist", "Remove", "Cancel", new VcsShowConfirmationOption() {
@Override
public Value getValue() {
return config.REMOVE_EMPTY_INACTIVE_CHANGELISTS;
/*
- * Copyright 2000-2014 JetBrains s.r.o.
+ * Copyright 2000-2016 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.
*/
package com.intellij.openapi.vcs.changes;
-import com.intellij.CommonBundle;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.util.SystemInfo;
/**
* @author Dmitry Avdeev
*/
-public class VcsConfirmationDialog extends OptionsDialog {
-
+class VcsConfirmationDialog extends OptionsDialog {
+ @NotNull private final String myOkText;
+ @NotNull private final String myCancelText;
private final VcsShowConfirmationOption myOption;
private final String myMessage;
private final String myDoNotShowMessage;
- protected VcsConfirmationDialog(Project project, VcsShowConfirmationOption option, String message, @NotNull String doNotShowMessage) {
+ VcsConfirmationDialog(@NotNull Project project,
+ @NotNull String title,
+ @NotNull String okText,
+ @NotNull String cancelText,
+ @NotNull VcsShowConfirmationOption option,
+ @NotNull String message,
+ @NotNull String doNotShowMessage) {
super(project);
+ myOkText = okText;
+ myCancelText = cancelText;
myOption = option;
myMessage = message;
myDoNotShowMessage = doNotShowMessage;
- setTitle("Confirmation");
+ setTitle(title);
init();
}
@NotNull
@Override
protected Action[] createActions() {
- final AbstractAction okAction = new AbstractAction(CommonBundle.getYesButtonText()) {
+ final AbstractAction okAction = new AbstractAction(myOkText) {
{
putValue(DEFAULT_ACTION, Boolean.TRUE);
}
+ @Override
public void actionPerformed(ActionEvent e) {
doOKAction();
}
};
- final AbstractAction cancelAction = new AbstractAction(CommonBundle.getNoButtonText()) {
+ final AbstractAction cancelAction = new AbstractAction(myCancelText) {
+ @Override
public void actionPerformed(ActionEvent e) {
doCancelAction();
}
@NotNull
PermanentGraph<Integer> getPermanentGraph();
+ @NotNull
+ VcsLogFilterCollection getFilters();
}
/**
* Return the style which should be used for the log table commit entry, or VcsCommitStyle.DEFAULT if this highlighter does not specify any style for this commit.
- *
- * @param commitIndex index of commit (can be transferred to the Hash and vice versa).
+ * @param commitDetails details of selected commit.
* @param isSelected if true, the row currently has selection on it.
*/
@NotNull
- VcsCommitStyle getStyle(int commitIndex, boolean isSelected);
+ VcsCommitStyle getStyle(@NotNull VcsShortCommitDetails commitDetails, boolean isSelected);
+
+ /**
+ * This method is called when new data arrives to the ui.
+ * @param dataPack new visible pack.
+ * @param refreshHappened true if permanent graph has changed.
+ */
+ void update(@NotNull VcsLogDataPack dataPack, boolean refreshHappened);
/**
* Describes how to display commit entry in the log table (for example, text or background color).
@NotNull
VcsLogDataPack getDataPack();
- void addHighlighter(@NotNull VcsLogHighlighter highlighter);
-
- void removeHighlighter(@NotNull VcsLogHighlighter highlighter);
-
void addLogListener(@NotNull VcsLogListener listener);
void removeLogListener(@NotNull VcsLogListener listener);
<group id="Vcs.Log.Settings">
<reference id="Vcs.Log.ShowBranchesPanelAction"/>
<reference id="Vcs.Log.ShowRootsColumnAction"/>
+ <separator/>
+ <reference id="Vcs.Log.CollapseAll"/>
+ <reference id="Vcs.Log.ExpandAll"/>
<reference id="Vcs.Log.HighlightersActionGroup"/>
</group>
<group id="Vcs.Log.Toolbar">
- <reference id="Vcs.Log.CollapseAll"/>
- <reference id="Vcs.Log.ExpandAll"/>
<reference id="Vcs.Log.ShowLongEdges"/>
<reference id="Vcs.Log.ShowDetailsAction"/>
</group>
public boolean LONG_EDGES_VISIBLE = false;
public int BEK_SORT_TYPE = 0;
public boolean SHOW_ROOT_NAMES = false;
- public boolean HIGHLIGHT_MY_COMMITS = true;
public Deque<UserGroup> RECENTLY_FILTERED_USER_GROUPS = new ArrayDeque<UserGroup>();
public Deque<UserGroup> RECENTLY_FILTERED_BRANCH_GROUPS = new ArrayDeque<UserGroup>();
public Map<String, Boolean> HIGHLIGHTERS = ContainerUtil.newTreeMap();
myState.HIGHLIGHTERS.put(id, value);
}
- public boolean isHighlightMyCommits() {
- return myState.HIGHLIGHT_MY_COMMITS;
- }
-
- public void setHighlightMyCommits(boolean isHighlightMyCommits) {
- myState.HIGHLIGHT_MY_COMMITS = isHighlightMyCommits;
- }
-
public static class UserGroup {
public List<String> users = new ArrayList<String>();
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.vcs.log.VcsLogDataPack;
+import com.intellij.vcs.log.VcsLogFilterCollection;
import com.intellij.vcs.log.VcsLogProvider;
import com.intellij.vcs.log.VcsLogRefs;
import com.intellij.vcs.log.graph.PermanentGraph;
import com.intellij.vcs.log.graph.VisibleGraph;
+import com.intellij.vcs.log.impl.VcsLogFilterCollectionImpl;
import org.jetbrains.annotations.NotNull;
import java.util.Map;
public class VisiblePack implements VcsLogDataPack {
- public static final VisiblePack EMPTY = new VisiblePack(DataPack.EMPTY, EmptyVisibleGraph.getInstance(), false);
+ public static final VisiblePack EMPTY = new VisiblePack(DataPack.EMPTY, EmptyVisibleGraph.getInstance(), false, VcsLogFilterCollectionImpl.EMPTY);
@NotNull private final DataPack myDataPack;
@NotNull private final VisibleGraph<Integer> myVisibleGraph;
private final boolean myCanRequestMore;
+ @NotNull private final VcsLogFilterCollection myFilters;
- VisiblePack(@NotNull DataPack dataPack, @NotNull VisibleGraph<Integer> graph, boolean canRequestMore) {
+ VisiblePack(@NotNull DataPack dataPack, @NotNull VisibleGraph<Integer> graph, boolean canRequestMore, @NotNull VcsLogFilterCollection filters) {
myDataPack = dataPack;
myVisibleGraph = graph;
myCanRequestMore = canRequestMore;
+ myFilters = filters;
}
@NotNull
public boolean isFull() {
return myDataPack.isFull();
}
+
+ @Override
+ @NotNull
+ public VcsLogFilterCollection getFilters() {
+ return myFilters;
+ }
}
import com.intellij.vcs.log.graph.PermanentGraph;
import com.intellij.vcs.log.graph.VisibleGraph;
import com.intellij.vcs.log.impl.VcsLogFilterCollectionImpl;
+import com.intellij.vcs.log.impl.VcsLogHashFilterImpl;
import com.intellij.vcs.log.impl.VcsLogUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
else {
visibleGraph = dataPack.getPermanentGraph().createVisibleGraph(sortType, matchingHeads, getMatchedCommitIndex(matchingCommits));
}
- return Pair.create(new VisiblePack(dataPack, visibleGraph, canRequestMore), commitCount);
+ return Pair.create(new VisiblePack(dataPack, visibleGraph, canRequestMore, filters), commitCount);
}
private static <T> boolean matchesNothing(@Nullable Collection<T> matchingSet) {
}
});
VisibleGraph<Integer> visibleGraph = dataPack.getPermanentGraph().createVisibleGraph(sortType, null, indices);
- return new VisiblePack(dataPack, visibleGraph, false);
+ return new VisiblePack(dataPack, visibleGraph, false, new VcsLogFilterCollectionImpl(null, null, new VcsLogHashFilterImpl(hashes), null, null, null, null));
}
@Nullable
import java.util.List;
public class VcsLogFilterCollectionImpl implements VcsLogFilterCollection {
+ @NotNull public static final VcsLogFilterCollection EMPTY = new VcsLogFilterCollectionImpl(null, null, null, null, null, null, null);
@Nullable private final VcsLogBranchFilter myBranchFilter;
@Nullable private final VcsLogUserFilter myUserFilter;
import com.intellij.openapi.util.Condition;
import com.intellij.ui.JBColor;
import com.intellij.vcs.log.*;
-import com.intellij.vcs.log.data.LoadingDetails;
import com.intellij.vcs.log.data.VcsLogDataHolder;
-import com.intellij.vcs.log.data.VcsLogUiProperties;
import com.intellij.vcs.log.impl.VcsLogUtil;
-import com.intellij.vcs.log.ui.filter.VcsLogClassicFilterUi;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class CurrentBranchHighlighter implements VcsLogHighlighter {
private static final JBColor CURRENT_BRANCH_BG = new JBColor(new Color(228, 250, 255), new Color(63, 71, 73));
- @NotNull private final VcsLogUiProperties myUiProperties;
@NotNull private final VcsLogDataHolder myDataHolder;
- @NotNull private final VcsLogFilterUi myFilterUi;
+ @NotNull private final VcsLogUi myLogUi;
@Nullable private String mySingleFilteredBranch;
- public CurrentBranchHighlighter(@NotNull VcsLogDataHolder logDataHolder,
- @NotNull VcsLogUiProperties uiProperties,
- @NotNull VcsLogFilterUi filterUi) {
+ public CurrentBranchHighlighter(@NotNull VcsLogDataHolder logDataHolder, @NotNull VcsLogUi logUi) {
myDataHolder = logDataHolder;
- myUiProperties = uiProperties;
- myFilterUi = filterUi;
-
-
- // this code will look much simpler when history* branch is merged
- ((VcsLogClassicFilterUi)filterUi).getLogUi().addLogListener(new VcsLogListener() {
- @Override
- public void onChange(@NotNull VcsLogDataPack dataPack, boolean refreshHappened) {
- VcsLogBranchFilter branchFilter = myFilterUi.getFilters().getBranchFilter();
- mySingleFilteredBranch = branchFilter == null
- ? null
- : VcsLogUtil
- .getSingleFilteredBranch(branchFilter, dataPack.getRefs());
- }
- });
+ myLogUi = logUi;
}
@NotNull
@Override
- public VcsCommitStyle getStyle(int commitIndex, boolean isSelected) {
- if (isSelected || !myUiProperties.isHighlighterEnabled(Factory.ID)) return VcsCommitStyle.DEFAULT;
- VcsShortCommitDetails details = myDataHolder.getMiniDetailsGetter().getCommitDataIfAvailable(commitIndex);
- if (details != null && !(details instanceof LoadingDetails)) {
- VcsLogProvider provider = myDataHolder.getLogProvider(details.getRoot());
- String currentBranch = provider.getCurrentBranch(details.getRoot());
- VcsLogBranchFilter branchFilter = myFilterUi.getFilters().getBranchFilter();
- if (currentBranch != null && (branchFilter == null || !(currentBranch.equals(mySingleFilteredBranch)))) {
- Condition<CommitId> condition =
- myDataHolder.getContainingBranchesGetter().getContainedInBranchCondition(currentBranch, details.getRoot());
- if (condition.value(new CommitId(details.getId(), details.getRoot()))) {
- return VcsCommitStyleFactory.background(CURRENT_BRANCH_BG);
- }
+ public VcsCommitStyle getStyle(@NotNull VcsShortCommitDetails details, boolean isSelected) {
+ if (isSelected || !myLogUi.isHighlighterEnabled(Factory.ID)) return VcsCommitStyle.DEFAULT;
+ VcsLogProvider provider = myDataHolder.getLogProvider(details.getRoot());
+ String currentBranch = provider.getCurrentBranch(details.getRoot());
+ if (currentBranch != null && !(currentBranch.equals(mySingleFilteredBranch))) {
+ Condition<CommitId> condition =
+ myDataHolder.getContainingBranchesGetter().getContainedInBranchCondition(currentBranch, details.getRoot());
+ if (condition.value(new CommitId(details.getId(), details.getRoot()))) {
+ return VcsCommitStyleFactory.background(CURRENT_BRANCH_BG);
}
}
return VcsCommitStyle.DEFAULT;
}
+ @Override
+ public void update(@NotNull VcsLogDataPack dataPack, boolean refreshHappened) {
+ VcsLogBranchFilter branchFilter = dataPack.getFilters().getBranchFilter();
+ mySingleFilteredBranch = branchFilter == null ? null : VcsLogUtil.getSingleFilteredBranch(branchFilter, dataPack.getRefs());
+ }
+
public static class Factory implements VcsLogHighlighterFactory {
@NotNull private static final String ID = "CURRENT_BRANCH";
@NotNull
@Override
- public VcsLogHighlighter createHighlighter(@NotNull VcsLogDataHolder logDataHolder,
- @NotNull VcsLogUiProperties uiProperties,
- @NotNull VcsLogFilterUi filterUi) {
- return new CurrentBranchHighlighter(logDataHolder, uiProperties, filterUi);
+ public VcsLogHighlighter createHighlighter(@NotNull VcsLogDataHolder logDataHolder, @NotNull VcsLogUi logUi) {
+ return new CurrentBranchHighlighter(logDataHolder, logUi);
}
@NotNull
public String getTitle() {
return "Current Branch";
}
+
+ @Override
+ public boolean showMenuItem() {
+ return true;
+ }
}
}
import com.intellij.ui.Gray;
import com.intellij.ui.JBColor;
-import com.intellij.vcs.log.VcsCommitStyleFactory;
-import com.intellij.vcs.log.VcsLogFilterUi;
-import com.intellij.vcs.log.VcsLogHighlighter;
-import com.intellij.vcs.log.VcsShortCommitDetails;
-import com.intellij.vcs.log.data.LoadingDetails;
+import com.intellij.vcs.log.*;
import com.intellij.vcs.log.data.VcsLogDataHolder;
-import com.intellij.vcs.log.data.VcsLogUiProperties;
import org.jetbrains.annotations.NotNull;
public class MergeCommitsHighlighter implements VcsLogHighlighter {
public static final JBColor MERGE_COMMIT_FOREGROUND = new JBColor(Gray._128, Gray._96);
- @NotNull private final VcsLogUiProperties myUiProperties;
- @NotNull private final VcsLogDataHolder myDataHolder;
+ @NotNull private final VcsLogUi myLogUi;
- public MergeCommitsHighlighter(@NotNull VcsLogDataHolder logDataHolder, @NotNull VcsLogUiProperties uiProperties) {
- myDataHolder = logDataHolder;
- myUiProperties = uiProperties;
+ public MergeCommitsHighlighter(@NotNull VcsLogUi logUi) {
+ myLogUi = logUi;
}
@NotNull
@Override
- public VcsCommitStyle getStyle(int commitIndex, boolean isSelected) {
- if (isSelected || !myUiProperties.isHighlighterEnabled(Factory.ID)) return VcsCommitStyle.DEFAULT;
- VcsShortCommitDetails details = myDataHolder.getMiniDetailsGetter().getCommitDataIfAvailable(commitIndex);
- if (details != null && !(details instanceof LoadingDetails)) {
- if (details.getParents().size() >= 2) return VcsCommitStyleFactory.foreground(MERGE_COMMIT_FOREGROUND);
- }
+ public VcsCommitStyle getStyle(@NotNull VcsShortCommitDetails details, boolean isSelected) {
+ if (isSelected || !myLogUi.isHighlighterEnabled(Factory.ID)) return VcsCommitStyle.DEFAULT;
+ if (details.getParents().size() >= 2) return VcsCommitStyleFactory.foreground(MERGE_COMMIT_FOREGROUND);
return VcsCommitStyle.DEFAULT;
}
+ @Override
+ public void update(@NotNull VcsLogDataPack dataPack, boolean refreshHappened) {
+ }
+
public static class Factory implements VcsLogHighlighterFactory {
@NotNull private static final String ID = "MERGE_COMMITS";
@NotNull
@Override
- public VcsLogHighlighter createHighlighter(@NotNull VcsLogDataHolder logDataHolder,
- @NotNull VcsLogUiProperties uiProperties,
- @NotNull VcsLogFilterUi filterUi) {
- return new MergeCommitsHighlighter(logDataHolder, uiProperties);
+ public VcsLogHighlighter createHighlighter(@NotNull VcsLogDataHolder logDataHolder, @NotNull VcsLogUi logUi) {
+ return new MergeCommitsHighlighter(logUi);
}
@NotNull
public String getTitle() {
return "Merge Commits";
}
+
+ @Override
+ public boolean showMenuItem() {
+ return true;
+ }
}
}
*/
package com.intellij.vcs.log.ui;
-import com.intellij.openapi.application.ApplicationManager;
import com.intellij.util.NotNullFunction;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.vcs.log.*;
-import com.intellij.vcs.log.data.LoadingDetails;
import com.intellij.vcs.log.data.VcsLogDataHolder;
-import com.intellij.vcs.log.data.VcsLogUiProperties;
-import com.intellij.vcs.log.impl.VcsLogContentProvider;
-import com.intellij.vcs.log.impl.VcsLogManager;
import com.intellij.vcs.log.impl.VcsUserImpl;
import com.intellij.vcs.log.ui.filter.VcsLogUserFilterImpl;
import org.jetbrains.annotations.NotNull;
import java.util.Set;
public class MyCommitsHighlighter implements VcsLogHighlighter {
- @NotNull private final VcsLogUiProperties myUiProperties;
@NotNull private final VcsLogDataHolder myDataHolder;
- @NotNull private final VcsLogFilterUi myFilterUi;
- private boolean myAreTheOnlyUsers = false;
+ @NotNull private final VcsLogUi myLogUi;
+ private boolean myShouldHighlightUser = false;
- public MyCommitsHighlighter(@NotNull VcsLogDataHolder logDataHolder,
- @NotNull VcsLogUiProperties uiProperties,
- @NotNull VcsLogFilterUi filterUi) {
+ public MyCommitsHighlighter(@NotNull VcsLogDataHolder logDataHolder, @NotNull VcsLogUi logUi) {
myDataHolder = logDataHolder;
- myUiProperties = uiProperties;
- myFilterUi = filterUi;
- // migration to map storage
- if (!myUiProperties.isHighlightMyCommits()) {
- // by default, my commits highlighter was enabled
- // if it was disabled we need to migrate that
- myUiProperties.enableHighlighter(Factory.ID, false);
- myUiProperties.setHighlightMyCommits(true);
- }
-
- // this is a tmp solution for performance problems of calculating areTheOnlyUsers every repaint (we simply do not want to do that)
- // todo remove this when history2 branch is merged into master (history2 will allow a proper way to fix the problem)
- ApplicationManager.getApplication().invokeLater(new Runnable() {
- @Override
- public void run() {
- if (myDataHolder.getProject().isDisposed()) return;
- VcsLogManager logManager = VcsLogContentProvider.findLogManager(myDataHolder.getProject());
- if (logManager != null) {
- VcsLogUiImpl logUi = logManager.getLogUi();
- if (logUi != null) {
- logUi.addLogListener(new VcsLogListener() {
- @Override
- public void onChange(@NotNull VcsLogDataPack dataPack, boolean refreshHappened) {
- myAreTheOnlyUsers = areTheOnlyUsers();
- }
- });
- }
- }
- }
- });
+ myLogUi = logUi;
}
@NotNull
@Override
- public VcsCommitStyle getStyle(int commitIndex, boolean isSelected) {
- if (!myUiProperties.isHighlighterEnabled(Factory.ID)) return VcsCommitStyle.DEFAULT;
- if (!myAreTheOnlyUsers && !isFilteredByCurrentUser()) {
- VcsShortCommitDetails details = myDataHolder.getMiniDetailsGetter().getCommitDataIfAvailable(commitIndex);
- if (details != null && !(details instanceof LoadingDetails)) {
- VcsUser currentUser = myDataHolder.getCurrentUser().get(details.getRoot());
- if (currentUser != null && VcsUserImpl.isSamePerson(currentUser, details.getAuthor())) {
- return VcsCommitStyleFactory.bold();
- }
+ public VcsCommitStyle getStyle(@NotNull VcsShortCommitDetails details, boolean isSelected) {
+ if (!myLogUi.isHighlighterEnabled(Factory.ID)) return VcsCommitStyle.DEFAULT;
+ if (myShouldHighlightUser) {
+ VcsUser currentUser = myDataHolder.getCurrentUser().get(details.getRoot());
+ if (currentUser != null && VcsUserImpl.isSamePerson(currentUser, details.getAuthor())) {
+ return VcsCommitStyleFactory.bold();
}
}
return VcsCommitStyle.DEFAULT;
}
- private boolean areTheOnlyUsers() {
+ @Override
+ public void update(@NotNull VcsLogDataPack dataPack, boolean refreshHappened) {
+ myShouldHighlightUser = !isSingleUser() && !isFilteredByCurrentUser(dataPack.getFilters());
+ }
+
+ // returns true if only one user commits to this repository
+ private boolean isSingleUser() {
NotNullFunction<VcsUser, String> nameToString = new NotNullFunction<VcsUser, String>() {
@NotNull
@Override
return allUserNames.size() == currentUserNames.size() && currentUserNames.containsAll(allUserNames);
}
- private boolean isFilteredByCurrentUser() {
- VcsLogUserFilter userFilter = myFilterUi.getFilters().getUserFilter();
+ // returns true if filtered by "me"
+ private static boolean isFilteredByCurrentUser(@NotNull VcsLogFilterCollection filters) {
+ VcsLogUserFilter userFilter = filters.getUserFilter();
if (userFilter == null) return false;
Collection<String> filterByName = ((VcsLogUserFilterImpl)userFilter).getUserNamesForPresentation();
if (Collections.singleton(VcsLogUserFilterImpl.ME).containsAll(filterByName)) return true;
@NotNull
@Override
- public VcsLogHighlighter createHighlighter(@NotNull VcsLogDataHolder logDataHolder,
- @NotNull VcsLogUiProperties uiProperties,
- @NotNull VcsLogFilterUi filterUi) {
- return new MyCommitsHighlighter(logDataHolder, uiProperties, filterUi);
+ public VcsLogHighlighter createHighlighter(@NotNull VcsLogDataHolder logDataHolder, @NotNull VcsLogUi logUi) {
+ return new MyCommitsHighlighter(logDataHolder, logUi);
}
@NotNull
public String getTitle() {
return "My Commits";
}
+
+ @Override
+ public boolean showMenuItem() {
+ return true;
+ }
}
}
*/
package com.intellij.vcs.log.ui;
-import com.intellij.vcs.log.VcsLogFilterUi;
import com.intellij.vcs.log.VcsLogHighlighter;
+import com.intellij.vcs.log.VcsLogUi;
import com.intellij.vcs.log.data.VcsLogDataHolder;
-import com.intellij.vcs.log.data.VcsLogUiProperties;
import org.jetbrains.annotations.NotNull;
public interface VcsLogHighlighterFactory {
@NotNull
- VcsLogHighlighter createHighlighter(@NotNull VcsLogDataHolder logDataHolder,
- @NotNull VcsLogUiProperties uiProperties,
- @NotNull VcsLogFilterUi filterUi);
+ VcsLogHighlighter createHighlighter(@NotNull VcsLogDataHolder logDataHolder, @NotNull VcsLogUi logUi);
@NotNull
String getId();
@NotNull
String getTitle();
+
+ boolean showMenuItem();
}
myMainFrame = new MainFrame(logDataHolder, this, project, settings, uiProperties, myLog, myVisiblePack);
for (VcsLogHighlighterFactory factory : Extensions.getExtensions(LOG_HIGHLIGHTER_FACTORY_EP, myProject)) {
- addHighlighter(factory.createHighlighter(logDataHolder, myUiProperties, myMainFrame.getFilterUi()));
+ getTable().addHighlighter(factory.createHighlighter(logDataHolder, this));
}
}
return myVisiblePack;
}
- @Override
- public void addHighlighter(@NotNull VcsLogHighlighter highlighter) {
- getTable().addHighlighter(highlighter);
- repaintUI();
- }
-
- @Override
- public void removeHighlighter(@NotNull VcsLogHighlighter highlighter) {
- getTable().removeHighlighter(highlighter);
- repaintUI();
- }
-
@Override
public void addLogListener(@NotNull VcsLogListener listener) {
ApplicationManager.getApplication().assertIsDispatchThread();
/*
- * Copyright 2000-2015 JetBrains s.r.o.
+ * Copyright 2000-2016 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.
*/
package com.intellij.vcs.log.ui.actions;
-import com.intellij.openapi.actionSystem.AnActionEvent;
-import com.intellij.vcs.log.VcsLogDataKeys;
-import com.intellij.vcs.log.VcsLogUi;
-import com.intellij.vcs.log.graph.PermanentGraph;
import com.intellij.vcs.log.ui.VcsLogUiImpl;
import icons.VcsLogIcons;
import org.jetbrains.annotations.NotNull;
-public class CollapseGraphAction extends GraphAction {
- public CollapseGraphAction() {
- super("Collapse linear branches", "Collapse linear branches", VcsLogIcons.CollapseBranches);
+import javax.swing.*;
+
+public class CollapseGraphAction extends CollapseOrExpandGraphAction {
+ @Override
+ protected void executeAction(@NotNull VcsLogUiImpl vcsLogUi) {
+ vcsLogUi.collapseAll();
+ }
+
+ @NotNull
+ @Override
+ protected Icon getMergesIcon() {
+ return VcsLogIcons.CollapseMerges;
}
+ @NotNull
@Override
- public void actionPerformed(@NotNull AnActionEvent e) {
- VcsLogUi ui = e.getRequiredData(VcsLogDataKeys.VCS_LOG_UI);
- ((VcsLogUiImpl)ui).collapseAll();
+ protected Icon getBranchesIcon() {
+ return VcsLogIcons.CollapseMerges;
}
+ @NotNull
@Override
- protected void update(@NotNull VcsLogUi ui, @NotNull AnActionEvent e) {
- if (!ui.getFilterUi().getFilters().getDetailsFilters().isEmpty()) {
- e.getPresentation().setEnabled(false);
- }
- if (ui.getBekType() == PermanentGraph.SortType.LinearBek) {
- e.getPresentation().setIcon(VcsLogIcons.CollapseMerges);
- e.getPresentation().setText("Collapse all merges");
- e.getPresentation().setDescription("Collapse all merges");
- }
- else {
- e.getPresentation().setIcon(VcsLogIcons.CollapseBranches);
- e.getPresentation().setText("Collapse all linear branches");
- e.getPresentation().setDescription("Collapse all linear branches");
- }
+ protected String getPrefix() {
+ return "Collapse ";
}
}
--- /dev/null
+/*
+ * Copyright 2000-2015 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.vcs.log.ui.actions;
+
+import com.intellij.openapi.actionSystem.AnActionEvent;
+import com.intellij.openapi.project.DumbAwareAction;
+import com.intellij.openapi.wm.impl.content.ToolWindowContentUi;
+import com.intellij.vcs.log.VcsLogDataKeys;
+import com.intellij.vcs.log.VcsLogUi;
+import com.intellij.vcs.log.graph.PermanentGraph;
+import com.intellij.vcs.log.ui.VcsLogUiImpl;
+import org.jetbrains.annotations.NotNull;
+
+import javax.swing.*;
+
+abstract class CollapseOrExpandGraphAction extends DumbAwareAction {
+ private static final String LINEAR_BRANCHES = "Linear Branches";
+ private static final String LINEAR_BRANCHES_DESCRIPTION = "linear branches";
+ private static final String MERGES = "Merges";
+ private static final String MERGES_DESCRIPTION = "merges";
+
+ public CollapseOrExpandGraphAction() {
+ super("Collapse or Expand " + LINEAR_BRANCHES, "Collapse or Expand " + LINEAR_BRANCHES_DESCRIPTION, null);
+ }
+
+ @Override
+ public void actionPerformed(@NotNull AnActionEvent e) {
+ VcsLogUi ui = e.getRequiredData(VcsLogDataKeys.VCS_LOG_UI);
+ executeAction((VcsLogUiImpl)ui);
+ }
+
+ @Override
+ public void update(@NotNull AnActionEvent e) {
+ VcsLogUi ui = e.getData(VcsLogDataKeys.VCS_LOG_UI);
+
+ if (ui != null && ui.areGraphActionsEnabled()) {
+ e.getPresentation().setEnabled(true);
+ if (!ui.getFilterUi().getFilters().getDetailsFilters().isEmpty()) {
+ e.getPresentation().setEnabled(false);
+ }
+
+ if (ui.getBekType() == PermanentGraph.SortType.LinearBek) {
+ e.getPresentation().setText(getPrefix() + MERGES);
+ e.getPresentation().setDescription(getPrefix() + MERGES_DESCRIPTION);
+ }
+ else {
+ e.getPresentation().setText(getPrefix() + LINEAR_BRANCHES);
+ e.getPresentation().setDescription(getPrefix() + LINEAR_BRANCHES_DESCRIPTION);
+ }
+ }
+ else {
+ e.getPresentation().setEnabled(false);
+ }
+
+ e.getPresentation().setText(getPrefix() + LINEAR_BRANCHES);
+ e.getPresentation().setDescription(getPrefix() + LINEAR_BRANCHES_DESCRIPTION);
+ if (isIconHidden(e)) {
+ e.getPresentation().setIcon(null);
+ }
+ else {
+ e.getPresentation().setIcon(ui != null && ui.getBekType() == PermanentGraph.SortType.LinearBek ? getMergesIcon() : getBranchesIcon());
+ }
+ }
+
+ protected abstract void executeAction(@NotNull VcsLogUiImpl vcsLogUi);
+
+ @NotNull
+ protected abstract Icon getMergesIcon();
+
+ @NotNull
+ protected abstract Icon getBranchesIcon();
+
+ @NotNull
+ protected abstract String getPrefix();
+
+ private static boolean isIconHidden(@NotNull AnActionEvent e) {
+ return e.getPlace().equals(ToolWindowContentUi.POPUP_PLACE);
+ }
+
+}
/*
- * Copyright 2000-2015 JetBrains s.r.o.
+ * Copyright 2000-2016 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.
*/
package com.intellij.vcs.log.ui.actions;
-import com.intellij.openapi.actionSystem.AnActionEvent;
-import com.intellij.vcs.log.VcsLogDataKeys;
-import com.intellij.vcs.log.VcsLogUi;
-import com.intellij.vcs.log.graph.PermanentGraph;
import com.intellij.vcs.log.ui.VcsLogUiImpl;
import icons.VcsLogIcons;
import org.jetbrains.annotations.NotNull;
-public class ExpandGraphAction extends GraphAction {
- public ExpandGraphAction() {
- super("Expand all branches", "Expand all branches", VcsLogIcons.ExpandBranches);
+import javax.swing.*;
+
+public class ExpandGraphAction extends CollapseOrExpandGraphAction {
+ @Override
+ protected void executeAction(@NotNull VcsLogUiImpl vcsLogUi) {
+ vcsLogUi.expandAll();
+ }
+
+ @NotNull
+ @Override
+ protected Icon getMergesIcon() {
+ return VcsLogIcons.ExpandMerges;
}
+ @NotNull
@Override
- public void actionPerformed(@NotNull AnActionEvent e) {
- VcsLogUi ui = e.getRequiredData(VcsLogDataKeys.VCS_LOG_UI);
- ((VcsLogUiImpl)ui).expandAll();
+ protected Icon getBranchesIcon() {
+ return VcsLogIcons.ExpandMerges;
}
+ @NotNull
@Override
- protected void update(@NotNull VcsLogUi ui, @NotNull AnActionEvent e) {
- if (!ui.getFilterUi().getFilters().getDetailsFilters().isEmpty()) {
- e.getPresentation().setEnabled(false);
- }
- if (ui.getBekType() == PermanentGraph.SortType.LinearBek) {
- e.getPresentation().setIcon(VcsLogIcons.ExpandMerges);
- e.getPresentation().setText("Expand all merges");
- e.getPresentation().setDescription("Expand all merges");
- }
- else {
- e.getPresentation().setIcon(VcsLogIcons.ExpandBranches);
- e.getPresentation().setText("Expand all linear branches");
- e.getPresentation().setDescription("Expand all linear branches");
- }
+ protected String getPrefix() {
+ return "Expand ";
}
}
+++ /dev/null
-/*
- * Copyright 2000-2015 JetBrains s.r.o.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.intellij.vcs.log.ui.actions;
-
-import com.intellij.openapi.actionSystem.AnActionEvent;
-import com.intellij.openapi.project.DumbAwareAction;
-import com.intellij.vcs.log.VcsLogDataKeys;
-import com.intellij.vcs.log.VcsLogUi;
-import org.jetbrains.annotations.NotNull;
-
-import javax.swing.*;
-
-public abstract class GraphAction extends DumbAwareAction {
-
- public GraphAction(@NotNull String text, @NotNull String description, @NotNull Icon icon) {
- super(text, description, icon);
- }
-
- private static boolean areGraphActionsEnabled(@NotNull AnActionEvent e) {
- VcsLogUi ui = e.getData(VcsLogDataKeys.VCS_LOG_UI);
- if (ui == null) return false;
- return ui.areGraphActionsEnabled();
- }
-
- @Override
- public void update(@NotNull AnActionEvent e) {
- boolean graphActionsEnabled = areGraphActionsEnabled(e);
- e.getPresentation().setEnabled(graphActionsEnabled);
- if (graphActionsEnabled) {
- update(e.getRequiredData(VcsLogDataKeys.VCS_LOG_UI), e);
- }
- }
-
- protected abstract void update(@NotNull VcsLogUi ui, @NotNull AnActionEvent e);
-}
if (ui != null) {
actions.add(new Separator("Highlight"));
for (VcsLogHighlighterFactory factory : Extensions.getExtensions(VcsLogUiImpl.LOG_HIGHLIGHTER_FACTORY_EP, e.getProject())) {
- actions.add(new EnableHighlighterAction(ui, factory));
+ if (factory.showMenuItem()) {
+ actions.add(new EnableHighlighterAction(ui, factory));
+ }
}
}
}
public class ShowLongEdgesAction extends ToggleAction implements DumbAware {
public ShowLongEdgesAction() {
- super("Show long edges", "Show long branch edges even if commits are invisible in the current view.", VcsLogIcons.ShowHideLongEdges);
+ super("Show Long Edges", "Show long branch edges even if commits are invisible in the current view.", VcsLogIcons.ShowHideLongEdges);
}
@Override
public void updateDataPack(@NotNull VisiblePack dataPack, boolean permGraphChanged) {
myFilterUi.updateDataPack(dataPack);
myDetailsPanel.updateDataPack(dataPack);
- myGraphTable.updateDataPack(dataPack);
+ myGraphTable.updateDataPack(dataPack, permGraphChanged);
myBranchesPanel.updateDataPack(dataPack, permGraphChanged);
}
Wrapper textFilter = new Wrapper(myFilterUi.createTextFilter());
textFilter.setVerticalSizeReferent(toolbar.getComponent());
- textFilter.setBorder(BorderFactory.createEmptyBorder(1, 5, 0, 0));
+ textFilter.setBorder(JBUI.Borders.emptyLeft(5));
ActionToolbar settings =
createActionsToolbar(new DefaultActionGroup(ActionManager.getInstance().getAction(VcsLogActionPlaces.VCS_LOG_QUICK_SETTINGS_ACTION)));
import com.intellij.util.ui.JBUI;
import com.intellij.util.ui.UIUtil;
import com.intellij.vcs.log.*;
+import com.intellij.vcs.log.data.LoadingDetails;
import com.intellij.vcs.log.data.VcsLogDataHolder;
import com.intellij.vcs.log.data.VisiblePack;
import com.intellij.vcs.log.graph.*;
initColumnSize();
}
- public void updateDataPack(@NotNull VisiblePack visiblePack) {
+ public void updateDataPack(@NotNull VisiblePack visiblePack, boolean permGraphChanged) {
VcsLogGraphTable.Selection previousSelection = getSelection();
getGraphTableModel().setVisiblePack(visiblePack);
previousSelection.restore(visiblePack.getVisibleGraph(), true);
+
+ for (VcsLogHighlighter highlighter: myHighlighters) {
+ highlighter.update(visiblePack, permGraphChanged);
+ }
+
setPaintBusy(false);
initColumnSize();
}
.createStyle(dummyRendererComponent.getForeground(), dummyRendererComponent.getBackground(), VcsLogHighlighter.TextStyle.NORMAL);
}
- final RowInfo<Integer> rowInfo = visibleGraph.getRowInfo(row);
+ RowInfo<Integer> rowInfo = visibleGraph.getRowInfo(row);
VcsLogHighlighter.VcsCommitStyle defaultStyle = VcsCommitStyleFactory
.createStyle(rowInfo.getRowType() == RowType.UNMATCHED ? JBColor.GRAY : dummyRendererComponent.getForeground(),
dummyRendererComponent.getBackground(), VcsLogHighlighter.TextStyle.NORMAL);
+ final VcsShortCommitDetails details = myLogDataHolder.getMiniDetailsGetter().getCommitDataIfAvailable(rowInfo.getCommit());
+ if (details == null || details instanceof LoadingDetails) return defaultStyle;
+
List<VcsLogHighlighter.VcsCommitStyle> styles =
ContainerUtil.map(myHighlighters, new Function<VcsLogHighlighter, VcsLogHighlighter.VcsCommitStyle>() {
@Override
public VcsLogHighlighter.VcsCommitStyle fun(VcsLogHighlighter highlighter) {
- return highlighter.getStyle(rowInfo.getCommit(), selected);
+ return highlighter.getStyle(details, selected);
}
});
-
return VcsCommitStyleFactory.combine(ContainerUtil.append(styles, defaultStyle));
}
/*
- * Copyright 2000-2015 JetBrains s.r.o.
+ * Copyright 2000-2016 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.
markupModel = (MarkupModelEx)DocumentMarkupModel.forDocument(document, getProject(), false);
if (markupModel != null) {
// renderersChanged false - we don't change gutter size
- markupModel.fireAttributesChanged((RangeHighlighterEx)highlighter, false);
+ markupModel.fireAttributesChanged((RangeHighlighterEx)highlighter, false, false);
}
}
}
key="method.return.concrete.class.display.name" groupBundle="messages.InspectionsBundle"
groupKey="group.names.abstraction.issues" enabledByDefault="false" level="WARNING"
implementationClass="com.siyeh.ig.abstraction.MethodReturnOfConcreteClassInspection"/>
+ <localInspection groupPath="Java" language="JAVA" shortName="OptionalUsedAsFieldOrParameterType" bundle="com.siyeh.InspectionGadgetsBundle"
+ key="optional.used.as.field.or.parameter.type.display.name" groupBundle="messages.InspectionsBundle"
+ groupKey="group.names.abstraction.issues" enabledByDefault="true" level="WARNING"
+ implementationClass="com.siyeh.ig.abstraction.OptionalUsedAsFieldOrParameterTypeInspection"/>
<localInspection groupPath="Java" language="JAVA" shortName="OverlyStrongTypeCast" bundle="com.siyeh.InspectionGadgetsBundle" key="overly.strong.type.cast.display.name"
groupBundle="messages.InspectionsBundle" groupKey="group.names.abstraction.issues" enabledByDefault="false"
level="WARNING" implementationClass="com.siyeh.ig.abstraction.OverlyStrongTypeCastInspection"/>
level="WARNING" implementationClass="com.siyeh.ig.threading.AwaitNotInLoopInspection"/>
<localInspection groupPath="Java" language="JAVA" shortName="AtomicFieldUpdaterIssues" bundle="com.siyeh.InspectionGadgetsBundle"
key="atomic.field.updater.issues.display.name" groupBundle="messages.InspectionsBundle"
- groupKey="group.names.threading.issues" enabledByDefault="false" level="WARNING"
+ groupKey="group.names.threading.issues" enabledByDefault="true" level="WARNING"
implementationClass="com.siyeh.ig.threading.AtomicFieldUpdaterIssuesInspection"/>
<localInspection groupPath="Java" language="JAVA" shortName="AtomicFieldUpdaterNotStaticFinal" bundle="com.siyeh.InspectionGadgetsBundle"
key="atomic.field.updater.not.static.final.display.name" groupBundle="messages.InspectionsBundle"
- groupKey="group.names.threading.issues" enabledByDefault="false" level="WARNING"
+ groupKey="group.names.threading.issues" enabledByDefault="true" level="WARNING"
implementationClass="com.siyeh.ig.threading.AtomicFieldUpdaterNotStaticFinalInspection"/>
<localInspection groupPath="Java" language="JAVA" shortName="AwaitWithoutCorrespondingSignal" bundle="com.siyeh.InspectionGadgetsBundle"
key="await.without.corresponding.signal.display.name" groupBundle="messages.InspectionsBundle"
return.of.null.objects.option=Report methods that return objects
return.of.null.collections.option=Report methods that return collection objects
return.of.null.ignore.private.option=Ignore private methods
-return.of.null.optional.quickfix=Replace with 'Optional.empty()'
+return.of.null.optional.quickfix=Replace with ''{0}.empty()''
+return.of.null.optional.quickfix.family=Replace with 'Optional.empty()'
static.method.via.subclass.display.name=Static method referenced via subclass
static.method.via.subclass.problem.descriptor=Static method <code>#ref()</code> declared in class ''{0}'' but referenced via subclass ''{1}'' #loc
static.method.via.subclass.rationalize.quickfix=Rationalize static method call
package.local.field.not.accessible=package local field ''{0}'' is not accessible from here
protected.field.not.accessible.problem.descriptor=''protected'' field ''{0}'' is not accessible from here
interface.clashes.with.object.class.display.name=Interface method clashes with method in 'java.lang.Object'
-interface.clashes.with.object.class.problem.descriptor=<code>#ref()</code> clashes with method in 'java.lang.Object'
\ No newline at end of file
+interface.clashes.with.object.class.problem.descriptor=<code>#ref()</code> clashes with method in 'java.lang.Object'
+optional.used.as.field.or.parameter.type.display.name='java.util.Optional<T>' used as field or parameter type
+optional.used.as.field.type.problem.descriptor=<code>#ref</code> used as type for field ''{0}''
+optional.used.as.parameter.type.problem.descriptor=<code>#ref</code> used as type for parameter ''{0}''
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright 2000-2016 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.siyeh.ig.abstraction;
+
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiField;
+import com.intellij.psi.PsiParameter;
+import com.intellij.psi.PsiTypeElement;
+import com.siyeh.InspectionGadgetsBundle;
+import com.siyeh.ig.BaseInspection;
+import com.siyeh.ig.BaseInspectionVisitor;
+import com.siyeh.ig.psiutils.TypeUtils;
+import org.jetbrains.annotations.Nls;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author Bas Leijdekkers
+ */
+public class OptionalUsedAsFieldOrParameterTypeInspection extends BaseInspection {
+
+ @Nls
+ @NotNull
+ @Override
+ public String getDisplayName() {
+ return InspectionGadgetsBundle.message("optional.used.as.field.or.parameter.type.display.name");
+ }
+
+ @NotNull
+ @Override
+ protected String buildErrorString(Object... infos) {
+ final PsiTypeElement typeElement = (PsiTypeElement)infos[0];
+ final PsiElement parent = typeElement.getParent();
+ if (parent instanceof PsiField) {
+ final PsiField field = (PsiField)parent;
+ return InspectionGadgetsBundle.message("optional.used.as.field.type.problem.descriptor", field.getName());
+ }
+ else if (parent instanceof PsiParameter) {
+ final PsiParameter parameter = (PsiParameter)parent;
+ return InspectionGadgetsBundle.message("optional.used.as.parameter.type.problem.descriptor", parameter.getName());
+ }
+ throw new AssertionError();
+ }
+
+ @Override
+ public BaseInspectionVisitor buildVisitor() {
+ return new OptionUsedAsFieldOrParameterTypeVisitor();
+ }
+
+ private static class OptionUsedAsFieldOrParameterTypeVisitor extends BaseInspectionVisitor {
+
+ @Override
+ public void visitField(PsiField field) {
+ super.visitField(field);
+ checkTypeElement(field.getTypeElement());
+ }
+
+ @Override
+ public void visitParameter(PsiParameter parameter) {
+ super.visitParameter(parameter);
+ checkTypeElement(parameter.getTypeElement());
+ }
+
+ private void checkTypeElement(PsiTypeElement typeElement) {
+ if (typeElement == null || !TypeUtils.isOptional(typeElement.getType())) {
+ return;
+ }
+ registerError(typeElement, typeElement);
+ }
+ }
+}
/*
- * Copyright 2003-2012 Dave Griffith, Bas Leijdekkers
+ * Copyright 2003-2016 Dave Griffith, Bas Leijdekkers
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
import com.siyeh.ig.DelegatingFix;
import com.siyeh.ig.InspectionGadgetsFix;
import com.siyeh.ig.psiutils.ParenthesesUtils;
+import com.siyeh.ig.psiutils.TypeUtils;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
@Override
@NotNull
public String buildErrorString(Object... infos) {
- return InspectionGadgetsBundle.message(
- "assignment.to.null.problem.descriptor");
+ return InspectionGadgetsBundle.message("assignment.to.null.problem.descriptor");
}
@Override
protected InspectionGadgetsFix buildFix(Object... infos) {
- final Object info = infos[0];
- if (!(info instanceof PsiReferenceExpression)) {
+ final PsiReferenceExpression referenceExpression = (PsiReferenceExpression)infos[0];
+ if (TypeUtils.isOptional(referenceExpression.getType())) {
return null;
}
- final PsiElement target = ((PsiReferenceExpression)info).resolve();
+ final PsiElement target = referenceExpression.resolve();
if (!(target instanceof PsiVariable)) {
return null;
}
+ final PsiVariable variable = (PsiVariable)target;
+ if (NullableNotNullManager.isNotNull(variable)) {
+ return null;
+ }
final NullableNotNullManager manager = NullableNotNullManager.getInstance(target.getProject());
- return new DelegatingFix(new AddAnnotationPsiFix(manager.getDefaultNullable(), (PsiVariable)target,PsiNameValuePair.EMPTY_ARRAY));
+ return new DelegatingFix(new AddAnnotationPsiFix(manager.getDefaultNullable(), variable, PsiNameValuePair.EMPTY_ARRAY));
}
@Override
public JComponent createOptionsPanel() {
return new SingleCheckboxOptionsPanel(InspectionGadgetsBundle.message(
- "assignment.to.null.option"), this,
- "ignoreAssignmentsToFields");
+ "assignment.to.null.option"), this, "ignoreAssignmentsToFields");
}
@Override
import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
import com.intellij.psi.util.PsiTreeUtil;
-import com.intellij.psi.util.PsiUtil;
import com.intellij.util.ArrayUtil;
import com.siyeh.InspectionGadgetsBundle;
import com.siyeh.ig.*;
import com.siyeh.ig.psiutils.CollectionUtils;
+import com.siyeh.ig.psiutils.TypeUtils;
import org.intellij.lang.annotations.Pattern;
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NotNull;
}
if (element instanceof PsiMethod) {
final PsiMethod method = (PsiMethod)element;
- final PsiClass aClass = PsiUtil.resolveClassInClassTypeOnly(method.getReturnType());
- if (aClass != null && CommonClassNames.JAVA_UTIL_OPTIONAL.equals(aClass.getQualifiedName())) {
+ final PsiType type = method.getReturnType();
+ if (TypeUtils.isOptional(type)) {
// don't suggest to annotate Optional methods as Nullable
- return new ReplaceWithEmptyOptionalFix();
+ return new ReplaceWithEmptyOptionalFix(((PsiClassType)type).rawType().getCanonicalText());
}
}
}
private static class ReplaceWithEmptyOptionalFix extends InspectionGadgetsFix {
+
+ private final String myTypeText;
+
+ public ReplaceWithEmptyOptionalFix(String typeText) {
+ myTypeText = typeText;
+ }
+
@Nls
@NotNull
@Override
public String getName() {
- return InspectionGadgetsBundle.message("return.of.null.optional.quickfix");
+ return InspectionGadgetsBundle.message("return.of.null.optional.quickfix", myTypeText);
}
@Nls
@NotNull
@Override
public String getFamilyName() {
- return getName();
+ return InspectionGadgetsBundle.message("return.of.null.optional.quickfix.family");
}
@Override
return;
}
final PsiLiteralExpression literalExpression = (PsiLiteralExpression)element;
- PsiReplacementUtil.replaceExpression(literalExpression, "java.util.Optional.empty()");
+ PsiReplacementUtil.replaceExpression(literalExpression, myTypeText + ".empty()");
}
}
return;
}
- final PsiClass aClass = PsiUtil.resolveClassInClassTypeOnly(returnType);
- if (aClass != null && "java.util.Optional".equals(aClass.getQualifiedName())) {
+ if (TypeUtils.isOptional(returnType)) {
registerError(value, value);
return;
}
/*
- * Copyright 2003-2015 Dave Griffith, Bas Leijdekkers
+ * Copyright 2003-2016 Dave Griffith, Bas Leijdekkers
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
import com.intellij.psi.*;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.util.InheritanceUtil;
+import com.intellij.psi.util.PsiUtil;
import com.intellij.psi.util.TypeConversionUtil;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
return typeEquals(CommonClassNames.JAVA_LANG_STRING, targetType);
}
+ public static boolean isOptional(@Nullable PsiType type) {
+ final PsiClass aClass = PsiUtil.resolveClassInClassTypeOnly(type);
+ if (aClass == null) {
+ return false;
+ }
+ final String qualifiedName = aClass.getQualifiedName();
+ return CommonClassNames.JAVA_UTIL_OPTIONAL.equals(qualifiedName)
+ || "java.util.OptionalDouble".equals(qualifiedName)
+ || "java.util.OptionalInt".equals(qualifiedName)
+ || "java.util.OptionalLong".equals(qualifiedName);
+ }
+
public static boolean isExpressionTypeAssignableWith(@NotNull PsiExpression expression, @NotNull Iterable<String> rhsTypeTexts) {
final PsiType type = expression.getType();
if (type == null) {
if (expression == null) {
return null;
}
- PsiType type = expression instanceof PsiFunctionalExpression ? ((PsiFunctionalExpression)expression).getFunctionalInterfaceType()
+ PsiType type = expression instanceof PsiFunctionalExpression ? ((PsiFunctionalExpression)expression).getFunctionalInterfaceType()
: expression.getType();
if (type == null) {
return null;
--- /dev/null
+<html>
+<body>
+Reports any uses of <b>java.util.Optional<T></b>, <b>java.util.OptionalDouble</b>, <b>java.util.OptionalInt</b> or
+<b>java.util.OptionalLong</b> as the type for a field or a parameter.
+Optional was designed to provide a limited mechanism for library method return types where there needed
+to be a clear way to represent "no result".
+Using a field with type Optional is also problematic if the class needs to be <b>Serializable</b>, which Optional isn't.
+<!-- tooltip end -->
+<p>
+<small>New in 16</small>
+</body>
+</html>
\ No newline at end of file
package com.siyeh.igtest.bugs;
-public class AssignmentToNullInspection
+public class AssignmentToNull
{
private Object m_foo = null;
public static void main(String[] args)
{
- new AssignmentToNullInspection(new Object()).bar();
+ new AssignmentToNull(new Object()).bar();
}
- public AssignmentToNullInspection(Object foo)
+ public AssignmentToNull(Object foo)
{
m_foo = foo;
}
{
Object foo = new Object();
System.out.println("foo = " + foo);
- foo = null;
- m_foo = null;
+ <warning descr="Assignment of variable 'foo' to 'null'">foo</warning> = null;
+ <warning descr="Assignment of variable 'm_foo' to 'null'">m_foo</warning> = null;
System.out.println("foo = " + foo);
System.out.println("m_foo = " + m_foo);
}
import java.util.Optional;
+import java.util.OptionalInt;
class WarnOptional {
return <warning descr="Return of 'null'">null</warning>;
}
+ public OptionalInt nothing() {
+ return <warning descr="Return of 'null'">null</warning>;
+ }
+
Object give() {
return null;
}
--- /dev/null
+/*
+ * Copyright 2000-2016 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.siyeh.ig.abstraction;
+
+import com.intellij.codeInspection.InspectionProfileEntry;
+import com.siyeh.ig.LightInspectionTestCase;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * @author Bas Leijdekkers
+ */
+public class OptionalUsedAsFieldOrParameterTypeInspectionTest extends LightInspectionTestCase {
+
+ public void testOptionalField() {
+ doTest("import java.util.Optional;" +
+ "class X {" +
+ " private /*'Optional<String>' used as type for field 's'*/Optional<String>/**/ s;" +
+ "}");
+ }
+
+ public void testOptionalParameter() {
+ doTest("import java.util.Optional;" +
+ "class X {" +
+ " void m(/*'Optional<Object>' used as type for parameter 'o'*/Optional<Object>/**/ o) {}" +
+ "}");
+ }
+
+ public void testOptionalDoubleField() {
+ doTest("import java.util.OptionalDouble;" +
+ "class X {" +
+ " private /*'OptionalDouble' used as type for field 'd'*/OptionalDouble/**/ d;" +
+ "}");
+ }
+
+ public void testNoWarnOnOptionalReturnType() {
+ doTest("import java.util.Optional;" +
+ "class X {" +
+ " Optional<Integer> f() {" +
+ " return null; // don't do this\n" +
+ " }" +
+ "}");
+ }
+
+ @Nullable
+ @Override
+ protected InspectionProfileEntry getInspection() {
+ return new OptionalUsedAsFieldOrParameterTypeInspection();
+ }
+
+ @Override
+ protected String[] getEnvironmentClasses() {
+ return new String[] {
+ "package java.util;" +
+ "public final class Optional<T> {}",
+
+ "package java.util;" +
+ "public final class OptionalDouble {}"
+ };
+ }
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright 2000-2016 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.siyeh.ig.assignment;
+
+import com.intellij.codeInspection.InspectionProfileEntry;
+import com.siyeh.ig.LightInspectionTestCase;
+import junit.framework.TestCase;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * @author Bas Leijdekkers
+ */
+public class AssignmentToNullInspectionTest extends LightInspectionTestCase {
+
+ public void testAssignmentToNull() {
+ doTest();
+ }
+
+ @Nullable
+ @Override
+ protected InspectionProfileEntry getInspection() {
+ return new AssignmentToNullInspection();
+ }
+}
\ No newline at end of file
protected String[] getEnvironmentClasses() {
return new String[] {
"package java.util;" +
- "public final class Optional<T> {}"
+ "public final class Optional<T> {}",
+
+ "package java.util;" +
+ "public final class OptionalInt {}"
};
}
}
\ No newline at end of file
<fileTypeFactory implementation="git4idea.vfs.GitFileTypeFactory"/>
<vcs.taskHandler implementation="git4idea.GitTaskHandler"/>
+
+ <logHighlighterFactory implementation="git4idea.branch.DeepComparator$Factory"/>
</extensions>
<extensionPoints>
/*
- * Copyright 2000-2014 JetBrains s.r.o.
+` * Copyright 2000-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
package git4idea.branch;
import com.intellij.openapi.Disposable;
+import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.vcs.log.*;
+import com.intellij.vcs.log.data.VcsLogDataHolder;
import com.intellij.vcs.log.impl.HashImpl;
import com.intellij.vcs.log.impl.VcsLogUtil;
import com.intellij.vcs.log.ui.MergeCommitsHighlighter;
+import com.intellij.vcs.log.ui.VcsLogHighlighterFactory;
import git4idea.GitBranch;
import git4idea.commands.GitCommand;
import git4idea.commands.GitLineHandler;
import git4idea.commands.GitLineHandlerAdapter;
import git4idea.repo.GitRepository;
import git4idea.repo.GitRepositoryManager;
-import gnu.trove.TIntHashSet;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Map;
+import java.util.Set;
-public class DeepComparator implements Disposable {
-
+public class DeepComparator implements VcsLogHighlighter, Disposable {
private static final Logger LOG = Logger.getInstance(DeepComparator.class);
@NotNull private final Project myProject;
@NotNull private final GitRepositoryManager myRepositoryManager;
@NotNull private final VcsLogUi myUi;
- @NotNull private final VcsLogListener myLogListener;
- @Nullable private VcsLogHighlighter myHighlighter;
@Nullable private MyTask myTask;
+ @Nullable private Set<CommitId> myNonPickedCommits;
- @NotNull
- public static DeepComparator getInstance(@NotNull Project project, @NotNull VcsLogUi ui) {
- DeepComparatorHolder holder = ServiceManager.getService(project, DeepComparatorHolder.class);
- return holder.getInstance(ui);
- }
-
- DeepComparator(@NotNull Project project, @NotNull GitRepositoryManager manager, @NotNull VcsLogUi ui, @NotNull Disposable parent) {
+ public DeepComparator(@NotNull Project project, @NotNull GitRepositoryManager manager, @NotNull VcsLogUi ui, @NotNull Disposable parent) {
myProject = project;
myRepositoryManager = manager;
myUi = ui;
Disposer.register(parent, this);
-
- myLogListener = new VcsLogListener() {
- @Override
- public void onChange(@NotNull VcsLogDataPack dataPack, boolean refreshHappened) {
- if (myTask == null) { // no task in progress => not interested in refresh events
- return;
- }
-
- if (refreshHappened) {
- // collect data
- String comparedBranch = myTask.myComparedBranch;
- Map<GitRepository, GitBranch> repositoriesWithCurrentBranches = myTask.myRepositoriesWithCurrentBranches;
- VcsLogDataProvider provider = myTask.myProvider;
-
- stopTask();
-
- // highlight again
- Map<GitRepository, GitBranch> repositories = getRepositories(myUi.getDataPack().getLogProviders(), comparedBranch);
- if (repositories.equals(repositoriesWithCurrentBranches)) { // but not if current branch changed
- highlightInBackground(comparedBranch, provider);
- }
- }
- else {
- VcsLogBranchFilter branchFilter = myUi.getFilterUi().getFilters().getBranchFilter();
- if (branchFilter == null || !myTask.myComparedBranch.equals(VcsLogUtil.getSingleFilteredBranch(branchFilter, myUi.getDataPack().getRefs()))) {
- stopAndUnhighlight();
- }
- }
- }
- };
- myUi.addLogListener(myLogListener);
}
public void highlightInBackground(@NotNull String branchToCompare, @NotNull VcsLogDataProvider dataProvider) {
return;
}
- myTask = new MyTask(myProject, myUi, repositories, dataProvider, branchToCompare);
+ myTask = new MyTask(myProject, repositories, dataProvider, branchToCompare);
myTask.queue();
}
}
private void removeHighlighting() {
- if (myHighlighter != null) {
- myUi.removeHighlighter(myHighlighter);
- }
+ ApplicationManager.getApplication().assertIsDispatchThread();
+ myNonPickedCommits = null;
}
@Override
public void dispose() {
stopAndUnhighlight();
- myUi.removeLogListener(myLogListener);
}
public boolean hasHighlightingOrInProgress() {
return myTask != null;
}
+ public static DeepComparator getInstance(@NotNull Project project, @NotNull VcsLogUi logUi) {
+ return ServiceManager.getService(project, DeepComparatorHolder.class).getInstance(logUi);
+ }
+
+ @NotNull
+ @Override
+ public VcsLogHighlighter.VcsCommitStyle getStyle(@NotNull VcsShortCommitDetails commitDetails, boolean isSelected) {
+ if (myNonPickedCommits == null) return VcsCommitStyle.DEFAULT;
+ return VcsCommitStyleFactory.foreground(!myNonPickedCommits.contains(new CommitId(commitDetails.getId(), commitDetails.getRoot()))
+ ? MergeCommitsHighlighter.MERGE_COMMIT_FOREGROUND
+ : null);
+ }
+
+ @Override
+ public void update(@NotNull VcsLogDataPack dataPack, boolean refreshHappened) {
+ if (myTask == null) { // no task in progress => not interested in refresh events
+ return;
+ }
+
+ if (refreshHappened) {
+ // collect data
+ String comparedBranch = myTask.myComparedBranch;
+ Map<GitRepository, GitBranch> repositoriesWithCurrentBranches = myTask.myRepositoriesWithCurrentBranches;
+ VcsLogDataProvider provider = myTask.myProvider;
+
+ stopTask();
+
+ // highlight again
+ Map<GitRepository, GitBranch> repositories = getRepositories(dataPack.getLogProviders(), comparedBranch);
+ if (repositories.equals(repositoriesWithCurrentBranches)) { // but not if current branch changed
+ highlightInBackground(comparedBranch, provider);
+ }
+ }
+ else {
+ VcsLogBranchFilter branchFilter = dataPack.getFilters().getBranchFilter();
+ if (branchFilter == null || !myTask.myComparedBranch.equals(VcsLogUtil.getSingleFilteredBranch(branchFilter, dataPack.getRefs()))) {
+ stopAndUnhighlight();
+ }
+ }
+ }
+
+ public static class Factory implements VcsLogHighlighterFactory {
+ @NotNull private static final String ID = "CHERRY_PICKED_COMMITS";
+
+ @NotNull
+ @Override
+ public VcsLogHighlighter createHighlighter(@NotNull VcsLogDataHolder logDataHolder, @NotNull VcsLogUi logUi) {
+ return getInstance(logDataHolder.getProject(), logUi);
+ }
+
+ @NotNull
+ @Override
+ public String getId() {
+ return ID;
+ }
+
+ @NotNull
+ @Override
+ public String getTitle() {
+ return "Cherry Picked Commits";
+ }
+
+ @Override
+ public boolean showMenuItem() {
+ return false;
+ }
+ }
+
private class MyTask extends Task.Backgroundable {
@NotNull private final Project myProject;
- @NotNull private final VcsLogUi myUi;
@NotNull private final Map<GitRepository, GitBranch> myRepositoriesWithCurrentBranches;
@NotNull private final VcsLogDataProvider myProvider;
@NotNull private final String myComparedBranch;
- @NotNull private final TIntHashSet myNonPickedCommits = new TIntHashSet();
+ @NotNull private final Set<CommitId> myCollectedNonPickedCommits = ContainerUtil.newHashSet();
@Nullable private VcsException myException;
private boolean myCancelled;
public MyTask(@NotNull Project project,
- @NotNull VcsLogUi ui,
@NotNull Map<GitRepository, GitBranch> repositoriesWithCurrentBranches,
@NotNull VcsLogDataProvider dataProvider,
@NotNull String branchToCompare) {
super(project, "Comparing Branches...");
myProject = project;
- myUi = ui;
myRepositoriesWithCurrentBranches = repositoriesWithCurrentBranches;
myProvider = dataProvider;
myComparedBranch = branchToCompare;
for (Map.Entry<GitRepository, GitBranch> entry : myRepositoriesWithCurrentBranches.entrySet()) {
GitRepository repo = entry.getKey();
GitBranch currentBranch = entry.getValue();
- myNonPickedCommits
- .addAll(getNonPickedCommitsFromGit(myProject, repo.getRoot(), myProvider, currentBranch.getName(), myComparedBranch).toArray());
+ myCollectedNonPickedCommits
+ .addAll(getNonPickedCommitsFromGit(myProject, repo.getRoot(), currentBranch.getName(), myComparedBranch));
}
}
catch (VcsException e) {
VcsNotifier.getInstance(myProject).notifyError("Couldn't compare with branch " + myComparedBranch, myException.getMessage());
return;
}
-
- myHighlighter = new VcsLogHighlighter() {
- @NotNull
- @Override
- public VcsCommitStyle getStyle(int commitIndex, boolean isSelected) {
- return VcsCommitStyleFactory
- .foreground(!myNonPickedCommits.contains(commitIndex) ? MergeCommitsHighlighter.MERGE_COMMIT_FOREGROUND : null);
- }
- };
- myUi.addHighlighter(myHighlighter);
+ myNonPickedCommits = myCollectedNonPickedCommits;
}
public void cancel() {
}
@NotNull
- private TIntHashSet getNonPickedCommitsFromGit(@NotNull Project project,
- @NotNull final VirtualFile root,
- @NotNull final VcsLogDataProvider dataProvider,
- @NotNull String currentBranch,
- @NotNull String comparedBranch) throws VcsException {
+ private Set<CommitId> getNonPickedCommitsFromGit(@NotNull Project project,
+ @NotNull final VirtualFile root,
+ @NotNull String currentBranch,
+ @NotNull String comparedBranch) throws VcsException {
GitLineHandler handler = new GitLineHandler(project, root, GitCommand.CHERRY);
handler.addParameters(currentBranch, comparedBranch); // upstream - current branch; head - compared branch
- final TIntHashSet pickedCommits = new TIntHashSet();
+ final Set<CommitId> pickedCommits = ContainerUtil.newHashSet();
handler.addLineListener(new GitLineHandlerAdapter() {
@Override
public void onLineAvailable(String line, Key outputType) {
line = line.substring(0, firstSpace); // safety-check: take just the first word for sure
}
Hash hash = HashImpl.build(line);
- pickedCommits.add(dataProvider.getCommitIndex(hash, root));
+ pickedCommits.add(new CommitId(hash, root));
}
catch (Exception e) {
LOG.error("Couldn't parse line [" + line + "]");
}
}
-
-}
+}
\ No newline at end of file
+/*
+ * Copyright 2000-2016 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package org.jetbrains.plugins.groovy.mvc;
import com.intellij.openapi.actionSystem.AnActionEvent;
Pair<MvcFramework, Module> pair = MvcActionBase.guessFramework(e);
- if (pair != null) {
+ if (pair != null && pair.first.showActionGroup()) {
presentation.setVisible(true);
presentation.setText(pair.getFirst().getDisplayName());
presentation.setIcon(pair.getFirst().getIcon());
}
return null;
}
+
+ public boolean showActionGroup() {
+ return true;
+ }
}
/*
- * Copyright 2000-2014 JetBrains s.r.o.
+ * Copyright 2000-2016 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.
import com.intellij.codeInsight.lookup.TailTypeDecorator;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.module.Module;
-import com.intellij.openapi.util.Key;
-import com.intellij.openapi.util.UserDataHolderEx;
+import com.intellij.openapi.util.NotNullLazyValue;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.JavaPsiFacade;