Merge remote-tracking branch 'origin/master'

This commit is contained in:
Alexander Lobas
2012-03-28 19:59:38 +04:00
160 changed files with 1242 additions and 624 deletions
@@ -43,7 +43,7 @@ public abstract class BaseParseTestcase extends UsefulTestCase{
protected void setUp() throws Exception {
super.setUp();
final IdeaTestFixtureFactory fixtureFactory = IdeaTestFixtureFactory.getFixtureFactory();
final TestFixtureBuilder<IdeaProjectTestFixture> builder = fixtureFactory.createFixtureBuilder();
final TestFixtureBuilder<IdeaProjectTestFixture> builder = fixtureFactory.createFixtureBuilder(getName());
myFixture = fixtureFactory.createCodeInsightFixture(builder.getFixture());
myFixture.setTestDataPath(getTestDataPath());
@@ -27,6 +27,7 @@ import javax.tools.*;
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.lang.reflect.Field;
import java.net.URI;
import java.util.List;
import java.util.concurrent.BlockingQueue;
@@ -145,6 +146,18 @@ class CompAPIDriver {
assert !processing;
//assert myCompilationResults.isEmpty() : myCompilationResults;
myCompilationResults.clear();
cleanupInternalFields();
}
private static void cleanupInternalFields() {
try {
Field freelist = Class.forName("com.sun.tools.javac.util.SharedNameTable").getDeclaredField("freelist");
freelist.setAccessible(true);
freelist.set(null, com.sun.tools.javac.util.List.nil());
}
catch (Exception ignored) {
}
}
public void offerClassFile(URI uri, byte[] bytes) {
@@ -80,6 +80,7 @@ public class PackagingElementNode<E extends PackagingElement<?>> extends Artifac
return myPackagingElements.size() == 1 ? myPackagingElements.get(0) : null;
}
@NotNull
@Override
public Object[] getEqualityObjects() {
return ArrayUtil.toObjectArray(myPackagingElements);
@@ -20,6 +20,7 @@ import com.intellij.openapi.roots.ui.configuration.artifacts.ArtifactEditorEx;
import com.intellij.packaging.ui.ArtifactEditorContext;
import com.intellij.packaging.ui.PackagingSourceItem;
import com.intellij.ui.treeStructure.SimpleTree;
import org.jetbrains.annotations.NotNull;
import java.awt.event.InputEvent;
import java.util.Collections;
@@ -35,6 +36,7 @@ public class SourceItemNode extends SourceItemNodeBase {
mySourceItem = sourceItem;
}
@NotNull
@Override
public Object[] getEqualityObjects() {
return new Object[]{mySourceItem};
@@ -35,6 +35,7 @@ public class SourceItemsTreeRoot extends SourceItemNodeBase {
return null;
}
@NotNull
@Override
public Object[] getEqualityObjects() {
return new Object[]{"root"};
@@ -290,6 +290,7 @@ public class ProjectStructureDaemonAnalyzer implements Disposable {
return myElement.equals(other.myElement) && (!other.myCheck || myCheck) && (!other.myCollectUsages || myCollectUsages);
}
@NotNull
@Override
public Object[] getEqualityObjects() {
return myEqualityObjects;
@@ -269,6 +269,7 @@ public abstract class ChooseLibrariesDialogBase extends DialogWrapper {
return 0;
}
@NotNull
@Override
public Object[] getEqualityObjects() {
return new Object[] {myElement};
@@ -66,7 +66,7 @@ public class SuppressAllForClassFix extends SuppressFix {
}
@Override
public void invoke(final Project project, final Editor editor, final PsiElement element) throws IncorrectOperationException {
public void invoke(@NotNull final Project project, final Editor editor, @NotNull final PsiElement element) throws IncorrectOperationException {
final PsiDocCommentOwner container = getContainer(element);
LOG.assertTrue(container != null);
if (!CodeInsightUtilBase.preparePsiElementForWrite(container)) return;
@@ -105,7 +105,7 @@ public class SuppressFix extends SuppressIntentionAction {
}
@Override
public void invoke(final Project project, final Editor editor, final PsiElement element) throws IncorrectOperationException {
public void invoke(@NotNull final Project project, final Editor editor, @NotNull final PsiElement element) throws IncorrectOperationException {
PsiDocCommentOwner container = getContainer(element);
assert container != null;
if (!CodeInsightUtilBase.preparePsiElementForWrite(container)) return;
@@ -66,7 +66,7 @@ public class SuppressParameterFix extends SuppressIntentionAction {
}
@Override
public void invoke(final Project project, final Editor editor, final PsiElement element) throws IncorrectOperationException {
public void invoke(@NotNull final Project project, final Editor editor, @NotNull final PsiElement element) throws IncorrectOperationException {
PsiParameter container = PsiTreeUtil.getParentOfType(element, PsiParameter.class, false);
assert container != null;
if (!CodeInsightUtilBase.preparePsiElementForWrite(container)) return;
@@ -26,6 +26,7 @@ import com.intellij.codeInsight.intention.QuickFixFactory;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.IndexNotReadyException;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.projectRoots.JavaSdkVersion;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.TextRange;
import com.intellij.pom.java.LanguageLevel;
@@ -505,7 +506,17 @@ public class GenericsHighlightUtil {
final PsiType retErasure1 = TypeConversionUtil.erasure(checkMethod.getReturnType());
final PsiType retErasure2 = TypeConversionUtil.erasure(superMethod.getReturnType());
if (!Comparing.equal(retErasure1, retErasure2) &&
boolean differentReturnTypeErasure = !Comparing.equal(retErasure1, retErasure2);
if (checkEqualsSuper && JavaSdkVersion.isAtLeast(checkMethod, JavaSdkVersion.JDK_1_7)) {
if (retErasure1 != null && retErasure2 != null) {
differentReturnTypeErasure = !TypeConversionUtil.isAssignable(retErasure1, retErasure2);
} else {
differentReturnTypeErasure = !(retErasure1 == null && retErasure2 == null);
}
}
if (differentReturnTypeErasure &&
!TypeConversionUtil.isVoidType(retErasure1) &&
!TypeConversionUtil.isVoidType(retErasure2) &&
!(checkEqualsSuper && Arrays.equals(superSignature.getParameterTypes(), signatureToCheck.getParameterTypes()))) {
@@ -83,7 +83,7 @@ public class DelegateWithDefaultParamValueIntentionAction extends PsiElementBase
}
@Override
public void invoke(Project project, Editor editor, PsiElement element) throws IncorrectOperationException {
public void invoke(@NotNull Project project, Editor editor, @NotNull PsiElement element) throws IncorrectOperationException {
final PsiParameter parameter = PsiTreeUtil.getParentOfType(element, PsiParameter.class);
final PsiMethod method = (PsiMethod)parameter.getDeclarationScope();
final PsiMethod prototype = (PsiMethod)method.getContainingClass().addBefore(generateMethodPrototype(method, parameter), method);
@@ -112,7 +112,9 @@ public class IterateOverIterableIntention implements IntentionAction {
element = ((PsiExpressionStatement)element).getExpression().getLastChild();
}
while ((element = PsiTreeUtil.getParentOfType(element, PsiExpression.class, true)) != null) {
if (element.getParent() instanceof PsiMethodCallExpression) continue;
final PsiElement parent = element.getParent();
if (parent instanceof PsiMethodCallExpression) continue;
if (!(parent instanceof PsiExpressionStatement)) return null;
final PsiType type = ((PsiExpression)element).getType();
if (type instanceof PsiArrayType || InheritanceUtil.isInheritor(type, CommonClassNames.JAVA_LANG_ITERABLE)) return (PsiExpression)element;
}
@@ -66,7 +66,7 @@ public class QualifyThisArgumentFix extends PsiElementBaseIntentionAction {
}
@Override
public void invoke(Project project, Editor editor, PsiElement element) throws IncorrectOperationException {
public void invoke(@NotNull Project project, Editor editor, @NotNull PsiElement element) throws IncorrectOperationException {
myExpression.replace(RefactoringUtil.createThisExpression(PsiManager.getInstance(project), myPsiClass));
}
@@ -46,7 +46,7 @@ public class InsertLiteralUnderscoresAction extends PsiElementBaseIntentionActio
}
@Override
public void invoke(final Project project, final Editor editor, final PsiElement element) throws IncorrectOperationException {
public void invoke(@NotNull final Project project, final Editor editor, @NotNull final PsiElement element) throws IncorrectOperationException {
final PsiLiteralExpression literalExpression = PsiTreeUtil.getParentOfType(element, PsiLiteralExpression.class, false);
if (literalExpression == null) return;
@@ -40,7 +40,7 @@ public class RemoveLiteralUnderscoresAction extends PsiElementBaseIntentionActio
}
@Override
public void invoke(final Project project, final Editor editor, final PsiElement element) throws IncorrectOperationException {
public void invoke(@NotNull final Project project, final Editor editor, @NotNull final PsiElement element) throws IncorrectOperationException {
final PsiLiteralExpression literalExpression = PsiTreeUtil.getParentOfType(element, PsiLiteralExpression.class, false);
if (literalExpression == null) return;
@@ -15,6 +15,7 @@
*/
package com.intellij.openapi.projectRoots.impl;
import com.intellij.execution.util.ExecUtil;
import com.intellij.openapi.application.PathManager;
import com.intellij.openapi.project.ProjectBundle;
import com.intellij.openapi.projectRoots.*;
@@ -154,33 +155,27 @@ public class JavaSdkImpl extends JavaSdk {
public String suggestHomePath() {
if (SystemInfo.isMac) {
if (new File("/usr/libexec/java_home").exists()) {
try {
final Process exec = Runtime.getRuntime().exec("/usr/libexec/java_home");
final BufferedReader input = new BufferedReader(new InputStreamReader(exec.getInputStream()));
try {
final String path = input.readLine();
if (new File(path).exists()) return path;
}
finally {
input.close();
}
final String path = ExecUtil.execAndReadLine("/usr/libexec/java_home");
if (path != null && new File(path).exists()) {
return path;
}
catch (IOException ignore) { }
}
return "/System/Library/Frameworks/JavaVM.framework/Versions/";
return "/System/Library/Frameworks/JavaVM.framework/Versions";
}
if (SystemInfo.isLinux) {
final String[] homes = {"/usr/java", "/opt/java", "/usr/lib/jvm/"};
final String[] homes = {"/usr/java", "/opt/java", "/usr/lib/jvm"};
for (String home : homes) {
if (new File(home).isDirectory()) {
return home;
}
}
}
if (SystemInfo.isSolaris) {
return "/usr/jdk/";
return "/usr/jdk";
}
return null;
}
@@ -192,10 +192,14 @@ public class PullUpDialog extends RefactoringDialog {
protected void doAction() {
if (!myCallback.checkConflicts(this)) return;
JavaRefactoringSettings.getInstance().PULL_UP_MEMBERS_JAVADOC = myJavaDocPanel.getPolicy();
StatisticsManager
.getInstance().incUseCount(new StatisticsInfo(PULL_UP_STATISTICS_KEY + myClass.getQualifiedName(), getSuperClass().getQualifiedName()));
final PsiClass superClass = getSuperClass();
String name = superClass.getQualifiedName();
if (name != null) {
StatisticsManager
.getInstance().incUseCount(new StatisticsInfo(PULL_UP_STATISTICS_KEY + myClass.getQualifiedName(), name));
}
invokeRefactoring(new PullUpHelper(myClass, getSuperClass(), getSelectedMemberInfos(),
invokeRefactoring(new PullUpHelper(myClass, superClass, getSelectedMemberInfos(),
new DocCommentPolicy(getJavaDocPolicy())));
close(OK_EXIT_CODE);
}
@@ -25,6 +25,7 @@
package com.intellij.refactoring.util;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.Comparing;
import com.intellij.psi.*;
import com.intellij.psi.search.PsiElementProcessor;
import com.intellij.psi.search.PsiElementProcessorAdapter;
@@ -129,7 +130,13 @@ public class RefactoringHierarchyUtil {
Collections.sort(
basesList, new Comparator<PsiClass>() {
public int compare(PsiClass c1, PsiClass c2) {
return c1.getQualifiedName().compareTo(c2.getQualifiedName());
final String fqn1 = c1.getQualifiedName();
final String fqn2 = c2.getQualifiedName();
if (fqn1 != null && fqn2 != null) return fqn1.compareTo(fqn2);
if (fqn1 == null && fqn2 == null) {
return Comparing.compare(c1.getName(), c2.getName());
}
return fqn1 == null ? 1 : -1;
}
}
);
@@ -144,6 +144,7 @@ public class SliceNode extends AbstractTreeNode<SliceUsage> implements Duplicate
@Override
protected PresentationData createPresentation() {
return new PresentationData(){
@NotNull
@Override
public Object[] getEqualityObjects() {
return ArrayUtil.append(super.getEqualityObjects(), changed);
@@ -79,7 +79,7 @@ public class MethodCandidatesProcessor extends MethodsProcessor{
protected boolean isShadowed(final PsiMethod candidate) {
if (myCurrentFileContext instanceof PsiImportStaticStatement) {
for (JavaResolveResult result : getResult()) {
for (JavaResolveResult result : getResults()) {
if (result.getElement() != candidate &&
result.isAccessible() &&
!(result.getCurrentFileResolveScope() instanceof PsiImportStaticStatement)) return true;
@@ -7,7 +7,7 @@ interface Matcher<T> {
}
interface ArgumentConstraintPhrases {
<T> T with(Matcher<T> matcher);
<error descr="'with(Matcher<T>)' clashes with 'with(Matcher<Boolean>)'; both methods have same erasure"><T> T with(Matcher<T> matcher)</error>;
boolean with(Matcher<Boolean> matcher);
byte with(Matcher<Byte> matcher);
short with(Matcher<Short> matcher);
@@ -19,7 +19,7 @@ interface ArgumentConstraintPhrases {
class ExpectationGroupBuilder implements ArgumentConstraintPhrases {
public <T> T with(final Matcher<T> matcher) {
<error descr="'with(Matcher<T>)' clashes with 'with(Matcher<Boolean>)'; both methods have same erasure">public <T> T with(final Matcher<T> matcher)</error> {
return null;
}
@@ -0,0 +1,48 @@
/** @noinspection UnusedDeclaration*/
interface Matcher<T> {
boolean matches(Object object);
void _dont_implement_Matcher___instead_extend_BaseMatcher_();
}
interface ArgumentConstraintPhrases {
<T> T with(Matcher<T> matcher);
boolean with(Matcher<Boolean> matcher);
byte with(Matcher<Byte> matcher);
int with(Matcher<Integer> matcher);
long with(Matcher<Long> matcher);
float with(Matcher<Float> matcher);
double with(Matcher<Double> matcher);
}
class ExpectationGroupBuilder implements ArgumentConstraintPhrases {
public <T> T with(final Matcher<T> matcher) {
return null;
}
public boolean with(final Matcher<Boolean> matcher) {
return false;
}
public byte with(final Matcher<Byte> matcher) {
return 0;
}
public int with(final Matcher<Integer> matcher) {
return 0;
}
public long with(final Matcher<Long> matcher) {
return 0;
}
public float with(final Matcher<Float> matcher) {
return 0;
}
public double with(final Matcher<Double> matcher) {
return 0;
}
}
@@ -0,0 +1,6 @@
// "Iterate" "false"
class Test {
void foo() {
final Annotation[] annotations = getClass().getAnnotat<caret>ions();
}
}
@@ -0,0 +1,14 @@
// "Pull method 'foo' to 'Foo' and make it abstract" "true"
public class Test {
void bar() {
abstract class Foo {
abstract void foo();
}
class FooImpl extends Foo {
@Override
void foo(){}
}
}
}
@@ -0,0 +1,12 @@
// "Pull method 'foo' to 'Foo' and make it abstract" "true"
public class Test {
void bar() {
class Foo {}
class FooImpl extends Foo {
@Overr<caret>ide
void foo(){}
}
}
}
@@ -0,0 +1,3 @@
public class ModuleSourceAsLibrarySource {
<ref>ModuleSourceAsLibrarySourceDep field;
}
@@ -0,0 +1 @@
public class ModuleSourceAsLibrarySourceDep {}
@@ -37,7 +37,7 @@ public class SuppressExternalTest extends UsefulTestCase {
public void setUp() throws Exception {
super.setUp();
final IdeaTestFixtureFactory fixtureFactory = IdeaTestFixtureFactory.getFixtureFactory();
final TestFixtureBuilder<IdeaProjectTestFixture> testFixtureBuilder = fixtureFactory.createFixtureBuilder();
final TestFixtureBuilder<IdeaProjectTestFixture> testFixtureBuilder = fixtureFactory.createFixtureBuilder(getName());
myFixture = JavaTestFixtureFactory.getFixtureFactory().createCodeInsightFixture(testFixtureBuilder.getFixture());
myFixture.setTestDataPath(PathManagerEx.getTestDataPath() + "/codeInsight/externalAnnotations");
final JavaModuleFixtureBuilder builder = testFixtureBuilder.addModule(JavaModuleFixtureBuilder.class);
@@ -4,6 +4,8 @@ import com.intellij.codeInspection.LocalInspectionTool;
import com.intellij.codeInspection.uncheckedWarnings.UncheckedWarningLocalInspection;
import com.intellij.codeInspection.unusedImport.UnusedImportLocalInspection;
import com.intellij.codeInspection.unusedSymbol.UnusedSymbolLocalInspection;
import com.intellij.openapi.projectRoots.Sdk;
import com.intellij.openapi.projectRoots.impl.JavaSdkImpl;
import com.intellij.openapi.roots.LanguageLevelProjectExtension;
import com.intellij.pom.java.LanguageLevel;
import com.intellij.psi.PsiClass;
@@ -34,6 +36,11 @@ public class GenericsHighlightingTest extends LightDaemonAnalyzerTestCase {
LanguageLevelProjectExtension.getInstance(getJavaFacade().getProject()).setLanguageLevel(level);
}
@Override
protected Sdk getProjectJDK() {
return getTestName(false).contains("Jdk14") ? JavaSdkImpl.getMockJdk14() : super.getProjectJDK();
}
public void testReferenceTypeParams() throws Exception { doTest(false); }
public void testOverridingMethods() throws Exception { doTest(false); }
public void testTypeParameterBoundsList() throws Exception { doTest(false); }
@@ -85,6 +92,7 @@ public class GenericsHighlightingTest extends LightDaemonAnalyzerTestCase {
public void testGenericExtendException() throws Exception { doTest(false); }
public void testSameErasureDifferentReturnTypes() throws Exception { doTest(false); }
public void testSameErasureDifferentReturnTypesJdk14() throws Exception { doTest(false); }
public void testDeepConflictingReturnTypes() throws Exception { doTest(false); }
public void testInheritFromTypeParameter() throws Exception { doTest(false); }
public void testAnnotationsAsPartOfModifierList() throws Exception { doTest(false); }
@@ -34,6 +34,10 @@ public class PullOverrideMethodUpFixTest extends LightQuickFixTestCase {
doSingleTest("4.java");
}
public void test6() throws Exception {
doSingleTest("6.java");
}
public void testRefactoringIntentionsAvailable() throws Exception {
doTestActionAvailable(5, "Pull members up");
doTestActionAvailable(5, "Extract interface");
@@ -8,6 +8,7 @@ import com.intellij.openapi.module.StdModuleTypes;
import com.intellij.openapi.roots.ContentEntry;
import com.intellij.openapi.roots.ModifiableRootModel;
import com.intellij.openapi.roots.ModuleRootManager;
import com.intellij.openapi.roots.OrderRootType;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.*;
@@ -155,6 +156,16 @@ public class ResolveClassTest extends ResolveTestCase {
assertNull(target);
}
public void testModuleSourceAsLibrarySource() throws Exception {
final PsiReference ref = configure();
final VirtualFile file = ref.getElement().getContainingFile().getVirtualFile();
assertNotNull(file);
createFile(myModule, file.getParent(), "ModuleSourceAsLibrarySourceDep.java", loadFile("class/ModuleSourceAsLibrarySourceDep.java"));
addLibraryToRoots(file.getParent(), OrderRootType.SOURCES);
assertInstanceOf(ref.resolve(), PsiClass.class);
}
public void testStaticImportInTheSameClass() throws Exception {
PsiReference ref = configure();
long start = System.currentTimeMillis();
@@ -15,7 +15,11 @@
*/
package com.intellij.openapi.projectRoots;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleUtil;
import com.intellij.openapi.roots.ModuleRootManager;
import com.intellij.pom.java.LanguageLevel;
import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.NotNull;
import java.util.Arrays;
@@ -70,4 +74,16 @@ public enum JavaSdkVersion {
String.format("Can't map Java SDK by description (%s). Available values: %s", description, Arrays.toString(values()))
);
}
public static boolean isAtLeast(PsiElement element, JavaSdkVersion minVersion) {
final Module module = ModuleUtil.findModuleForPsiElement(element);
if (module != null) {
final Sdk sdk = ModuleRootManager.getInstance(module).getSdk();
if (sdk != null && sdk.getSdkType() instanceof JavaSdk) {
final JavaSdkVersion version = JavaSdk.getInstance().getVersion(sdk);
return version != null && version.isAtLeast(minVersion);
}
}
return false;
}
}
@@ -216,7 +216,7 @@ public abstract class PsiTestCase extends ModuleTestCase {
addLibraryToRoots(myModule, jarFile, rootType);
}
protected static void addLibraryToRoots(final Module module, final VirtualFile jarFile, final OrderRootType rootType) {
protected static void addLibraryToRoots(final Module module, final VirtualFile root, final OrderRootType rootType) {
ApplicationManager.getApplication().runWriteAction(new Runnable() {
@Override
public void run() {
@@ -224,7 +224,7 @@ public abstract class PsiTestCase extends ModuleTestCase {
final ModifiableRootModel rootModel = manager.getModifiableModel();
final Library jarLibrary = rootModel.getModuleLibraryTable().createLibrary();
final Library.ModifiableModel libraryModel = jarLibrary.getModifiableModel();
libraryModel.addRoot(jarFile, rootType);
libraryModel.addRoot(root, rootType);
libraryModel.commit();
rootModel.commit();
}
@@ -46,7 +46,8 @@ public interface PsiElement extends UserDataHolder, Iconable {
* Returns the project to which the PSI element belongs.
*
* @return the project instance.
* @throws PsiInvalidElementAccessException if this element is invalid
* @throws PsiInvalidElementAccessException
* if this element is invalid
*/
@NotNull
Project getProject() throws PsiInvalidElementAccessException;
@@ -56,7 +57,8 @@ public interface PsiElement extends UserDataHolder, Iconable {
*
* @return the language instance.
*/
@NotNull Language getLanguage();
@NotNull
Language getLanguage();
/**
* Returns the PSI manager for the project to which the PSI element belongs.
@@ -71,7 +73,8 @@ public interface PsiElement extends UserDataHolder, Iconable {
*
* @return the array of child elements.
*/
@NotNull PsiElement[] getChildren();
@NotNull
PsiElement[] getChildren();
/**
* Returns the parent of the PSI element.
@@ -85,34 +88,40 @@ public interface PsiElement extends UserDataHolder, Iconable {
*
* @return the first child, or null if the element has no children.
*/
@Nullable PsiElement getFirstChild();
@Nullable
PsiElement getFirstChild();
/**
* Returns the last child of the PSI element.
*
* @return the last child, or null if the element has no children.
*/
@Nullable PsiElement getLastChild();
@Nullable
PsiElement getLastChild();
/**
* Returns the next sibling of the PSI element.
*
* @return the next sibling, or null if the node is the last in the list of siblings.
*/
@Nullable PsiElement getNextSibling();
@Nullable
PsiElement getNextSibling();
/**
* Returns the previous sibling of the PSI element.
*
* @return the previous sibling, or null if the node is the first in the list of siblings.
*/
@Nullable PsiElement getPrevSibling();
@Nullable
PsiElement getPrevSibling();
/**
* Returns the file containing the PSI element.
* @throws PsiInvalidElementAccessException if this element is invalid
*
* @return the file instance, or null if the PSI element is not contained in a file (for example,
* the element represents a package or directory).
* the element represents a package or directory).
* @throws PsiInvalidElementAccessException
* if this element is invalid
*/
PsiFile getContainingFile() throws PsiInvalidElementAccessException;
@@ -178,7 +187,8 @@ public interface PsiElement extends UserDataHolder, Iconable {
*
* @return the element text as a character array.
*/
@NotNull char[] textToCharArray();
@NotNull
char[] textToCharArray();
/**
* Returns the PSI element which should be used as a navigation target
@@ -246,7 +256,7 @@ public interface PsiElement extends UserDataHolder, Iconable {
/**
* Creates a copy of the file containing the PSI element and returns the corresponding
* element in the created copy. Resolve operations performed on elements in the copy
* of the file will resolve to elements in the copy, not in the original file.
* of the file will resolve to elements in the copy, not in the original file.
*
* @return the element in the file copy corresponding to this element.
*/
@@ -304,9 +314,9 @@ public interface PsiElement extends UserDataHolder, Iconable {
/**
* Adds a range of elements as children to this PSI element, before the specified anchor element.
*
* @param first the first child element to add.
* @param last the last child element to add (must have the same parent as <code>first</code>)
* @param anchor the anchor before which the child element is inserted (must be a child of this PSI element)
* @param first the first child element to add.
* @param last the last child element to add (must have the same parent as <code>first</code>)
* @param anchor the anchor before which the child element is inserted (must be a child of this PSI element)
* @return the first child element which was actually added (either <code>first</code> or its copy).
* @throws IncorrectOperationException if the modification is not supported or not possible for some reason.
*/
@@ -315,9 +325,9 @@ public interface PsiElement extends UserDataHolder, Iconable {
/**
* Adds a range of elements as children to this PSI element, after the specified anchor element.
*
* @param first the first child element to add.
* @param last the last child element to add (must have the same parent as <code>first</code>)
* @param anchor the anchor after which the child element is inserted (must be a child of this PSI element)
* @param first the first child element to add.
* @param last the last child element to add (must have the same parent as <code>first</code>)
* @param anchor the anchor after which the child element is inserted (must be a child of this PSI element)
* @return the first child element which was actually added (either <code>first</code> or its copy).
* @throws IncorrectOperationException if the modification is not supported or not possible for some reason.
*/
@@ -327,7 +337,7 @@ public interface PsiElement extends UserDataHolder, Iconable {
* Deletes this PSI element from the tree.
*
* @throws IncorrectOperationException if the modification is not supported
* or not possible for some reason (for example, the file containing the element is read-only).
* or not possible for some reason (for example, the file containing the element is read-only).
*/
void delete() throws IncorrectOperationException;
@@ -382,7 +392,7 @@ public interface PsiElement extends UserDataHolder, Iconable {
* associated reference.
*
* @return the reference instance, or null if the PSI element does not have any
* associated references.
* associated references.
*/
@Nullable
PsiReference getReference();
@@ -394,15 +404,16 @@ public interface PsiElement extends UserDataHolder, Iconable {
* contains only one text fragment which acts as a reference but the reference has
* multiple possible targets, {@link PsiPolyVariantReference} should be used instead
* of returning multiple references.
*
* <p/>
* Actually, it's preferable to call {@link com.intellij.psi.PsiReferenceService#getReferences} instead
* as it allows adding references by plugins when the element implements {@link com.intellij.psi.ContributedReferenceHost}.
*
* @return the array of references, or an empty array if the element has no associated
* references.
* references.
* @see com.intellij.psi.PsiReferenceService#getReferences
*/
@NotNull PsiReference[] getReferences();
@NotNull
PsiReference[] getReferences();
/**
* Returns a copyable user data object attached to this element.
@@ -411,13 +422,14 @@ public interface PsiElement extends UserDataHolder, Iconable {
* @return the user data object, or null if no such object is found in the current element.
* @see #putCopyableUserData(com.intellij.openapi.util.Key, Object)
*/
@Nullable <T> T getCopyableUserData(Key<T> key);
@Nullable
<T> T getCopyableUserData(Key<T> key);
/**
* Attaches a copyable user data object to this element. Copyable user data objects are copied
* when the PSI elements are copied.
*
* @param key the key for accessing the user data object.
* @param key the key for accessing the user data object.
* @param value the user data object to attach.
* @see #getCopyableUserData(com.intellij.openapi.util.Key)
*/
@@ -427,12 +439,12 @@ public interface PsiElement extends UserDataHolder, Iconable {
* Passes the declarations contained in this PSI element and its children
* for processing to the specified scope processor.
*
* @param processor the processor receiving the declarations.
* @param processor the processor receiving the declarations.
* @param state
* @param lastParent the child of this element has been processed during the previous
* step of the tree up walk (declarations under this element do not need
* to be processed again)
* @param place the original element from which the tree up walk was initiated.
* @param lastParent the child of this element has been processed during the previous
* step of the tree up walk (declarations under this element do not need
* to be processed again)
* @param place the original element from which the tree up walk was initiated.
* @return true if the declaration processing should continue or false if it should be stopped.
*/
boolean processDeclarations(@NotNull PsiScopeProcessor processor,
@@ -444,11 +456,12 @@ public interface PsiElement extends UserDataHolder, Iconable {
* Returns the element which should be used as the parent of this element in a tree up
* walk during a resolve operation. For most elements, this returns <code>getParent()</code>,
* but the context can be overridden for some elements like code fragments (see
* {@link PsiElementFactory#createCodeBlockCodeFragment(String, PsiElement, boolean)}).
* {@link PsiElementFactory#createCodeBlockCodeFragment(String, PsiElement, boolean)}).
*
* @return the resolve context element.
*/
@Nullable PsiElement getContext();
@Nullable
PsiElement getContext();
/**
* Checks if an actual source or class file corresponds to the element. Non-physical elements include,
@@ -465,7 +478,8 @@ public interface PsiElement extends UserDataHolder, Iconable {
*
* @return the resolve scope instance.
*/
@NotNull GlobalSearchScope getResolveScope();
@NotNull
GlobalSearchScope getResolveScope();
/**
* Returns the scope in which references to this element are searched.
@@ -473,7 +487,8 @@ public interface PsiElement extends UserDataHolder, Iconable {
* @return the search scope instance.
* @see {@link com.intellij.psi.search.PsiSearchHelper#getUseScope(PsiElement)}
*/
@NotNull SearchScope getUseScope();
@NotNull
SearchScope getUseScope();
/**
* Returns the AST node corresponding to the element.
@@ -485,7 +500,8 @@ public interface PsiElement extends UserDataHolder, Iconable {
/**
* toString() should never be presented to the user.
*/
@NonNls String toString();
@NonNls
String toString();
boolean isEquivalentTo(PsiElement another);
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 978 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

@@ -51,7 +51,8 @@ public interface IntentionAction {
* @return the intention family ID.
* @see IntentionManager#registerIntentionAndMetaData(com.intellij.codeInsight.intention.IntentionAction, java.lang.String...)
*/
@NotNull String getFamilyName();
@NotNull
String getFamilyName();
/**
* Checks whether this intention is available at a caret offset in file.
@@ -43,16 +43,17 @@ public abstract class PsiElementBaseIntentionAction extends BaseIntentionAction
throw new IncorrectOperationException();
}
@Override
public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) {
final PsiElement element = getElement(editor, file);
return element != null && isAvailable(project, editor, element);
}
@Nullable
protected static PsiElement getElement(Editor editor, PsiFile file) {
protected static PsiElement getElement(Editor editor, @NotNull PsiFile file) {
if (!file.getManager().isInProject(file)) return null;
final CaretModel caretModel = editor.getCaretModel();
final int position = caretModel.getOffset();
CaretModel caretModel = editor.getCaretModel();
int position = caretModel.getOffset();
return file.findElementAt(position);
}
@@ -25,6 +25,7 @@ import org.jetbrains.annotations.NotNull;
public abstract class BaseIntentionAction implements IntentionAction {
private String myText = "";
@Override
@NotNull
public String getText() {
return myText;
@@ -34,6 +35,7 @@ public abstract class BaseIntentionAction implements IntentionAction {
myText = text;
}
@Override
public boolean startInWriteAction() {
return true;
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
* Copyright 2000-2012 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.
@@ -40,7 +40,7 @@ public abstract class SdkType {
private final String myName;
/**
* @return path to set up filechooser to or null if not applicable
* @return path to set up file chooser to or null if not applicable
*/
@Nullable
public abstract String suggestHomePath();
@@ -111,8 +111,9 @@ public class DaemonTooltipRendererProvider implements ErrorStripTooltipRendererP
return new MyRenderer(text, width, new Object[] {text});
}
@NotNull
@Override
public TrafficTooltipRenderer createTrafficTooltipRenderer(Runnable onHide, Editor editor) {
public TrafficTooltipRenderer createTrafficTooltipRenderer(@NotNull Runnable onHide, @NotNull Editor editor) {
return new TrafficTooltipRendererImpl(onHide, editor);
}
@@ -16,6 +16,7 @@
package com.intellij.codeInsight.daemon.impl;
import com.google.common.primitives.Ints;
import com.intellij.codeHighlighting.HighlightDisplayLevel;
import com.intellij.lang.annotation.HighlightSeverity;
import com.intellij.openapi.editor.colors.EditorColorsManager;
@@ -265,7 +266,7 @@ public class SeverityRegistrar implements JDOMExternalizable, Comparator<Highlig
}
public int getSeverityMaxIndex() {
return getOrder().size();
return Ints.max(getOrder().getValues());
}
public HighlightSeverity getSeverity(@NotNull String name) {
@@ -345,9 +346,7 @@ public class SeverityRegistrar implements JDOMExternalizable, Comparator<Highlig
}
public int getSeverityIdx(@NotNull HighlightSeverity severity) {
final OrderMap order = getOrder();
if (!order.contains(severity)) return -1;
return order.get(severity);
return getOrder().getOrder(severity, -1);
}
public boolean isDefaultSeverity(@NotNull HighlightSeverity severity) {
@@ -24,6 +24,7 @@ import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiCompiledElement;
import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.PsiFile;
import com.intellij.psi.util.PsiUtilCore;
import com.intellij.util.ArrayUtil;
import gnu.trove.*;
import org.jetbrains.annotations.NotNull;
@@ -111,7 +112,8 @@ public class TextEditorHighlightingPassRegistrarImpl extends TextEditorHighlight
if (!(fileFromDoc instanceof PsiCompiledElement)) {
assert fileFromDoc == psiFile : "Files are different: " + psiFile + ";" + fileFromDoc;
Document documentFromFile = documentManager.getDocument(psiFile);
assert documentFromFile == document : "Documents are different: " + document + ";" + documentFromFile;
assert documentFromFile == document : "Documents are different. Doc: " + document + "; Doc from file: " + documentFromFile +"; File: "+psiFile +"; Virtual file: "+
PsiUtilCore.getVirtualFile(psiFile);
}
final TIntObjectHashMap<TextEditorHighlightingPass> id2Pass = new TIntObjectHashMap<TextEditorHighlightingPass>();
final TIntArrayList passesRefusedToCreate = new TIntArrayList();
@@ -108,7 +108,7 @@ public class TrafficLightRenderer implements ErrorStripeRenderer, Disposable {
private void refresh() {
int maxIndex = mySeverityRegistrar.getSeverityMaxIndex();
if (errorCount != null && maxIndex == errorCount.length) return;
int[] newErrors = new int[maxIndex];
int[] newErrors = new int[maxIndex+1];
if (errorCount != null) {
System.arraycopy(errorCount, 0, newErrors, 0, Math.min(errorCount.length, newErrors.length));
}
@@ -140,7 +140,7 @@ public class TrafficLightRenderer implements ErrorStripeRenderer, Disposable {
HighlightSeverity infoSeverity = info.getSeverity();
final int severityIdx = mySeverityRegistrar.getSeverityIdx(infoSeverity);
if (severityIdx != -1) {
errorCount[severityIdx]+= delta;
errorCount[severityIdx] += delta;
}
}
@@ -718,6 +718,7 @@ public class DocumentationManager {
myUpdateDocAlarm.addRequest(new Runnable() {
public void run() {
if (myProject.isDisposed()) return;
final Throwable[] ex = new Throwable[1];
String text = null;
try {
@@ -1,14 +1,9 @@
package com.intellij.find.editorHeaderActions;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.ui.popup.JBPopup;
import com.intellij.openapi.ui.popup.JBPopupFactory;
import com.intellij.openapi.ui.popup.PopupChooserBuilder;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.vfs.ReadonlyStatusHandler;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.PsiFile;
import javax.swing.*;
import javax.swing.text.JTextComponent;
@@ -42,7 +37,7 @@ public class Utils {
.setRequestFocus(true).setItemChoosenCallback(callback).createPopup();
if (ad != null) {
popup.setAdText(ad, SwingUtilities.LEFT);
popup.setAdText(ad, SwingConstants.LEFT);
}
if (toolbarComponent != null) {
@@ -72,20 +67,4 @@ public class Utils {
}
}
}
public static boolean ensureOkToWrite(Editor e) {
final PsiFile psiFile = PsiDocumentManager.getInstance(e.getProject()).getPsiFile(e.getDocument());
boolean okWritable;
if (psiFile != null) {
final VirtualFile virtualFile = psiFile.getVirtualFile();
if (virtualFile != null) {
okWritable = ReadonlyStatusHandler.ensureFilesWritable(e.getProject(), virtualFile);
} else {
okWritable = psiFile.isWritable();
}
} else {
okWritable = e.getDocument().isWritable();
}
return okWritable;
}
}
@@ -3,13 +3,13 @@ package com.intellij.find.impl.livePreview;
import com.intellij.find.FindManager;
import com.intellij.find.FindModel;
import com.intellij.find.FindUtil;
import com.intellij.find.editorHeaderActions.Utils;
import com.intellij.find.impl.FindResultImpl;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.*;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.vfs.ReadonlyStatusHandler;
import com.intellij.util.Alarm;
import org.jetbrains.annotations.Nullable;
@@ -169,7 +169,7 @@ public class LivePreviewControllerBase implements LivePreview.Delegate, FindUtil
@Nullable
@Override
public TextRange performReplace(final LiveOccurrence occurrence, final String replacement, final Editor editor) {
if (myReplaceDenied || !Utils.ensureOkToWrite(editor)) return null;
if (myReplaceDenied || !ReadonlyStatusHandler.ensureDocumentWritable(editor.getProject(), editor.getDocument())) return null;
TextRange range = occurrence.getPrimaryRange();
FindModel findModel = mySearchResults.getFindModel();
TextRange result = null;
@@ -197,7 +197,7 @@ public class LivePreviewControllerBase implements LivePreview.Delegate, FindUtil
@Override
public void performReplaceAll(Editor e) {
if (!Utils.ensureOkToWrite(e)) return;
if (!ReadonlyStatusHandler.ensureDocumentWritable(e.getProject(), e.getDocument())) return;
if (mySearchResults.getFindModel() != null) {
final FindModel copy = new FindModel();
copy.copyFrom(mySearchResults.getFindModel());
@@ -26,6 +26,7 @@ import com.intellij.navigation.NavigationItem;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.RangeMarker;
import com.intellij.openapi.editor.ex.MarkupModelEx;
import com.intellij.openapi.editor.ex.RangeHighlighterEx;
import com.intellij.openapi.editor.impl.DocumentMarkupModel;
import com.intellij.openapi.editor.markup.GutterIconRenderer;
import com.intellij.openapi.editor.markup.HighlighterLayer;
@@ -41,6 +42,7 @@ import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiManager;
import com.intellij.ui.LightColors;
import com.intellij.util.PlatformIcons;
import com.intellij.util.Processor;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -52,45 +54,41 @@ public class Bookmark {
private final VirtualFile myFile;
private final OpenFileDescriptor myTarget;
private final RangeHighlighter myHighlighter;
private final Project myProject;
private String myDescription;
private char myMnemonic = 0;
public static final Font MNEMONIC_FONT = new Font("Monospaced", 0, 11);
public Bookmark(Project project, VirtualFile file, String description) {
this(project, file, -1, description);
}
public Bookmark(Project project, VirtualFile file, int line, String description) {
public Bookmark(@NotNull Project project, @NotNull VirtualFile file, int line, @NotNull String description) {
myFile = file;
myProject = project;
myDescription = description;
myTarget = new OpenFileDescriptor(project, file, line, -1, true);
Document document = FileDocumentManager.getInstance().getCachedDocument(getFile());
if (document != null) {
createHighlighter((MarkupModelEx)DocumentMarkupModel.forDocument(document, myProject, true));
}
}
public RangeHighlighter createHighlighter(@NotNull MarkupModelEx markup) {
final RangeHighlighter myHighlighter;
int line = getLine();
if (line >= 0) {
Document document = getDocument();
if (document == null) {
myHighlighter = null;
}
else {
MarkupModelEx markup = (MarkupModelEx)DocumentMarkupModel.forDocument(document, myProject, true);
myHighlighter = markup.addPersistentLineHighlighter(line, HighlighterLayer.ERROR + 1, null);
myHighlighter = markup.addPersistentLineHighlighter(line, HighlighterLayer.ERROR + 1, null);
if (myHighlighter != null) {
myHighlighter.setGutterIconRenderer(new MyGutterIconRenderer(this));
if (myHighlighter != null) {
myHighlighter.setGutterIconRenderer(new MyGutterIconRenderer());
myHighlighter.setErrorStripeMarkColor(Color.black);
myHighlighter.setErrorStripeTooltip(getBookmarkTooltip());
}
myHighlighter.setErrorStripeMarkColor(Color.black);
myHighlighter.setErrorStripeTooltip(getBookmarkTooltip());
}
}
else {
myHighlighter = null;
}
myTarget = new OpenFileDescriptor(project, file, line, -1, true);
return myHighlighter;
}
public Document getDocument() {
@@ -98,9 +96,28 @@ public class Bookmark {
}
public void release() {
if (myHighlighter != null) {
myHighlighter.dispose();
int line = getLine();
if (line < 0) {
return;
}
final Document document = getDocument();
if (document == null) return;
MarkupModelEx markup = (MarkupModelEx)DocumentMarkupModel.forDocument(document, myProject, true);
int startOffset = markup.getDocument().getLineStartOffset(line);
int endOffset = markup.getDocument().getLineEndOffset(line);
final RangeHighlighterEx[] found = new RangeHighlighterEx[1];
markup.processRangeHighlightersOverlappingWith(startOffset, endOffset, new Processor<RangeHighlighterEx>() {
@Override
public boolean process(RangeHighlighterEx highlighter) {
GutterIconRenderer renderer = highlighter.getGutterIconRenderer();
if (renderer instanceof MyGutterIconRenderer && ((MyGutterIconRenderer)renderer).myBookmark == Bookmark.this) {
found[0] = highlighter;
return false;
}
return true;
}
});
if (found[0] != null) found[0].dispose();
}
public Icon getIcon() {
@@ -123,25 +140,18 @@ public class Bookmark {
myMnemonic = Character.toUpperCase(mnemonic);
}
@NotNull
public VirtualFile getFile() {
return myFile;
}
@Nullable
public String getNotEmptyDescription() {
return isDescriptionEmpty() ? null : myDescription;
}
public boolean isDescriptionEmpty() {
return myDescription == null || myDescription.trim().length() == 0;
}
OpenFileDescriptor getTarget() {
return myTarget;
return StringUtil.isEmpty(myDescription) ? null : myDescription;
}
public boolean isValid() {
if (!getFile().isValid() || (myHighlighter != null && !myHighlighter.isValid())) {
if (!getFile().isValid()) {
return false;
}
@@ -156,8 +166,10 @@ public class Bookmark {
}
public int getLine() {
if (myHighlighter != null && myHighlighter.isValid()) {
return myHighlighter.getDocument().getLineNumber(myHighlighter.getStartOffset());
RangeMarker marker = myTarget.getRangeMarker();
if (marker != null && marker.isValid()) {
Document document = marker.getDocument();
return document.getLineNumber(marker.getStartOffset());
}
return myTarget.getLine();
}
@@ -169,7 +181,7 @@ public class Bookmark {
public String getQualifiedName() {
String presentableUrl = myFile.getPresentableUrl();
if (myFile.isDirectory() || myHighlighter == null) return presentableUrl;
if (myFile.isDirectory()) return presentableUrl;
PsiDocumentManager.getInstance(myProject).commitAllDocuments();
final PsiFile psiFile = PsiManager.getInstance(myProject).findFile(myFile);
@@ -188,8 +200,7 @@ public class Bookmark {
}
}
return IdeBundle
.message("bookmark.file.X.line.Y", presentableUrl, myHighlighter.getDocument().getLineNumber(myHighlighter.getStartOffset()) + 1);
return IdeBundle.message("bookmark.file.X.line.Y", presentableUrl, getLine() + 1);
}
private String getBookmarkTooltip() {
@@ -211,6 +222,7 @@ public class Bookmark {
myMnemonic = mnemonic;
}
@Override
public void paintIcon(Component c, Graphics g, int x, int y) {
g.setColor(LightColors.YELLOW);
g.fillRect(x, y, getIconWidth(), getIconHeight());
@@ -226,10 +238,12 @@ public class Bookmark {
g.setFont(oldFont);
}
@Override
public int getIconWidth() {
return 10;
}
@Override
public int getIconHeight() {
return 12;
}
@@ -245,14 +259,22 @@ public class Bookmark {
}
}
private class MyGutterIconRenderer extends GutterIconRenderer {
@NotNull
public Icon getIcon() {
return Bookmark.this.getIcon();
private static class MyGutterIconRenderer extends GutterIconRenderer {
private final Bookmark myBookmark;
public MyGutterIconRenderer(@NotNull Bookmark bookmark) {
myBookmark = bookmark;
}
@Override
@NotNull
public Icon getIcon() {
return myBookmark.getIcon();
}
@Override
public String getTooltipText() {
return getBookmarkTooltip();
return myBookmark.getBookmarkTooltip();
}
@Override
@@ -16,25 +16,32 @@
package com.intellij.ide.bookmarks;
import com.intellij.openapi.components.*;
import com.intellij.openapi.components.AbstractProjectComponent;
import com.intellij.openapi.components.PersistentStateComponent;
import com.intellij.openapi.components.State;
import com.intellij.openapi.components.Storage;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.EditorFactory;
import com.intellij.openapi.editor.event.*;
import com.intellij.openapi.editor.ex.MarkupModelEx;
import com.intellij.openapi.editor.impl.DocumentMarkupModel;
import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.project.DumbAwareRunnable;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.startup.StartupManager;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.VirtualFileManager;
import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.PsiFile;
import com.intellij.util.messages.MessageBus;
import com.intellij.util.ui.UIUtil;
import org.jdom.Element;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.awt.*;
import java.awt.event.InputEvent;
import java.util.*;
@@ -46,51 +53,54 @@ import java.util.List;
@Storage( file = "$WORKSPACE_FILE$")
}
)
public class BookmarkManager implements PersistentStateComponent<Element>, ProjectComponent {
public class BookmarkManager extends AbstractProjectComponent implements PersistentStateComponent<Element> {
private static final int MAX_AUTO_DESCRIPTION_SIZE = 50;
private final List<Bookmark> myBookmarks = new ArrayList<Bookmark>();
private final MyEditorMouseListener myEditorMouseListener = new MyEditorMouseListener();
private final List<Bookmark> myBookmarks = new ArrayList<Bookmark>();
private final Project myProject;
private final MessageBus myBus;
public static BookmarkManager getInstance(Project project) {
return project.getComponent(BookmarkManager.class);
}
public BookmarkManager(Project project, MessageBus bus) {
myProject = project;
public BookmarkManager(Project project, MessageBus bus, PsiDocumentManager documentManager) {
super(project);
myBus = bus;
EditorFactory.getInstance().getEventMulticaster().addDocumentListener(new MyDocumentListener(), myProject);
EditorEventMulticaster multicaster = EditorFactory.getInstance().getEventMulticaster();
multicaster.addDocumentListener(new MyDocumentListener(), myProject);
multicaster.addEditorMouseListener(new MyEditorMouseListener(), myProject);
documentManager.addListener(new PsiDocumentManager.Listener() {
@Override
public void documentCreated(@NotNull final Document document, PsiFile psiFile) {
final VirtualFile file = FileDocumentManager.getInstance().getFile(document);
if (file == null) return;
UIUtil.invokeLaterIfNeeded(new Runnable() {
@Override
public void run() {
if (myProject.isDisposed()) return;
for (Bookmark bookmark : myBookmarks) {
if (bookmark.getFile() == file) {
bookmark.createHighlighter((MarkupModelEx)DocumentMarkupModel.forDocument(document, myProject, true));
}
}
}
});
}
@Override
public void fileCreated(@NotNull PsiFile file, @NotNull Document document) {
}
});
}
public void projectOpened() {
EditorFactory.getInstance().getEventMulticaster().addEditorMouseListener(myEditorMouseListener, myProject);
}
@Override
public void projectClosed() {
EditorFactory.getInstance().getEventMulticaster().removeEditorMouseListener(myEditorMouseListener);
}
@Override
public void initComponent() {}
@Override
public void disposeComponent() {}
@NotNull
@Override
public String getComponentName() {
return "BookmarkManager";
}
public Project getProject() {
return myProject;
}
public void addEditorBookmark(Editor editor, int lineIndex) {
Document document = editor.getDocument();
PsiFile psiFile = PsiDocumentManager.getInstance(myProject).getPsiFile(document);
@@ -127,7 +137,7 @@ public class BookmarkManager implements PersistentStateComponent<Element>, Proje
if (file == null) return null;
if (findFileBookmark(file) != null) return null;
Bookmark b = new Bookmark(myProject, file, description);
Bookmark b = new Bookmark(myProject, file, -1, description);
myBookmarks.add(0, b);
myBus.syncPublisher(BookmarksListener.TOPIC).bookmarkAdded(b);
return b;
@@ -144,9 +154,9 @@ public class BookmarkManager implements PersistentStateComponent<Element>, Proje
@Nullable
public Bookmark findEditorBookmark(Document document, int lineIndex) {
public Bookmark findEditorBookmark(@NotNull Document document, int line) {
for (Bookmark bookmark : myBookmarks) {
if (bookmark.getDocument() == document && bookmark.getLine() == lineIndex) {
if (bookmark.getDocument() == document && bookmark.getLine() == line) {
return bookmark;
}
}
@@ -155,7 +165,7 @@ public class BookmarkManager implements PersistentStateComponent<Element>, Proje
}
@Nullable
public Bookmark findFileBookmark(VirtualFile file) {
public Bookmark findFileBookmark(@NotNull VirtualFile file) {
for (Bookmark bookmark : myBookmarks) {
if (bookmark.getFile() == file && bookmark.getLine() == -1) return bookmark;
}
@@ -180,20 +190,23 @@ public class BookmarkManager implements PersistentStateComponent<Element>, Proje
return false;
}
public void removeBookmark(Bookmark bookmark) {
public void removeBookmark(@NotNull Bookmark bookmark) {
myBookmarks.remove(bookmark);
bookmark.release();
myBus.syncPublisher(BookmarksListener.TOPIC).bookmarkRemoved(bookmark);
}
@Override
public Element getState() {
Element container = new Element("BookmarkManager");
writeExternal(container);
return container;
}
@Override
public void loadState(final Element state) {
StartupManager.getInstance(myProject).runWhenProjectIsInitialized(new DumbAwareRunnable() {
@Override
public void run() {
BookmarksListener publisher = myBus.syncPublisher(BookmarksListener.TOPIC);
for (Bookmark bookmark : myBookmarks) {
@@ -214,7 +227,7 @@ public class BookmarkManager implements PersistentStateComponent<Element>, Proje
if ("bookmark".equals(bookmarkElement.getName())) {
String url = bookmarkElement.getAttributeValue("url");
String line = bookmarkElement.getAttributeValue("line");
String description = bookmarkElement.getAttributeValue("description");
String description = StringUtil.notNullize(bookmarkElement.getAttributeValue("description"));
String mnemonic = bookmarkElement.getAttributeValue("mnemonic");
Bookmark b = null;
@@ -335,6 +348,7 @@ public class BookmarkManager implements PersistentStateComponent<Element>, Proje
Bookmark[] bookmarks = answer.toArray(new Bookmark[answer.size()]);
Arrays.sort(bookmarks, new Comparator<Bookmark>() {
@Override
public int compare(final Bookmark o1, final Bookmark o2) {
return o1.getLine() - o2.getLine();
}
@@ -342,7 +356,7 @@ public class BookmarkManager implements PersistentStateComponent<Element>, Proje
return bookmarks;
}
public void setMnemonic(Bookmark bookmark, char c) {
public void setMnemonic(@NotNull Bookmark bookmark, char c) {
final Bookmark old = findBookmarkForMnemonic(c);
if (old != null) removeBookmark(old);
@@ -350,13 +364,14 @@ public class BookmarkManager implements PersistentStateComponent<Element>, Proje
myBus.syncPublisher(BookmarksListener.TOPIC).bookmarkChanged(bookmark);
}
public void setDescription(Bookmark bookmark, String description) {
public void setDescription(@NotNull Bookmark bookmark, String description) {
bookmark.setDescription(description);
myBus.syncPublisher(BookmarksListener.TOPIC).bookmarkChanged(bookmark);
}
private class MyEditorMouseListener extends EditorMouseAdapter {
@Override
public void mouseClicked(final EditorMouseEvent e) {
if (e.getArea() != EditorMouseEventArea.LINE_MARKERS_AREA) return;
if (e.getMouseEvent().isPopupTrigger()) return;
@@ -20,12 +20,13 @@
package com.intellij.ide.bookmarks;
import com.intellij.util.messages.Topic;
import org.jetbrains.annotations.NotNull;
public interface BookmarksListener {
Topic<BookmarksListener> TOPIC = Topic.create("Bookmarks", BookmarksListener.class);
void bookmarkAdded(Bookmark b);
void bookmarkRemoved(Bookmark b);
void bookmarkAdded(@NotNull Bookmark b);
void bookmarkRemoved(@NotNull Bookmark b);
void bookmarkChanged(Bookmark b);
void bookmarkChanged(@NotNull Bookmark b);
}
@@ -64,8 +64,10 @@ public class ProjectTreeBuilder extends BaseProjectTreeBuilder {
myPsiTreeChangeListener = createPsiTreeChangeListener(myProject);
connection.subscribe(ProjectTopics.PROJECT_ROOTS, new ModuleRootListener() {
@Override
public void beforeRootsChange(ModuleRootEvent event) {
}
@Override
public void rootsChanged(ModuleRootEvent event) {
queueUpdate();
}
@@ -87,6 +89,7 @@ public class ProjectTreeBuilder extends BaseProjectTreeBuilder {
initRootNode();
}
@Override
public final void dispose() {
super.dispose();
PsiManager.getInstance(myProject).removePsiTreeChangeListener(myPsiTreeChangeListener);
@@ -110,29 +113,35 @@ public class ProjectTreeBuilder extends BaseProjectTreeBuilder {
super(project);
}
@Override
protected DefaultMutableTreeNode getRootNode(){
return ProjectTreeBuilder.this.getRootNode();
}
@Override
protected AbstractTreeUpdater getUpdater() {
return ProjectTreeBuilder.this.getUpdater();
}
@Override
protected boolean isFlattenPackages(){
return ((AbstractProjectTreeStructure)getTreeStructure()).isFlattenPackages();
}
}
private final class MyBookmarksListener implements BookmarksListener {
public void bookmarkAdded(Bookmark b) {
@Override
public void bookmarkAdded(@NotNull Bookmark b) {
updateForFile(b.getFile());
}
public void bookmarkRemoved(Bookmark b) {
@Override
public void bookmarkRemoved(@NotNull Bookmark b) {
updateForFile(b.getFile());
}
public void bookmarkChanged(Bookmark b) {
@Override
public void bookmarkChanged(@NotNull Bookmark b) {
updateForFile(b.getFile());
}
@@ -145,10 +154,12 @@ public class ProjectTreeBuilder extends BaseProjectTreeBuilder {
}
private final class MyFileStatusListener implements FileStatusListener {
@Override
public void fileStatusesChanged() {
queueUpdate(false);
}
@Override
public void fileStatusChanged(@NotNull VirtualFile vFile) {
queueUpdate(false);
}
@@ -171,10 +182,12 @@ public class ProjectTreeBuilder extends BaseProjectTreeBuilder {
private final Alarm myUpdateProblemAlarm = new Alarm();
private final Collection<VirtualFile> myFilesToRefresh = new THashSet<VirtualFile>();
@Override
public void problemsAppeared(VirtualFile file) {
queueUpdate(file);
}
@Override
public void problemsDisappeared(VirtualFile file) {
queueUpdate(file);
}
@@ -184,6 +197,7 @@ public class ProjectTreeBuilder extends BaseProjectTreeBuilder {
if (myFilesToRefresh.add(fileToRefresh)) {
myUpdateProblemAlarm.cancelAllRequests();
myUpdateProblemAlarm.addRequest(new Runnable() {
@Override
public void run() {
if (!myProject.isOpen()) return;
Set<VirtualFile> filesToRefresh;
@@ -7,6 +7,7 @@ import com.intellij.ui.SimpleTextAttributes;
import com.intellij.ui.treeStructure.SimpleNode;
import com.intellij.util.Function;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import java.awt.*;
public class BlockTreeNode extends SimpleNode {
@@ -56,6 +57,7 @@ public class BlockTreeNode extends SimpleNode {
}
@NotNull
@Override
public Object[] getEqualityObjects() {
return new Object[]{myBlock};
@@ -27,6 +27,7 @@ import com.intellij.ui.DeferredIconImpl;
import com.intellij.ui.mac.foundation.Foundation;
import com.intellij.util.Function;
import com.intellij.util.ui.update.ComparableObject;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
@@ -134,6 +135,7 @@ public class NativeFileIconProvider implements FileIconProvider {
myText = new Object[] {text, flags};
}
@NotNull
public Object[] getEqualityObjects() {
return myText;
}
@@ -248,7 +248,7 @@ public class DirectoryIndexImpl extends DirectoryIndex implements ProjectCompone
DirectoryInfo info = stateAndDirs.first.myDirToInfoMap.get(dir);
assert info != null;
if (!info.isInLibrarySource || info.libraryClassRoot != null) {
if (!info.isInLibrarySource || info.isInModuleSource || info.libraryClassRoot != null) {
if (!consumer.process(dir)) return false;
}
}
@@ -613,7 +613,6 @@ public class DirectoryIndexImpl extends DirectoryIndex implements ProjectCompone
if (definedPackage != null && definedPackage.isEmpty()) return; // another library source root starts here
}
info.isInModuleSource = false;
info.isInLibrarySource = true;
info.sourceRoot = sourceRoot;
setPackageName(dir, packageName);
@@ -67,9 +67,15 @@ public class ModulesCombobox extends ComboBox {
}
public void fillModules(@NotNull Project project) {
fillModules(project, null);
}
public void fillModules(@NotNull Project project, final @Nullable ModuleType moduleType) {
myModel.clear();
for (Module module : ModuleManager.getInstance(project).getModules()) {
myModel.add(module);
if (moduleType == null || moduleType.equals(ModuleType.get(module))) {
myModel.add(module);
}
}
}
@@ -162,7 +162,9 @@ public class InjectedLanguageUtil {
@NotNull
public static Editor getInjectedEditorForInjectedFile(@NotNull Editor hostEditor, final PsiFile injectedFile) {
if (injectedFile == null || hostEditor instanceof EditorWindow || hostEditor.isDisposed()) return hostEditor;
Document document = PsiDocumentManager.getInstance(hostEditor.getProject()).getDocument(injectedFile);
Project project = hostEditor.getProject();
if (project == null) project = injectedFile.getProject();
Document document = PsiDocumentManager.getInstance(project).getDocument(injectedFile);
if (!(document instanceof DocumentWindowImpl)) return hostEditor;
DocumentWindowImpl documentWindow = (DocumentWindowImpl)document;
SelectionModel selectionModel = hostEditor.getSelectionModel();
@@ -198,7 +198,8 @@ public class StubIndexImpl extends StubIndex implements ApplicationComponent, Pe
@NotNull final Project project,
@Nullable final GlobalSearchScope scope,
@NotNull final Processor<? super Psi> processor) {
FileBasedIndex.getInstance().ensureUpToDate(StubUpdatingIndex.INDEX_ID, project, scope);
final FileBasedIndex fileBasedIndex = FileBasedIndex.getInstance();
fileBasedIndex.ensureUpToDate(StubUpdatingIndex.INDEX_ID, project, scope);
final PersistentFS fs = (PersistentFS)ManagingFS.getInstance();
final PsiManager psiManager = PsiManager.getInstance(project);
@@ -212,7 +213,7 @@ public class StubIndexImpl extends StubIndex implements ApplicationComponent, Pe
index.getReadLock().lock();
final ValueContainer<TIntArrayList> container = index.getData(key);
final FileBasedIndex.ProjectIndexableFilesFilter projectFilesFilter = FileBasedIndex.getInstance().projectIndexableFiles(project);
final FileBasedIndex.ProjectIndexableFilesFilter projectFilesFilter = fileBasedIndex.projectIndexableFiles(project);
return container.forEach(new ValueContainer.ContainerAction<TIntArrayList>() {
@Override
@@ -278,7 +279,7 @@ public class StubIndexImpl extends StubIndex implements ApplicationComponent, Pe
ApplicationManager.getApplication().invokeLater(new Runnable() {
@Override
public void run() {
FileBasedIndex.getInstance().requestReindex(file);
fileBasedIndex.requestReindex(file);
}
}, ModalityState.NON_MODAL);
}
@@ -108,11 +108,14 @@ public class TextOccurrencesUtil {
@NotNull String stringToSearch,
@NotNull final Collection<UsageInfo> results,
@NotNull final UsageInfoFactory factory) {
final Object lock = new Object();
processUsagesInStringsAndComments(element, stringToSearch, false, new PairProcessor<PsiElement, TextRange>() {
public boolean process(PsiElement commentOrLiteral, TextRange textRange) {
UsageInfo usageInfo = factory.createUsageInfo(commentOrLiteral, textRange.getStartOffset(), textRange.getEndOffset());
if (usageInfo != null) {
results.add(usageInfo);
synchronized (lock) {
results.add(usageInfo);
}
}
return true;
}
@@ -27,9 +27,7 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.script.ScriptException;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.*;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
@@ -103,12 +101,15 @@ public class ExecUtil {
}
@Nullable
public static String execAndReadLine(@NotNull final List<String> command) {
public static String execAndReadLine(final String... command) {
try {
final ProcessOutput output = execAndGetOutput(command, null);
final List<String> lines = output.getStdoutLines();
if (lines.size() > 0) {
return lines.get(0);
final Process process = new GeneralCommandLine(command).createProcess();
final BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
try {
return reader.readLine();
}
finally {
reader.close();
}
}
catch (Exception ignored) { }
@@ -133,7 +133,7 @@ public class BrowserUtil {
if (SystemInfo.isMac || SystemInfo.isWindows) {
return true;
}
else if (SystemInfo.isUnix && SystemInfo.hasXdgOpen) {
else if (SystemInfo.isUnix && SystemInfo.hasXdgOpen()) {
return true;
}
else if (Desktop.isDesktopSupported() && Desktop.getDesktop().isSupported(Desktop.Action.BROWSE)) {
@@ -152,7 +152,7 @@ public class BrowserUtil {
else if (SystemInfo.isMac) {
return new String[]{ExecUtil.getOpenCommandPath()};
}
else if (SystemInfo.isUnix && SystemInfo.hasXdgOpen) {
else if (SystemInfo.isUnix && SystemInfo.hasXdgOpen()) {
return new String[]{"xdg-open"};
}
@@ -17,6 +17,7 @@ package com.intellij.ide;
import com.intellij.util.ui.update.ComparableObject;
import com.intellij.util.ui.update.ComparableObjectCheck;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
@@ -38,6 +39,7 @@ public class UiActivity implements ComparableObject{
}
}
@NotNull
@Override
public Object[] getEqualityObjects() {
return new Object[] {myElements};
@@ -247,6 +247,7 @@ public class PresentationData implements ColoredItemPresentation, ComparableObje
mySeparatorAbove = false;
}
@NotNull
public Object[] getEqualityObjects() {
return new Object[]{myOpenIcon, myClosedIcon, myColoredText, myAttributesKey, myFont, myForcedTextForeground, myPresentableText,
myLocationString, mySeparatorAbove};
@@ -24,13 +24,15 @@ import org.jetbrains.annotations.NotNull;
*/
public class ExtensionFileNameMatcher implements FileNameMatcher {
private final String myExtension;
private final String myDotExtension;
public ExtensionFileNameMatcher(@NotNull @NonNls String extension) {
myExtension = extension.toLowerCase();
myDotExtension = "." + myExtension;
}
public boolean accept(@NotNull @NonNls String fileName) {
return fileName.regionMatches(true, fileName.length() - myExtension.length() - 1, "." + myExtension, 0, myExtension.length() + 1);
return fileName.regionMatches(true, fileName.length() - myDotExtension.length(), myDotExtension, 0, myDotExtension.length());
}
@NonNls
@@ -16,17 +16,18 @@
package com.intellij.openapi.util;
import com.intellij.util.ui.update.ComparableObject;
import org.jetbrains.annotations.NotNull;
public abstract class ActiveRunnable extends ComparableObject.Impl {
protected ActiveRunnable() {
}
protected ActiveRunnable(final Object object) {
protected ActiveRunnable(@NotNull Object object) {
super(object);
}
protected ActiveRunnable(final Object[] objects) {
protected ActiveRunnable(@NotNull Object[] objects) {
super(objects);
}
@@ -16,7 +16,10 @@
package com.intellij.openapi.vfs;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.PsiFile;
import org.jetbrains.annotations.NotNull;
import java.util.Collection;
@@ -26,6 +29,24 @@ public abstract class ReadonlyStatusHandler {
return !getInstance(project).ensureFilesWritable(files).hasReadonlyFiles();
}
public static boolean ensureDocumentWritable(@NotNull Project project, @NotNull Document document) {
final PsiFile psiFile = PsiDocumentManager.getInstance(project).getPsiFile(document);
boolean okWritable;
if (psiFile != null) {
final VirtualFile virtualFile = psiFile.getVirtualFile();
if (virtualFile != null) {
okWritable = ensureFilesWritable(project, virtualFile);
}
else {
okWritable = psiFile.isWritable();
}
}
else {
okWritable = document.isWritable();
}
return okWritable;
}
public abstract static class OperationStatus {
@NotNull
public abstract VirtualFile[] getReadonlyFiles();
@@ -17,6 +17,7 @@ package com.intellij.ui;
import com.intellij.openapi.application.Application;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ModalityState;
import com.intellij.openapi.fileChooser.FileChooser;
import com.intellij.openapi.fileChooser.FileChooserDescriptor;
import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory;
@@ -382,4 +383,18 @@ public class GuiUtils {
invokeAndWait(runnable);
}
}
/**
* Runs the runnable, if called from the dispatch thread.
* Otherwise calls {@link Application#invokeAndWait(Runnable, com.intellij.openapi.application.ModalityState)}
*/
public static void invokeAndWaitIfNeeded(@NotNull Runnable runnable, @NotNull ModalityState modalityState) {
Application application = ApplicationManager.getApplication();
if (application.isDispatchThread()) {
runnable.run();
}
else {
application.invokeAndWait(runnable, modalityState);
}
}
}
@@ -29,6 +29,7 @@ public class Place implements ComparableObject {
private LinkedHashMap<String, Object> myPath = new LinkedHashMap<String, Object>();
@NotNull
public final Object[] getEqualityObjects() {
return new Object[] {myPath};
}
@@ -3221,6 +3221,7 @@ public class JBTabsImpl extends JComponent
return myInfo.getText();
}
@NotNull
@Override
public Object[] getEqualityObjects() {
return new Object[] {myInfo};
@@ -24,6 +24,7 @@ import com.intellij.openapi.vcs.FileStatus;
import com.intellij.ui.SimpleTextAttributes;
import com.intellij.util.ui.update.ComparableObject;
import com.intellij.util.ui.update.ComparableObjectCheck;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
@@ -263,6 +264,7 @@ public abstract class SimpleNode extends PresentableNodeDescriptor implements Co
return list.toArray(new ColoredFragment[list.size()]);
}
@NotNull
public Object[] getEqualityObjects() {
return NONE;
}
@@ -243,6 +243,7 @@ public class FilteringTreeStructure extends AbstractTreeStructure {
return super.getWeight();
}
@NotNull
public Object[] getEqualityObjects() {
return new Object[]{myDelegate};
}
@@ -73,8 +73,9 @@ public class RangeBlinker {
MarkupModel markupModel = myEditor.getMarkupModel();
if (show) {
for (Segment rangeMarker : myMarkers) {
RangeHighlighter highlighter = markupModel.addRangeHighlighter(rangeMarker.getStartOffset(), rangeMarker.getEndOffset(),
for (Segment segment : myMarkers) {
if (segment.getEndOffset() > myEditor.getDocument().getTextLength()) continue;
RangeHighlighter highlighter = markupModel.addRangeHighlighter(segment.getStartOffset(), segment.getEndOffset(),
HighlighterLayer.ADDITIONAL_SYNTAX, myAttributes,
HighlighterTargetArea.EXACT_RANGE);
myAddedHighlighters.add(highlighter);
@@ -85,6 +86,7 @@ public class RangeBlinker {
}
stopBlinking();
myBlinkingAlarm.addRequest(new Runnable() {
@Override
public void run() {
if (myTimeToLive > 0 || show) {
myTimeToLive--;
@@ -0,0 +1,54 @@
/*
* Copyright 2000-2012 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.util.ui;
import com.intellij.openapi.util.IconLoader;
import javax.swing.*;
import java.awt.*;
/**
* @author Konstantin Bulenkov
*/
public class RefreshFileSystemIcon extends AnimatedIcon {
private static final Icon[] ICONS = getIcons("/process/fs/step_", 18);
private static Icon[] getIcons(String path, int count) {
Icon[] icons = new Icon[count];
for (int i = 0; i < icons.length; i++) {
int index = i + 1;
icons[i] = IconLoader.getIcon(path + index + ".png");
}
return icons;
}
public RefreshFileSystemIcon() {
super("Refreshing filesystem", ICONS, EmptyIcon.ICON_16, 800);
}
@Override
public Dimension getPreferredSize() {
if (!isRunning()) return new Dimension(0, 0);
return super.getPreferredSize();
}
@Override
public void paint(Graphics g) {
g.translate(0, -1);
super.paint(g);
g.translate(0, 1);
}
}
@@ -50,7 +50,7 @@ public class IdeTooltip extends ComparableObject.Impl {
private Ui myUi;
private boolean hint = false;
private boolean myHint = false;
public IdeTooltip(Component component, Point point, JComponent tipComponent, Object... identity) {
@@ -235,12 +235,12 @@ public class IdeTooltip extends ComparableObject.Impl {
}
public IdeTooltip setHint(boolean hint) {
this.hint = hint;
this.myHint = hint;
return this;
}
public boolean isHint() {
return hint;
return myHint;
}
public boolean isInside(RelativePoint target) {
@@ -41,7 +41,7 @@ public class RevealFileAction extends DumbAwareAction {
@NotNull
public static String getActionName() {
return SystemInfo.isMac ? "Reveal in Finder" : "Show in " + SystemInfo.nativeFileManagerName;
return SystemInfo.isMac ? "Reveal in Finder" : "Show in " + SystemInfo.getFileManagerName();
}
@Override
@@ -35,6 +35,7 @@ import com.intellij.openapi.ui.popup.JBPopupFactory;
import com.intellij.openapi.ui.popup.ListPopup;
import com.intellij.openapi.ui.popup.PopupStep;
import com.intellij.openapi.ui.popup.util.BaseListPopupStep;
import com.intellij.openapi.util.NotNullLazyValue;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.openapi.vfs.JarFileSystem;
@@ -51,11 +52,19 @@ import java.awt.event.MouseEvent;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
public class ShowFilePathAction extends AnAction {
private static final Logger LOG = Logger.getInstance("#com.intellij.ide.actions.ShowFilePathAction");
private static NotNullLazyValue<Boolean> hasNautilusV3 = new NotNullLazyValue<Boolean>() {
@NotNull
@Override
protected Boolean compute() {
final String version = ExecUtil.execAndReadLine("nautilus", "--version");
return version != null && version.startsWith("GNOME nautilus 3");
}
};
@Override
public void update(final AnActionEvent e) {
if (SystemInfo.isMac || !isSupported()) {
@@ -166,7 +175,7 @@ public class ShowFilePathAction extends AnAction {
public static boolean isSupported() {
return SystemInfo.isWindows ||
Desktop.isDesktopSupported() && Desktop.getDesktop().isSupported(Desktop.Action.OPEN) ||
SystemInfo.hasXdgOpen || SystemInfo.hasNautilus;
SystemInfo.hasXdgOpen() || SystemInfo.hasNautilus();
}
/** @deprecated use {@linkplain #openFile(java.io.File)} (to remove in IDEA 13) */
@@ -231,7 +240,7 @@ public class ShowFilePathAction extends AnAction {
return;
}
if (Registry.is("ide.use.nautilus3") && SystemInfo.hasNautilus && hasNautilusV3()) {
if (Registry.is("ide.use.nautilus3") && SystemInfo.hasNautilus() && hasNautilusV3.getValue()) {
if (toSelect != null) {
new GeneralCommandLine("nautilus", toSelect.getCanonicalPath()).createProcess();
}
@@ -242,10 +251,10 @@ public class ShowFilePathAction extends AnAction {
}
final String path = dir.getCanonicalPath();
if (SystemInfo.hasXdgOpen) {
if (SystemInfo.hasXdgOpen()) {
new GeneralCommandLine("/usr/bin/xdg-open", path).createProcess();
}
else if (SystemInfo.hasNautilus) {
else if (SystemInfo.hasNautilus()) {
new GeneralCommandLine("nautilus", path).createProcess();
}
else if (Desktop.isDesktopSupported() && Desktop.getDesktop().isSupported(Desktop.Action.OPEN)) {
@@ -256,16 +265,6 @@ public class ShowFilePathAction extends AnAction {
}
}
private static Boolean hasNautilusV3 = null;
private static boolean hasNautilusV3() {
if (hasNautilusV3 == null) {
final String version = ExecUtil.execAndReadLine(Arrays.asList("nautilus", "--version"));
hasNautilusV3 = version != null && version.startsWith("GNOME nautilus 3");
}
return hasNautilusV3;
}
@Nullable
private static VirtualFile getFile(final AnActionEvent e) {
return PlatformDataKeys.VIRTUAL_FILE.getData(e.getDataContext());
@@ -44,6 +44,6 @@ public class ShowLogAction extends AnAction implements DumbAware {
@NotNull
public static String getActionName() {
return "Reveal Log in " + SystemInfo.nativeFileManagerName;
return "Reveal Log in " + SystemInfo.getFileManagerName();
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2011 JetBrains s.r.o.
* Copyright 2000-2012 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.
@@ -34,6 +34,7 @@ import com.intellij.openapi.ui.popup.JBPopupFactory;
import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.Iconable;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vcs.FileStatus;
import com.intellij.openapi.vcs.FileStatusManager;
import com.intellij.openapi.vfs.VirtualFile;
@@ -43,10 +44,8 @@ import com.intellij.openapi.wm.ToolWindowManager;
import com.intellij.openapi.wm.ex.WindowManagerEx;
import com.intellij.openapi.wm.impl.IdeFrameImpl;
import com.intellij.openapi.wm.impl.ToolWindowManagerImpl;
import com.intellij.ui.ColoredListCellRenderer;
import com.intellij.ui.Gray;
import com.intellij.ui.IdeBorderFactory;
import com.intellij.ui.SimpleTextAttributes;
import com.intellij.openapi.wm.impl.content.GraphicsConfig;
import com.intellij.ui.*;
import com.intellij.ui.components.JBList;
import com.intellij.util.Alarm;
import com.intellij.util.ArrayUtil;
@@ -62,6 +61,8 @@ import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import java.awt.*;
import java.awt.event.*;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.File;
import java.util.*;
import java.util.List;
@@ -121,10 +122,12 @@ public class Switcher extends AnAction implements DumbAware {
ToolWindow tw;
if (SWITCHER != null && event instanceof KeyEvent) {
final KeyEvent keyEvent = (KeyEvent)event;
if (event.getID() == KEY_RELEASED && keyEvent.getKeyCode() == CTRL_KEY && UISettings.getInstance().HIDE_SWITCHER_ON_CONTROL_RELEASE) {
if (event.getID() == KEY_RELEASED && keyEvent.getKeyCode() == CTRL_KEY && isAutoHide()) {
SwingUtilities.invokeLater(CHECKER);
}
else if (event.getID() == KEY_PRESSED && (tw = SWITCHER.twShortcuts.get(String.valueOf((char)keyEvent.getKeyCode()))) != null) {
else if (isAutoHide()
&& event.getID() == KEY_PRESSED
&& (tw = SWITCHER.twShortcuts.get(String.valueOf((char)keyEvent.getKeyCode()))) != null) {
SWITCHER.myPopup.closeOk(null);
tw.activate(null, true, true);
}
@@ -176,6 +179,7 @@ public class Switcher extends AnAction implements DumbAware {
final Project project;
final Map<String, ToolWindow> twShortcuts;
final Alarm myAlarm;
final SwitcherSpeedSearch mySpeedSearch = isAutoHide() ? null : new SwitcherSpeedSearch();
@SuppressWarnings({"ManualArrayToCollectionCopy"})
SwitcherPanel(Project project) {
@@ -225,7 +229,7 @@ public class Switcher extends AnAction implements DumbAware {
toolWindows = new JBList(twModel);
toolWindows.setBorder(IdeBorderFactory.createEmptyBorder(5, 5, 5, 20));
toolWindows.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
toolWindows.setCellRenderer(new SwitcherToolWindowsListRenderer(ids, map) {
toolWindows.setCellRenderer(new SwitcherToolWindowsListRenderer(mySpeedSearch, ids, map) {
@Override
public Component getListCellRendererComponent(JList list,
Object value,
@@ -297,7 +301,7 @@ public class Switcher extends AnAction implements DumbAware {
files = new JBList(filesModel);
files.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
files.setBorder(IdeBorderFactory.createEmptyBorder(5, 5, 5, 20));
files.setCellRenderer(new VirtualFilesRenderer(project) {
files.setCellRenderer(new VirtualFilesRenderer(project, mySpeedSearch) {
@Override
public Component getListCellRendererComponent(JList list,
Object value,
@@ -381,19 +385,33 @@ public class Switcher extends AnAction implements DumbAware {
.setRequestFocus(true)
.setTitle(SWITCHER_TITLE)
.setMovable(false)
.setCancelKeyEnabled(false)
.setCancelCallback(new Computable<Boolean>() {
public Boolean compute() {
SWITCHER = null;
return true;
}
}).createPopup();
public Boolean compute() {
SWITCHER = null;
return true;
}
}).createPopup();
new AnAction(null, null, null){
if (!isAutoHide()) {
new AnAction(null, null, null) {
@Override
public void actionPerformed(AnActionEvent e) {
//suppress all actions to activate a toolwindow : IDEA-71277
}
}.registerCustomShortcutSet(TW_SHORTCUT, this, myPopup);
new AnAction(null, null, null) {
@Override
public void actionPerformed(AnActionEvent e) {
if (mySpeedSearch != null && mySpeedSearch.isPopupActive()) {
mySpeedSearch.hidePopup();
} else {
myPopup.cancel();
}
}
}.registerCustomShortcutSet(CustomShortcutSet.fromString("ESCAPE"), this, myPopup);
}
Component comp = null;
final EditorWindow result = FileEditorManagerEx.getInstanceEx(project).getActiveWindow().getResult();
@@ -407,6 +425,7 @@ public class Switcher extends AnAction implements DumbAware {
myPopup.showInCenterOf(comp);
}
private Map<String, ToolWindow> createShortcuts(List<ToolWindow> windows) {
final Map<String, ToolWindow> keymap = new HashMap<String, ToolWindow>(windows.size());
final List<ToolWindow> pluginToolWindows = new ArrayList<ToolWindow>();
@@ -441,7 +460,7 @@ public class Switcher extends AnAction implements DumbAware {
}
public void keyReleased(KeyEvent e) {
if ((e.getKeyCode() == CTRL_KEY && UISettings.getInstance().HIDE_SWITCHER_ON_CONTROL_RELEASE)
if ((e.getKeyCode() == CTRL_KEY && isAutoHide())
|| e.getKeyCode() == VK_ENTER) {
navigate();
} else
@@ -453,6 +472,8 @@ public class Switcher extends AnAction implements DumbAware {
}
public void keyPressed(KeyEvent e) {
if (mySpeedSearch != null && mySpeedSearch.isPopupActive()) return;
switch (e.getKeyCode()) {
case VK_UP:
goBack();
@@ -546,7 +567,7 @@ public class Switcher extends AnAction implements DumbAware {
}
private void goRight() {
if ((isFilesSelected() || !isFilesVisible()) && UISettings.getInstance().HIDE_SWITCHER_ON_CONTROL_RELEASE) {
if ((isFilesSelected() || !isFilesVisible()) && isAutoHide()) {
cancel();
}
else {
@@ -562,7 +583,7 @@ public class Switcher extends AnAction implements DumbAware {
}
private void goLeft() {
if (isToolWindowsSelected() && UISettings.getInstance().HIDE_SWITCHER_ON_CONTROL_RELEASE) {
if (isToolWindowsSelected() && isAutoHide()) {
cancel();
}
else {
@@ -699,26 +720,102 @@ public class Switcher extends AnAction implements DumbAware {
repaintLists();
}
public void mouseDragged(MouseEvent e) {}
private class SwitcherSpeedSearch extends SpeedSearchBase<SwitcherPanel> implements PropertyChangeListener {
private Object[] myElements;
public SwitcherSpeedSearch() {
super(SwitcherPanel.this);
addChangeListener(this);
}
@Override
protected int getSelectedIndex() {
return isFilesSelected()
? files.getSelectedIndex()
: files.getModel().getSize() + toolWindows.getSelectedIndex();
}
@Override
protected Object[] getAllElements() {
if (myElements == null) {
final SwitcherPanel switcher = SwitcherPanel.this;
final Object[] files = ((DefaultListModel)switcher.files.getModel()).toArray();
final Object[] toolWindows = ((DefaultListModel)switcher.toolWindows.getModel()).toArray();
myElements = new Object[files.length + toolWindows.length];
System.arraycopy(files, 0, myElements, 0, files.length);
System.arraycopy(toolWindows, 0, myElements, files.length, toolWindows.length);
}
return myElements;
}
@Override
protected String getElementText(Object element) {
return element instanceof ToolWindow
? ids.get(element)
: element instanceof FileInfo
? ((FileInfo)element).getFirst().getName() : "";
}
@Override
protected void selectElement(Object element, String selectedText) {
if (element instanceof FileInfo) {
toolWindows.getSelectionModel().clearSelection();
files.setSelectedValue(element, false);
} else {
files.clearSelection();
toolWindows.setSelectedValue(element, false);
}
}
@Override
public void propertyChange(PropertyChangeEvent evt) {
files.repaint();
toolWindows.repaint();
}
}
}
private static boolean isAutoHide() {
return UISettings.getInstance().HIDE_SWITCHER_ON_CONTROL_RELEASE;
}
private static class VirtualFilesRenderer extends ColoredListCellRenderer {
private final Project myProject;
private final SpeedSearchBase mySearch;
private boolean hide = false;
public VirtualFilesRenderer(Project project) {
public VirtualFilesRenderer(Project project, SpeedSearchBase search) {
myProject = project;
mySearch = search;
}
protected void customizeCellRenderer(JList list, Object value, int index, boolean selected, boolean hasFocus) {
hide = false;
if (value instanceof FileInfo) {
final VirtualFile virtualFile = ((FileInfo)value).first;
final String name = virtualFile.getPresentableName();
setIcon(IconUtil.getIcon(virtualFile, Iconable.ICON_FLAG_READ_STATUS, myProject));
if ( mySearch != null && mySearch.isPopupActive()) {
hide = mySearch.matchingFragments(name) == null && !StringUtil.isEmpty(mySearch.getEnteredPrefix());
}
final FileStatus fileStatus = FileStatusManager.getInstance(myProject).getStatus(virtualFile);
final TextAttributes attributes = new TextAttributes(fileStatus.getColor(), null, null, EffectType.LINE_UNDERSCORE, Font.PLAIN);
append(name, SimpleTextAttributes.fromTextAttributes(attributes));
}
}
@Override
protected void doPaint(Graphics2D g) {
GraphicsConfig config = new GraphicsConfig(g);
if (hide) {
g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.4f));
}
super.doPaint(g);
config.restore();
}
}
private static class FileInfo extends Pair<VirtualFile, EditorWindow> {
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2011 JetBrains s.r.o.
* Copyright 2000-2012 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.
@@ -15,11 +15,15 @@
*/
package com.intellij.ide.actions;
import com.intellij.ide.ui.UISettings;
import com.intellij.openapi.editor.markup.EffectType;
import com.intellij.openapi.editor.markup.TextAttributes;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.wm.ToolWindow;
import com.intellij.openapi.wm.impl.content.GraphicsConfig;
import com.intellij.ui.ColoredListCellRenderer;
import com.intellij.ui.SimpleTextAttributes;
import com.intellij.ui.SpeedSearchBase;
import com.intellij.util.PlatformIcons;
import javax.swing.*;
@@ -34,26 +38,51 @@ import java.util.Map;
class SwitcherToolWindowsListRenderer extends ColoredListCellRenderer {
private static final Map<String, Icon> iconCache = new HashMap<String, Icon>();
private static final SimpleTextAttributes ID_STYLE = new SimpleTextAttributes(SimpleTextAttributes.STYLE_UNDERLINE, Color.black);
private final SpeedSearchBase mySpeedSearch;
private final Map<ToolWindow, String> ids;
private final Map<ToolWindow, String> shortcuts;
private boolean hide = false;
SwitcherToolWindowsListRenderer(Map<ToolWindow, String> ids, Map<ToolWindow, String> shortcuts) {
SwitcherToolWindowsListRenderer(SpeedSearchBase speedSearch,
Map<ToolWindow, String> ids,
Map<ToolWindow, String> shortcuts) {
mySpeedSearch = speedSearch;
this.ids = ids;
this.shortcuts = shortcuts;
}
protected void customizeCellRenderer(JList list, Object value, int index, boolean selected, boolean hasFocus) {
hide = false;
if (value instanceof ToolWindow) {
final ToolWindow tw = (ToolWindow)value;
setIcon(getIcon(tw));
append(shortcuts.get(tw), ID_STYLE);
final String name = ": " + ids.get(tw);
final String name;
if (UISettings.getInstance().HIDE_SWITCHER_ON_CONTROL_RELEASE) {
append(shortcuts.get(tw), ID_STYLE);
name = ": " + ids.get(tw);
} else {
name = ids.get(tw);
}
final TextAttributes attributes = new TextAttributes(Color.BLACK, null, null, EffectType.LINE_UNDERSCORE, Font.PLAIN);
append(name, SimpleTextAttributes.fromTextAttributes(attributes));
if (mySpeedSearch != null && mySpeedSearch.isPopupActive()) {
hide = mySpeedSearch.matchingFragments(ids.get(tw)) == null && !StringUtil.isEmpty(mySpeedSearch.getEnteredPrefix());
}
}
}
@Override
protected void doPaint(Graphics2D g) {
GraphicsConfig config = new GraphicsConfig(g);
if (hide) {
g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.4f));
}
super.doPaint(g);
config.restore();
}
private Icon getIcon(ToolWindow toolWindow) {
Icon icon = iconCache.get(ids.get(toolWindow));
if (icon != null) return icon;
@@ -26,6 +26,7 @@ import com.intellij.openapi.application.ModalityState;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.ui.GuiUtils;
import java.io.UnsupportedEncodingException;
import java.util.HashMap;
@@ -182,7 +183,7 @@ public class MasterKeyPasswordSafe extends BasePasswordSafeProvider {
}
if (key.get() == null) {
final Ref<PasswordSafeException> ex = new Ref<PasswordSafeException>();
ApplicationManager.getApplication().invokeAndWait(new Runnable() {
GuiUtils.invokeAndWaitIfNeeded(new Runnable() {
public void run() {
if (key.get() == null) {
try {
@@ -18,12 +18,12 @@ package com.intellij.ide.passwordSafe.ui;
import com.intellij.ide.passwordSafe.PasswordSafe;
import com.intellij.ide.passwordSafe.PasswordSafeException;
import com.intellij.ide.passwordSafe.impl.PasswordSafeImpl;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ModalityState;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.ui.Messages;
import com.intellij.ui.GuiUtils;
import com.intellij.util.ui.UIUtil;
import javax.swing.*;
@@ -273,7 +273,7 @@ public class PasswordSafePromptDialog extends DialogWrapper {
}
}
final AtomicReference<String> pw = new AtomicReference<String>(null);
ApplicationManager.getApplication().invokeAndWait(new Runnable() {
GuiUtils.invokeAndWaitIfNeeded(new Runnable() {
public void run() {
final PasswordSafePromptDialog d = new PasswordSafePromptDialog(project, ps, title, message);
if (promptLabel != null) {
@@ -40,13 +40,13 @@ import java.util.Comparator;
public abstract class Change {
private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.diff.impl.incrementalMerge.Change");
private void apply(FragmentSide original) {
private void apply(@NotNull FragmentSide original) {
FragmentSide targetSide = original.otherSide();
RangeMarker originalRangeMarker = getRangeMarker(original);
RangeMarker rangeMarker = getRangeMarker(targetSide);
if (originalRangeMarker != null && rangeMarker != null) {
ChangeType.apply(originalRangeMarker, rangeMarker);
ChangeType.apply(getProject(), originalRangeMarker, rangeMarker);
if (isValid()) {
removeFromList();
}

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