Merge remote-tracking branch 'origin/master'

This commit is contained in:
Ilya.Kazakevich
2015-06-10 16:50:46 +03:00
81 changed files with 1251 additions and 346 deletions
+12 -4
View File
@@ -23,10 +23,18 @@ if ("GIT_TESTS".equalsIgnoreCase(System.getProperty("idea.test.group"))) {
setProperty("cucumber_test_dirs", [["git4idea", "Idea", "${home}/plugins/git4idea/test-features/git4idea", "git4idea"]])
}
def args = [
"-Xmx450m",
"-Dsun.io.useCanonCaches=false"
]
def args = []
def mem = System.getProperty("test.jvm.memory")
if (mem != null) {
args.addAll(mem.split())
}
else {
args += [
"-Xmx450m",
"-Dsun.io.useCanonCaches=false"
]
}
if (System.getProperty("os.name").toLowerCase().startsWith("mac")) {
String vendor = System.getProperty("java.vm.vendor")
@@ -36,6 +36,7 @@ import com.intellij.ui.ToolbarDecorator;
import com.intellij.ui.awt.RelativePoint;
import com.intellij.ui.components.JBList;
import com.intellij.ui.treeStructure.Tree;
import com.intellij.util.SmartList;
import com.intellij.util.ui.EditableTreeModel;
import com.intellij.util.ui.tree.TreeUtil;
import org.jetbrains.jps.model.java.compiler.ProcessorConfigProfile;
@@ -270,14 +271,29 @@ public class AnnotationProcessorsPanel extends JPanel {
@Override
public void removeNode(TreePath nodePath) {
Object node = nodePath.getLastPathComponent();
if (node instanceof ProfileNode) {
final ProcessorConfigProfile nodeProfile = ((ProfileNode)node).myProfile;
if (nodeProfile != myDefaultProfile) {
removeNodes(Collections.singleton(nodePath));
}
public void removeNodes(Collection<TreePath> paths) {
final List<ProcessorConfigProfile> toRemove = new SmartList<ProcessorConfigProfile>();
for (TreePath path : paths) {
Object node = path.getLastPathComponent();
if (node instanceof ProfileNode) {
final ProcessorConfigProfile nodeProfile = ((ProfileNode)node).myProfile;
if (nodeProfile != myDefaultProfile) {
toRemove.add(nodeProfile);
}
}
}
if (!toRemove.isEmpty()) {
boolean changed = false;
for (ProcessorConfigProfile nodeProfile : toRemove) {
if (mySelectedProfile == nodeProfile) {
mySelectedProfile = null;
}
myModuleProfiles.remove(nodeProfile);
changed |= myModuleProfiles.remove(nodeProfile);
}
if (changed) {
((DataSynchronizable)getRoot()).sync();
final DefaultMutableTreeNode object = TreeUtil.findNodeWithObject((DefaultMutableTreeNode)getRoot(), myDefaultProfile);
if (object != null) {
@@ -1,5 +1,5 @@
/*
* 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.
@@ -87,7 +87,7 @@ public class DefaultSourcePositionProvider extends SourcePositionProvider {
if (nearest) {
return DebuggerContextUtil.findNearest(context, psiVariable, aClass.getContainingFile());
}
return SourcePosition.createFromOffset(psiVariable.getContainingFile(), psiVariable.getTextOffset());
return SourcePosition.createFromElement(psiVariable);
}
else {
final DebuggerSession session = context.getDebuggerSession();
@@ -115,13 +115,11 @@ public class DefaultSourcePositionProvider extends SourcePositionProvider {
if (aClass != null) {
PsiField field = aClass.findFieldByName(fieldName, false);
if (field != null) {
PsiElement element = field.getNavigationElement();
if (nearest) {
return DebuggerContextUtil.findNearest(context, element, aClass.getContainingFile());
}
return SourcePosition.createFromOffset(element.getContainingFile(), element.getTextOffset());
if (field == null) return null;
if (nearest) {
return DebuggerContextUtil.findNearest(context, field.getNavigationElement(), aClass.getContainingFile());
}
return SourcePosition.createFromElement(field);
}
return null;
}
@@ -133,20 +131,16 @@ public class DefaultSourcePositionProvider extends SourcePositionProvider {
@NotNull DebuggerContextImpl context,
boolean nearest) {
PsiElement place = PositionUtil.getContextElement(context);
if (place == null) {
return null;
}
if (place == null) return null;
PsiVariable psiVariable = JavaPsiFacade.getInstance(project).getResolveHelper().resolveReferencedVariable(descriptor.getName(), place);
if (psiVariable == null) {
return null;
}
if (psiVariable == null) return null;
PsiFile containingFile = psiVariable.getContainingFile();
if(containingFile == null) return null;
if (nearest) {
return DebuggerContextUtil.findNearest(context, psiVariable, containingFile);
}
return SourcePosition.createFromOffset(containingFile, psiVariable.getTextOffset());
return SourcePosition.createFromElement(psiVariable);
}
}
@@ -274,7 +274,7 @@ public abstract class SourcePosition implements Navigatable{
}
}
public static SourcePosition createFromLineComputable(final PsiFile file, final Computable<Integer> line) {
public static SourcePosition createFromLineComputable(@NotNull final PsiFile file, final Computable<Integer> line) {
return new SourcePositionCache(file) {
@Override
protected int calcLine() {
@@ -283,7 +283,7 @@ public abstract class SourcePosition implements Navigatable{
};
}
public static SourcePosition createFromLine(final PsiFile file, final int line) {
public static SourcePosition createFromLine(@NotNull final PsiFile file, final int line) {
return new SourcePositionCache(file) {
@Override
protected int calcLine() {
@@ -297,9 +297,8 @@ public abstract class SourcePosition implements Navigatable{
};
}
public static SourcePosition createFromOffset(final PsiFile file, final int offset) {
public static SourcePosition createFromOffset(@NotNull final PsiFile file, final int offset) {
return new SourcePositionCache(file) {
@Override
protected int calcOffset() {
return offset;
@@ -311,7 +310,8 @@ public abstract class SourcePosition implements Navigatable{
}
};
}
@Nullable
public static SourcePosition createFromElement(PsiElement element) {
ApplicationManager.getApplication().assertReadAccessAllowed();
PsiElement navigationElement = element.getNavigationElement();
@@ -324,6 +324,7 @@ public abstract class SourcePosition implements Navigatable{
else {
psiFile = navigationElement.getContainingFile();
}
if (psiFile == null) return null;
return new SourcePositionCache(psiFile) {
@Override
protected PsiElement calcPsiElement() {
@@ -38,7 +38,7 @@ public class ApplicationRunLineMarkerProvider implements LineMarkerProvider {
public LineMarkerInfo getLineMarkerInfo(@NotNull PsiElement element) {
if (element instanceof PsiClass && PsiMethodUtil.findMainInClass((PsiClass)element) != null)
return new RunLineMarkerInfo(element, ApplicationConfigurationType.getInstance().getIcon(), null);
if (element instanceof PsiMethod && PsiMethodUtil.isMainMethod((PsiMethod)element))
if (element instanceof PsiMethod && "main".equals(((PsiMethod)element).getName()) && PsiMethodUtil.isMainMethod((PsiMethod)element))
return new RunLineMarkerInfo(element, ApplicationConfigurationType.getInstance().getIcon(), null);
return null;
}
@@ -19,6 +19,8 @@ import com.intellij.codeInsight.daemon.JavaErrorMessages;
import com.intellij.codeInspection.InspectionsBundle;
import com.intellij.codeInspection.ProblemHighlightType;
import com.intellij.codeInspection.ProblemsHolder;
import com.intellij.openapi.projectRoots.JavaSdkVersion;
import com.intellij.openapi.projectRoots.JavaVersionService;
import com.intellij.patterns.ElementPattern;
import com.intellij.pom.java.LanguageLevel;
import com.intellij.psi.*;
@@ -70,11 +72,11 @@ public class JavacQuirksInspectionVisitor extends JavaElementVisitor {
@Override
public void visitIdentifier(PsiIdentifier identifier) {
super.visitIdentifier(identifier);
final LanguageLevel languageLevel = PsiUtil.getLanguageLevel(identifier);
if (languageLevel.isAtLeast(LanguageLevel.JDK_1_8)) {
final JavaSdkVersion version = JavaVersionService.getInstance().getJavaSdkVersion(identifier);
if (version != null && version.isAtLeast(JavaSdkVersion.JDK_1_8)) {
if ("_".equals(identifier.getText())) {
myHolder.registerProblem(identifier, JavaErrorMessages.message("underscore.identifier"),
languageLevel.isAtLeast(LanguageLevel.JDK_1_9) ? ProblemHighlightType.ERROR : ProblemHighlightType.GENERIC_ERROR_OR_WARNING);
version.isAtLeast(JavaSdkVersion.JDK_1_9) ? ProblemHighlightType.ERROR : ProblemHighlightType.GENERIC_ERROR_OR_WARNING);
}
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2009 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.
@@ -52,6 +52,11 @@ public class CollapseBlockHandler implements CodeInsightActionHandler {
int end = block.getTextRange().getEndOffset();
FoldRegion existing = FoldingUtil.findFoldRegion(editor, start, end);
if (existing != null) {
if (existing.isExpanded()) {
existing.setExpanded(false);
editor.getCaretModel().moveToOffset(existing.getEndOffset());
return;
}
previous = existing;
if (info.getPsiElement(existing) == null) myPrevious = existing;
block = PsiTreeUtil.getParentOfType(block, PsiCodeBlock.class);
@@ -0,0 +1,51 @@
/*
* 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.codeInsight.hint;
import com.intellij.lang.ExpressionTypeProvider;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiExpression;
import com.intellij.psi.PsiType;
import com.intellij.psi.SyntaxTraverser;
import org.jetbrains.annotations.NotNull;
import java.util.List;
/**
* @author gregsh
*/
public class JavaTypeProvider extends ExpressionTypeProvider<PsiExpression> {
@NotNull
@Override
public String getInformationHint(@NotNull PsiExpression element) {
PsiType type = element.getType();
String text = type == null ? "<unknown>" : type.getCanonicalText();
return StringUtil.escapeXml(text);
}
@NotNull
@Override
public String getErrorHint() {
return "No expression found";
}
@NotNull
@Override
public List<PsiExpression> getExpressionsAt(@NotNull PsiElement elementAt) {
return SyntaxTraverser.psiTraverser().parents(elementAt).filter(PsiExpression.class).toList();
}
}
@@ -135,7 +135,7 @@ public class PsiPolyExpressionUtil {
private static boolean isAssignmentContext(PsiExpression expr, PsiElement context) {
return PsiUtil.isCondition(expr, context) ||
context instanceof PsiReturnStatement ||
context instanceof PsiAssignmentExpression ||
context instanceof PsiAssignmentExpression && ((PsiAssignmentExpression)context).getOperationTokenType() == JavaTokenType.EQ ||
context instanceof PsiVariable ||
context instanceof PsiLambdaExpression;
}
@@ -100,6 +100,23 @@ public class PsiPolyExpressionUtilTest extends LightCodeInsightFixtureTestCase {
assertTrue(PsiPolyExpressionUtil.isPolyExpression(psiExpression));
}
public void testConditionalInAssignment() throws Exception {
myFixture.configureByText("Foo.java", "class Foo {" +
" public static void main(String[] args) {\n" +
" Object obj = new Object();\n" +
" String str = \"\";\n" +
" str += args.length == 0 <caret>? obj : args[0];\n" +
" }" +
"}");
final PsiElement elementAtCaret = myFixture.getFile().findElementAt(myFixture.getCaretOffset());
assertNotNull(elementAtCaret);
final PsiExpression psiExpression = PsiTreeUtil.getParentOfType(elementAtCaret, PsiExpression.class);
assertInstanceOf(psiExpression, PsiConditionalExpression.class);
assertFalse(PsiPolyExpressionUtil.isPolyExpression(psiExpression));
}
private PsiExpression findExpression(String textWithExpression) {
myFixture.configureByText("Foo.java", "import java.util.*;" +
"class Foo {" +
@@ -1,5 +1,5 @@
/*
* 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.
@@ -1116,6 +1116,31 @@ class Foo {
\t}
}""");
}
public void testCollapseExistingButExpandedBlock() {
String text = '''class Foo {
void m {
if (true) {
System.out.println();
}
}
}
'''
configure text
myFixture.editor.caretModel.moveToOffset(text.indexOf("System"))
myFixture.performEditorAction("CollapseBlock")
myFixture.performEditorAction("ExpandAllRegions")
myFixture.editor.caretModel.moveToOffset(text.indexOf("System"))
myFixture.performEditorAction("CollapseBlock")
def topLevelRegions = ((FoldingModelEx)myFixture.editor.foldingModel).fetchTopLevel()
assert topLevelRegions.length == 1
assert topLevelRegions[0].startOffset == text.indexOf('{', text.indexOf("if"))
assert topLevelRegions[0].endOffset == text.indexOf('}', text.indexOf("if")) + 1
}
private int getFoldRegionsCount() {
return myFixture.editor.foldingModel.allFoldRegions.length
@@ -0,0 +1,35 @@
/*
* 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.codeInsight.navigation;
import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase;
/**
* @author Dmitry Avdeev
*/
public class RunLineMarkerTest extends LightCodeInsightFixtureTestCase {
public void testRunLineMarker() throws Exception {
myFixture.configureByText("MainTest.java", "public class MainTest {\n" +
" public static void fo<caret>o(String[] args) {\n" +
" }\n " +
" public static void main(String[] args) {\n" +
" }\n" +
"}");
assertEquals(0, myFixture.findGuttersAtCaret().size());
assertEquals(2, myFixture.findAllGutters().size());
}
}
@@ -185,7 +185,7 @@ public class BuildDataManager implements StorageOwner {
public void clean() throws IOException {
try {
myTargetStoragesOwner.close();
myTargetStoragesOwner.clean();
myTargetStorages.clear();
}
finally {
@@ -80,6 +80,35 @@ public abstract class SyntaxTraverser<T> extends FilteredTraverser<T, SyntaxTrav
return null;
}
@NotNull
public JBIterable<T> parents(@Nullable final T element) {
return new JBIterable<T>() {
@Override
public Iterator<T> iterator() {
return new Iterator<T>() {
T cur = element;
@Override
public boolean hasNext() {
return cur != null;
}
@Override
public T next() {
T result = cur;
cur = parent(cur);
return result;
}
@Override
public void remove() {
throw new UnsupportedOperationException();
}
};
}
};
}
private abstract static class FirstNextTraverser<T> extends SyntaxTraverser<T> {
public FirstNextTraverser(Meta<T> meta) {
@@ -161,7 +190,8 @@ public abstract class SyntaxTraverser<T> extends FilteredTraverser<T, SyntaxTrav
@Nullable
@Override
public PsiElement parent(@NotNull PsiElement node) {
return node.getParent();
PsiElement parent = node.getParent();
return parent instanceof PsiFile ? null : parent;
}
}
@@ -55,12 +55,13 @@ public class CoreProgressManager extends ProgressManager implements Disposable {
private static final boolean ENABLED = !"disabled".equals(System.getProperty("idea.ProcessCanceledException"));
private final ScheduledFuture<?> myCheckCancelledFuture;
// indicator -> threads which are running under this indicator. guarded by this.
// indicator -> threads which are running under this indicator. guarded by threadsUnderIndicator.
private static final Map<ProgressIndicator, Set<Thread>> threadsUnderIndicator = new THashMap<ProgressIndicator, Set<Thread>>();
// the active indicator for the thread id
private static final ConcurrentLongObjectMap<ProgressIndicator> currentIndicators = ContainerUtil.createConcurrentLongObjectMap();
// threads which are running under canceled indicator
static final Set<Thread> threadsUnderCanceledIndicator = ContainerUtil.newConcurrentSet();
private static volatile boolean thereIsProcessUnderCanceledIndicator;
// active (i.e. which have executeProcessUnderProgress() method running) indicators which are not inherited from StandardProgressIndicator.
// for them an extra processing thread (see myCheckCancelledFuture) has to be run to call their non-standard checkCanceled() method
@@ -89,8 +90,7 @@ public class CoreProgressManager extends ProgressManager implements Disposable {
@Override
protected void doCheckCanceled() throws ProcessCanceledException {
boolean thereIsCanceledIndicator = !threadsUnderCanceledIndicator.isEmpty();
if (thereIsCanceledIndicator) {
if (thereIsProcessUnderCanceledIndicator) {
final ProgressIndicator progress = getProgressIndicator();
if (progress != null && ENABLED) {
progress.checkCanceled();
@@ -421,6 +421,7 @@ public class CoreProgressManager extends ProgressManager implements Disposable {
else {
threadsUnderCanceledIndicator.remove(currentThread);
}
thereIsProcessUnderCanceledIndicator = !threadsUnderCanceledIndicator.isEmpty();
}
try {
@@ -449,6 +450,7 @@ public class CoreProgressManager extends ProgressManager implements Disposable {
else {
threadsUnderCanceledIndicator.remove(currentThread);
}
thereIsProcessUnderCanceledIndicator = !threadsUnderCanceledIndicator.isEmpty();
}
}
}
@@ -473,6 +475,7 @@ public class CoreProgressManager extends ProgressManager implements Disposable {
if (underCancelledIndicator) {
threadsUnderCanceledIndicator.add(thread);
thereIsProcessUnderCanceledIndicator = true;
}
}
}
@@ -1,5 +1,5 @@
/*
* 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.
@@ -362,7 +362,7 @@ public abstract class PsiDocumentManagerBase extends PsiDocumentManager implemen
}
}
protected void doCommit(@NotNull final Document document) {
private void doCommit(@NotNull final Document document) {
assert !myIsCommitInProgress : "Do not call commitDocument() from inside PSI change listener";
ApplicationManager.getApplication().runWriteAction(new Runnable() {
@Override
@@ -782,7 +782,7 @@ public abstract class PsiDocumentManagerBase extends PsiDocumentManager implemen
}
char[] fileText = psiFile.textToCharArray();
@SuppressWarnings({"NonConstantStringShouldBeStringBuffer"})
@SuppressWarnings("NonConstantStringShouldBeStringBuffer")
@NonNls String error = "File '" + psiFile.getName() + "' text mismatch after reparse. " +
"File length=" + fileText.length + "; Doc length=" + documentLength + "\n";
int i = 0;
@@ -145,7 +145,7 @@ public class SelfElementInfo implements SmartPointerElementInfo {
mySyncMarkerIsValid = false;
}
}
myRangeMarker = null; // clear hard ref to avoid leak, hold soft ref for not recreating marker later
myRangeMarker = null; // clear hard ref to avoid leak, but hold soft ref (in myMarkerRef) for not recreating marker too often
}
@Override
@@ -169,11 +169,11 @@ public class SelfElementInfo implements SmartPointerElementInfo {
return restoreFileFromVirtual(myVirtualFile, myProject, myLanguage);
}
protected static PsiElement findElementInside(@NotNull PsiFile file,
int syncStartOffset,
int syncEndOffset,
@NotNull Class type,
@NotNull Language language) {
static PsiElement findElementInside(@NotNull PsiFile file,
int syncStartOffset,
int syncEndOffset,
@NotNull Class type,
@NotNull Language language) {
PsiElement anchor = file.getViewProvider().findElementAt(syncStartOffset, language);
if (anchor == null) return null;
@@ -266,11 +266,11 @@ public class SelfElementInfo implements SmartPointerElementInfo {
});
}
protected int getSyncEndOffset() {
int getSyncEndOffset() {
return mySyncEndOffset;
}
protected int getSyncStartOffset() {
int getSyncStartOffset() {
return mySyncStartOffset;
}
@@ -1,5 +1,5 @@
/*
* 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.
@@ -20,7 +20,7 @@ import org.jetbrains.annotations.NotNull;
import java.util.EventListener;
/**
* @see {@link com.intellij.openapi.editor.EditorFactory#addEditorFactoryListener(com.intellij.openapi.editor.event.EditorFactoryListener, com.intellij.openapi.Disposable)}
* @see {@link com.intellij.openapi.editor.EditorFactory#addEditorFactoryListener(EditorFactoryListener, com.intellij.openapi.Disposable)}
*/
public interface EditorFactoryListener extends EventListener {
/**
@@ -102,7 +102,7 @@ public class ExternalSystemShortcutsManager implements Disposable {
KeymapManager keymapManager = KeymapManager.getInstance();
if (keymapManager != null) {
listenTo(keymapManager.getActiveKeymap());
keymapManager.addKeymapManagerListener(this);
keymapManager.addKeymapManagerListener(this, ExternalSystemShortcutsManager.this);
}
}
@@ -129,10 +129,6 @@ public class ExternalSystemShortcutsManager implements Disposable {
private void stopListen() {
listenTo(null);
KeymapManager keymapManager = KeymapManager.getInstance();
if (keymapManager != null) {
keymapManager.removeKeymapManagerListener(this);
}
}
}
@@ -0,0 +1,35 @@
/*
* 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.lang;
import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.NotNull;
import java.util.List;
/**
* @author gregsh
*/
public abstract class ExpressionTypeProvider<T extends PsiElement> {
@NotNull
public abstract String getInformationHint(@NotNull T element);
@NotNull
public abstract String getErrorHint();
@NotNull
public abstract List<T> getExpressionsAt(@NotNull PsiElement elementAt);
}
@@ -0,0 +1,28 @@
/*
* Copyright 2000-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* @author max
*/
package com.intellij.lang;
public class LanguageExpressionTypes extends LanguageExtension<ExpressionTypeProvider> {
public static final LanguageExpressionTypes INSTANCE = new LanguageExpressionTypes();
private LanguageExpressionTypes() {
super("com.intellij.codeInsight.typeInfo");
}
}
@@ -954,13 +954,13 @@ public class DocumentationManager extends DockablePopupManager<DocumentationComp
BrowserUtil.browse(url1);
return "";
}
else if (url.startsWith("..")) {
return CodeInsightBundle.message("javadoc.error.resolving.url", url);
}
else {
else if (BrowserUtil.isAbsoluteURL(url)) {
BrowserUtil.browse(url);
return "";
}
else {
return CodeInsightBundle.message("javadoc.error.resolving.url", url);
}
}
@Override
@@ -0,0 +1,123 @@
/*
* 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.codeInsight.hint;
import com.intellij.codeInsight.CodeInsightActionHandler;
import com.intellij.codeInsight.TargetElementUtil;
import com.intellij.lang.ExpressionTypeProvider;
import com.intellij.lang.Language;
import com.intellij.lang.LanguageExpressionTypes;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.ex.util.EditorUtil;
import com.intellij.openapi.project.DumbService;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Pass;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.refactoring.IntroduceTargetChooser;
import com.intellij.util.Function;
import com.intellij.util.ObjectUtils;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.JBIterable;
import org.jetbrains.annotations.NotNull;
import java.util.Map;
import java.util.Set;
public class ShowExpressionTypeHandler implements CodeInsightActionHandler {
@Override
public boolean startInWriteAction() {
return false;
}
public void invoke(@NotNull final Project project, @NotNull final Editor editor, @NotNull PsiFile file) {
ApplicationManager.getApplication().assertIsDispatchThread();
PsiDocumentManager.getInstance(project).commitAllDocuments();
PsiElement elementAt = file.findElementAt(
TargetElementUtil.adjustOffset(file, editor.getDocument(), editor.getCaretModel().getOffset()));
if (elementAt == null) return;
Language language = elementAt.getLanguage();
final Set<ExpressionTypeProvider> handlers = getHandlers(project, language, file.getViewProvider().getBaseLanguage());
if (handlers.isEmpty()) return;
TextRange range = EditorUtil.getSelectionInAnyMode(editor);
final Map<PsiElement, ExpressionTypeProvider> map = ContainerUtil.newLinkedHashMap();
for (ExpressionTypeProvider handler : handlers) {
for (PsiElement element : ((ExpressionTypeProvider<? extends PsiElement>)handler).getExpressionsAt(elementAt)) {
if (!element.getTextRange().contains(range)) continue;
map.put(element, handler);
}
}
Pass<PsiElement> callback = new Pass<PsiElement>() {
@Override
public void pass(@NotNull PsiElement expression) {
//noinspection unchecked
ExpressionTypeProvider<PsiElement> provider = ObjectUtils.assertNotNull(map.get(expression));
final String informationHint = provider.getInformationHint(expression);
TextRange range = expression.getTextRange();
editor.getSelectionModel().setSelection(range.getStartOffset(), range.getEndOffset());
ApplicationManager.getApplication().invokeLater(new Runnable() {
@Override
public void run() {
HintManager.getInstance().showInformationHint(editor, informationHint);
}
});
}
};
if (map.isEmpty()) {
ApplicationManager.getApplication().invokeLater(new Runnable() {
@Override
public void run() {
String errorHint = ObjectUtils.assertNotNull(ContainerUtil.getFirstItem(handlers)).getErrorHint();
HintManager.getInstance().showErrorHint(editor, errorHint);
}
});
}
else if (map.size() == 1) {
callback.pass(ObjectUtils.assertNotNull(ContainerUtil.getFirstItem(map.keySet())));
}
else {
IntroduceTargetChooser.showChooser(
editor, ContainerUtil.newArrayList(map.keySet()), callback,
new Function<PsiElement, String>() {
@Override
public String fun(@NotNull PsiElement expression) {
return expression.getText();
}
}
);
}
}
@NotNull
public static Set<ExpressionTypeProvider> getHandlers(final Project project, Language... languages) {
return JBIterable.of(languages).flatten(new Function<Language, Iterable<ExpressionTypeProvider>>() {
@Override
public Iterable<ExpressionTypeProvider> fun(Language language) {
return DumbService.getInstance(project).filterByDumbAwareness(LanguageExpressionTypes.INSTANCE.allForLanguage(language));
}
}).addAllTo(ContainerUtil.<ExpressionTypeProvider>newLinkedHashSet());
}
}
@@ -0,0 +1,47 @@
/*
* 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.codeInsight.hint.actions;
import com.intellij.codeInsight.CodeInsightActionHandler;
import com.intellij.codeInsight.actions.BaseCodeInsightAction;
import com.intellij.codeInsight.hint.ShowExpressionTypeHandler;
import com.intellij.lang.Language;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.DumbAware;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiFile;
import com.intellij.psi.util.PsiUtilCore;
import org.jetbrains.annotations.NotNull;
public class ShowExpressionTypeAction extends BaseCodeInsightAction implements DumbAware {
public ShowExpressionTypeAction() {
setEnabledInModalContext(true);
}
@NotNull
@Override
protected CodeInsightActionHandler getHandler() {
return new ShowExpressionTypeHandler();
}
@Override
protected boolean isValidForFile(@NotNull Project project, @NotNull Editor editor, @NotNull final PsiFile file) {
Language language = PsiUtilCore.getLanguageAtOffset(file, editor.getCaretModel().getOffset());
return !ShowExpressionTypeHandler.getHandlers(project, language, file.getViewProvider().getBaseLanguage()).isEmpty();
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2011 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.
@@ -15,6 +15,7 @@
*/
package com.intellij.openapi.keymap;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.application.ApplicationManager;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
@@ -35,7 +36,11 @@ public abstract class KeymapManager {
return ApplicationManager.getApplication().getComponent(KeymapManager.class);
}
/**
* @deprecated use {@link KeymapManager#addKeymapManagerListener(KeymapManagerListener, Disposable)} instead
*/
public abstract void addKeymapManagerListener(@NotNull KeymapManagerListener listener);
public abstract void addKeymapManagerListener(@NotNull KeymapManagerListener listener, @NotNull Disposable parentDisposable);
public abstract void removeKeymapManagerListener(@NotNull KeymapManagerListener listener);
}
@@ -30,8 +30,10 @@ import javax.swing.event.TreeSelectionListener;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreePath;
import javax.swing.tree.TreeSelectionModel;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.Arrays;
/**
* @author Konstantin Bulenkov
@@ -98,8 +100,18 @@ class TreeToolbarDecorator extends ToolbarDecorator {
@Override
public void run(AnActionButton button) {
myTree.stopEditing();
final TreePath path = myTree.getSelectionPath();
model.removeNode(path);
if (myTree.getSelectionModel().getSelectionMode() == TreeSelectionModel.SINGLE_TREE_SELECTION) {
final TreePath path = myTree.getSelectionPath();
if (path != null) {
model.removeNode(path);
}
}
else {
final TreePath[] paths = myTree.getSelectionPaths();
if (paths != null && paths.length > 0) {
model.removeNodes(Arrays.asList(paths));
}
}
}
};
}
@@ -1,5 +1,5 @@
/*
* 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.
@@ -67,7 +67,7 @@ public class QuickAccessSettings implements ApplicationComponent, KeymapManagerL
}, this);
KeymapManager kmMgr = KeymapManager.getInstance();
kmMgr.addKeymapManagerListener(this);
kmMgr.addKeymapManagerListener(this, this);
activeKeymapChanged(kmMgr.getActiveKeymap());
@@ -76,7 +76,6 @@ public class QuickAccessSettings implements ApplicationComponent, KeymapManagerL
@Override
public void disposeComponent() {
KeymapManager.getInstance().removeKeymapManagerListener(this);
Disposer.dispose(this);
}
@@ -16,8 +16,12 @@
package com.intellij.ide.ui.laf;
import com.intellij.ide.ui.laf.darcula.DarculaLaf;
import com.intellij.openapi.util.SystemInfo;
import javax.swing.*;
import javax.swing.plaf.FontUIResource;
import javax.swing.plaf.metal.DefaultMetalTheme;
import java.awt.*;
/**
* @author Konstantin Bulenkov
@@ -37,4 +41,20 @@ public class IntelliJLaf extends DarculaLaf {
protected DefaultMetalTheme createMetalTheme() {
return new IdeaBlueMetalTheme();
}
@Override
public UIDefaults getDefaults() {
UIDefaults defaults = super.getDefaults();
if (SystemInfo.isMacOSYosemite) {
installMacOSXFonts(defaults);
}
return defaults;
}
private static void installMacOSXFonts(UIDefaults defaults) {
FontUIResource font = new FontUIResource("HelveticaNeue-CondensedBlack", Font.PLAIN, 13);
defaults.put("Label.font", font);
defaults.put("CheckBox.font", font);
defaults.put("RadioButton.font", font);
}
}
@@ -46,7 +46,6 @@ public class DarculaCheckBoxUI extends MetalCheckBoxUI {
public synchronized void paint(Graphics g2d, JComponent c) {
Graphics2D g = (Graphics2D)g2d;
JCheckBox b = (JCheckBox) c;
final ButtonModel model = b.getModel();
final Dimension size = c.getSize();
final Font font = c.getFont();
@@ -72,6 +71,11 @@ public class DarculaCheckBoxUI extends MetalCheckBoxUI {
final boolean selected = b.isSelected();
final boolean enabled = b.isEnabled();
drawCheckIcon(c, g, b, iconRect, selected, enabled);
drawText(c, g, b, fm, textRect, text);
}
protected void drawCheckIcon(JComponent c, Graphics2D g, JCheckBox b, Rectangle iconRect, boolean selected, boolean enabled) {
if (selected && b.getSelectedIcon() != null) {
b.getSelectedIcon().paintIcon(b, g, iconRect.x + JBUI.scale(4), iconRect.y + JBUI.scale(2));
} else if (!selected && b.getIcon() != null) {
@@ -85,7 +89,7 @@ public class DarculaCheckBoxUI extends MetalCheckBoxUI {
g.translate(x, y);
final Paint paint = UIUtil.getGradientPaint(w / 2, 0, b.getBackground().brighter(),
w / 2, h, b.getBackground());
w / 2, h, b.getBackground());
g.setPaint(paint);
final int fillOffset = JBUI.scale(1);
g.fillRect(fillOffset, fillOffset, w - 2*fillOffset, h - 2*fillOffset);
@@ -123,14 +127,16 @@ public class DarculaCheckBoxUI extends MetalCheckBoxUI {
g.translate(-x, -y);
config.restore();
}
}
protected void drawText(JComponent c, Graphics2D g, JCheckBox b, FontMetrics fm, Rectangle textRect, String text) {
//text
if(text != null) {
View view = (View) c.getClientProperty(BasicHTML.propertyKey);
if (view != null) {
view.paint(g, textRect);
} else {
g.setColor(model.isEnabled() ? b.getForeground() : getDisabledTextColor());
g.setColor(b.isEnabled() ? b.getForeground() : getDisabledTextColor());
SwingUtilities2.drawStringUnderlineCharAt(c, g, text,
b.getDisplayedMnemonicIndex(),
textRect.x,
@@ -351,11 +351,11 @@ public class DarculaComboBoxUI extends BasicComboBoxUI implements Border {
g.setColor(editor.getBackground());
g.fillRect(xxx, y + 1, 5, H);
} else {
g.setColor(UIUtil.getPanelBackground());
g.setColor(comboBox.getBackground());
g.fillRoundRect(x + 1, y + 1, W, H, R, R);
g.setColor(getArrowButtonFillColor(arrowButton.getBackground()));
g.fillRoundRect(xxx, y + 1, width - xxx, H, R, R);
g.setColor(UIUtil.getPanelBackground());
g.setColor(comboBox.getBackground());
g.fillRect(xxx, y + 1, 5, H);
}
final Color borderColor = getBorderColor();//ColorUtil.shift(UIUtil.getBorderColor(), 4);
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

@@ -0,0 +1,57 @@
/*
* 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.ide.ui.laf.intellij;
import com.intellij.openapi.util.IconLoader;
import com.intellij.util.ui.EmptyIcon;
import javax.swing.*;
import javax.swing.plaf.ComponentUI;
import java.awt.*;
/**
* @author Konstantin Bulenkov
*/
public class MacIntelliJCheckBoxUI extends IntelliJCheckBoxUI {
public static final Icon DEFAULT_ICON = EmptyIcon.create(14);
@SuppressWarnings({"MethodOverridesStaticMethodOfSuperclass", "UnusedDeclaration"})
public static ComponentUI createUI(JComponent c) {
return new MacIntelliJCheckBoxUI();
}
@Override
protected void drawCheckIcon(JComponent c, Graphics2D g, JCheckBox b, Rectangle iconRect, boolean selected, boolean enabled) {
Icon icon;
if (selected) {
icon = IconLoader.findIcon("/com/intellij/ide/ui/laf/icons/checkboxSelectedMac.png", MacIntelliJCheckBoxUI.class, true);
} else {
icon = IconLoader.findIcon("/com/intellij/ide/ui/laf/icons/checkboxMac.png", MacIntelliJCheckBoxUI.class, true);
}
if (icon != null) {
icon.paintIcon(c, g, iconRect.x, iconRect.y);
}
}
@Override
public Icon getDefaultIcon() {
return DEFAULT_ICON;
}
private static boolean isGraphite() {
return false;
}
}
@@ -0,0 +1,12 @@
intellijlaf.background=ececec
window=ececec
CheckBoxUI=com.intellij.ide.ui.laf.intellij.MacIntelliJCheckBoxUI
Panel.background=ececec
PopupMenu.translucentBackground=ececec
Spinner.background=ececec
Spinner.darcula.disabledButtonColor=ececec
SplitPane.highlight=ececec
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2010 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.
@@ -16,6 +16,7 @@
package com.intellij.openapi.fileEditor.impl;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.wm.IdeFrame;
@@ -71,6 +72,7 @@ public class DockableEditorContainerFactory implements DockContainerFactory.Pers
splitters.createCurrentWindow();
}
final DockableEditorTabbedContainer container = new DockableEditorTabbedContainer(myProject, splitters, true);
Disposer.register(container, splitters);
containerRef.set(container);
container.getSplitters().startListeningFocus();
return container;
@@ -18,6 +18,7 @@ package com.intellij.openapi.fileEditor.impl;
import com.intellij.ide.IdeBundle;
import com.intellij.ide.ui.UISettings;
import com.intellij.ide.ui.UISettingsListener;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ModalityState;
import com.intellij.openapi.components.ServiceManager;
@@ -70,7 +71,7 @@ import java.util.concurrent.CopyOnWriteArraySet;
/**
* Author: msk
*/
public class EditorsSplitters extends IdePanePanel implements UISettingsListener {
public class EditorsSplitters extends IdePanePanel implements UISettingsListener, Disposable {
private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.fileEditor.impl.EditorsSplitters");
private static final String PINNED = "pinned";
private static final String CURRENT_IN_TAB = "current-in-tab";
@@ -84,13 +85,12 @@ public class EditorsSplitters extends IdePanePanel implements UISettingsListener
private final FileEditorManagerImpl myManager;
private Element mySplittersElement; // temporarily used during initialization
int myInsideChange = 0;
int myInsideChange;
private final MyFocusWatcher myFocusWatcher;
private final Alarm myIconUpdaterAlarm = new Alarm();
private final KeymapManagerListener myKeymapListener;
private final UIBuilder myUIBuilder = new UIBuilder();
public EditorsSplitters(final FileEditorManagerImpl manager, DockManager dockManager, boolean createOwnDockableContainer) {
EditorsSplitters(final FileEditorManagerImpl manager, DockManager dockManager, boolean createOwnDockableContainer) {
super(new BorderLayout());
myManager = manager;
myFocusWatcher = new MyFocusWatcher();
@@ -102,15 +102,15 @@ public class EditorsSplitters extends IdePanePanel implements UISettingsListener
Disposer.register(manager.getProject(), dockable);
dockManager.register(dockable);
}
myKeymapListener = new KeymapManagerListener() {
KeymapManagerListener keymapListener = new KeymapManagerListener() {
@Override
public void activeKeymapChanged(Keymap keymap) {
invalidate();
repaint();
}
};
KeymapManager.getInstance().addKeymapManagerListener(myKeymapListener);
UISettings.getInstance().addUISettingsListener(this);
KeymapManager.getInstance().addKeymapManagerListener(keymapListener, this);
UISettings.getInstance().addUISettingsListener(this, this);
}
public FileEditorManagerImpl getManager() {
@@ -127,7 +127,7 @@ public class EditorsSplitters extends IdePanePanel implements UISettingsListener
repaint (); // revalidate doesn't repaint correctly after "Close All"
}
public void startListeningFocus() {
void startListeningFocus() {
myFocusWatcher.install(this);
}
@@ -135,11 +135,10 @@ public class EditorsSplitters extends IdePanePanel implements UISettingsListener
myFocusWatcher.deinstall(this);
}
@Override
public void dispose() {
myIconUpdaterAlarm.cancelAllRequests();
stopListeningFocus();
KeymapManager.getInstance().removeKeymapManagerListener(myKeymapListener);
UISettings.getInstance().removeUISettingsListener(this);
}
@Nullable
@@ -151,7 +150,7 @@ public class EditorsSplitters extends IdePanePanel implements UISettingsListener
}
protected boolean showEmptyText() {
private boolean showEmptyText() {
return myCurrentWindow == null || myCurrentWindow.getFiles().length == 0;
}
@@ -179,7 +178,7 @@ public class EditorsSplitters extends IdePanePanel implements UISettingsListener
}
}
@SuppressWarnings({"HardCodedStringLiteral"})
@SuppressWarnings("HardCodedStringLiteral")
private Element writePanel(final JPanel panel) {
final Component comp = panel.getComponent(0);
if (comp instanceof Splitter) {
@@ -315,7 +314,7 @@ public class EditorsSplitters extends IdePanePanel implements UISettingsListener
}
@NotNull public VirtualFile[] getOpenFiles() {
final ArrayListSet<VirtualFile> files = new ArrayListSet<VirtualFile>();
final Set<VirtualFile> files = new ArrayListSet<VirtualFile>();
for (final EditorWindow myWindow : myWindows) {
final EditorWithProviderComposite[] editors = myWindow.getEditors();
for (final EditorWithProviderComposite editor : editors) {
@@ -331,7 +330,7 @@ public class EditorsSplitters extends IdePanePanel implements UISettingsListener
}
@NotNull public VirtualFile[] getSelectedFiles() {
final ArrayListSet<VirtualFile> files = new ArrayListSet<VirtualFile>();
final Set<VirtualFile> files = new ArrayListSet<VirtualFile>();
for (final EditorWindow window : myWindows) {
final VirtualFile file = window.getSelectedFile();
if (file != null) {
@@ -397,7 +396,7 @@ public class EditorsSplitters extends IdePanePanel implements UISettingsListener
}, 200, ModalityState.stateForComponent(this));
}
public void updateFileColor(@NotNull final VirtualFile file) {
void updateFileColor(@NotNull final VirtualFile file) {
final Collection<EditorWindow> windows = findWindows(file);
for (final EditorWindow window : windows) {
final int index = window.findEditorIndex(window.findFileComposite(file));
@@ -420,14 +419,14 @@ public class EditorsSplitters extends IdePanePanel implements UISettingsListener
}
}
public void setTabLayoutPolicy(int scrollTabLayout) {
void setTabLayoutPolicy(int scrollTabLayout) {
final EditorWindow[] windows = getWindows();
for (int i = 0; i != windows.length; ++ i) {
windows[i].setTabLayoutPolicy(scrollTabLayout);
}
}
public void updateFileName(final VirtualFile updatedFile) {
void updateFileName(final VirtualFile updatedFile) {
final EditorWindow[] windows = getWindows();
for (int i = 0; i != windows.length; ++ i) {
windows [i].updateFileName(updatedFile);
@@ -457,7 +456,7 @@ public class EditorsSplitters extends IdePanePanel implements UISettingsListener
return frame;
}
public boolean isInsideChange() {
boolean isInsideChange() {
return myInsideChange > 0;
}
@@ -468,14 +467,14 @@ public class EditorsSplitters extends IdePanePanel implements UISettingsListener
myCurrentWindow = currentWindow;
}
public void updateFileBackgroundColor(@NotNull VirtualFile file) {
void updateFileBackgroundColor(@NotNull VirtualFile file) {
final EditorWindow[] windows = getWindows();
for (int i = 0; i != windows.length; ++ i) {
windows [i].updateFileBackgroundColor(file);
}
}
public int getSplitCount() {
int getSplitCount() {
if (getComponentCount() > 0) {
JPanel panel = (JPanel) getComponent(0);
return getSplitCount(panel);
@@ -502,7 +501,7 @@ public class EditorsSplitters extends IdePanePanel implements UISettingsListener
}
@Nullable
public JBTabs getTabsAt(RelativePoint point) {
JBTabs getTabsAt(RelativePoint point) {
Point thisPoint = point.getPoint(this);
Component c = SwingUtilities.getDeepestComponentAt(this, thisPoint.x, thisPoint.y);
while (c != null) {
@@ -515,7 +514,7 @@ public class EditorsSplitters extends IdePanePanel implements UISettingsListener
return null;
}
public boolean isEmptyVisible() {
boolean isEmptyVisible() {
EditorWindow[] windows = getWindows();
for (EditorWindow each : windows) {
if (!each.isEmptyVisible()) {
@@ -526,7 +525,7 @@ public class EditorsSplitters extends IdePanePanel implements UISettingsListener
}
@Nullable
public VirtualFile findNextFile(final VirtualFile file) {
private VirtualFile findNextFile(final VirtualFile file) {
final EditorWindow[] windows = getWindows(); // TODO: use current file as base
for (int i = 0; i != windows.length; ++i) {
final VirtualFile[] files = windows[i].getFiles();
@@ -618,7 +617,7 @@ public class EditorsSplitters extends IdePanePanel implements UISettingsListener
return getCurrentWindow();
}
public void createCurrentWindow() {
void createCurrentWindow() {
LOG.assertTrue(myCurrentWindow == null);
setCurrentWindow(createEditorWindow());
add(myCurrentWindow.myPanel, BorderLayout.CENTER);
@@ -634,7 +633,7 @@ public class EditorsSplitters extends IdePanePanel implements UISettingsListener
* @param window a window to be set as current
* @param requestFocus whether to request focus to the editor currently selected in this window
*/
public void setCurrentWindow(@Nullable final EditorWindow window, final boolean requestFocus) {
void setCurrentWindow(@Nullable final EditorWindow window, final boolean requestFocus) {
final EditorWithProviderComposite newEditor = window == null ? null : window.getSelectedEditor();
Runnable fireRunnable = new Runnable() {
@@ -704,7 +703,7 @@ public class EditorsSplitters extends IdePanePanel implements UISettingsListener
}
@NotNull
public List<EditorWindow> findWindows(final VirtualFile file) {
private List<EditorWindow> findWindows(final VirtualFile file) {
List<EditorWindow> res = new ArrayList<EditorWindow>();
for (final EditorWindow window : myWindows) {
if (window.findFileComposite(file) != null) {
@@ -718,12 +717,13 @@ public class EditorsSplitters extends IdePanePanel implements UISettingsListener
return myWindows.toArray(new EditorWindow [myWindows.size()]);
}
@NotNull public EditorWindow[] getOrderedWindows() {
@NotNull
EditorWindow[] getOrderedWindows() {
final List<EditorWindow> res = new ArrayList<EditorWindow>();
// Collector for windows in tree ordering:
class Inner{
final void collect(final JPanel panel){
private final void collect(final JPanel panel){
final Component comp = panel.getComponent(0);
if (comp instanceof Splitter) {
final Splitter splitter = (Splitter)comp;
@@ -122,7 +122,7 @@ public class FileEditorManagerImpl extends FileEditorManagerEx implements Projec
/**
* Removes invalid myEditor and updates "modified" status.
*/
private final MyEditorPropertyChangeListener myEditorPropertyChangeListener = new MyEditorPropertyChangeListener();
private final PropertyChangeListener myEditorPropertyChangeListener = new MyEditorPropertyChangeListener();
private final DockManager myDockManager;
private DockableEditorContainerFactory myContentFactory;
private final EditorHistoryManager myEditorHistoryManager;
@@ -288,6 +288,7 @@ public class FileEditorManagerImpl extends FileEditorManagerEx implements Projec
panel.setOpaque(false);
panel.setBorder(new MyBorder());
mySplitters = new EditorsSplitters(this, myDockManager, true);
Disposer.register(myProject, mySplitters);
panel.add(mySplitters, BorderLayout.CENTER);
myPanels = panel;
}
@@ -1511,11 +1512,8 @@ public class FileEditorManagerImpl extends FileEditorManagerEx implements Projec
@Override
public void projectClosed() {
//myFocusWatcher.deinstall(myWindows.getComponent ());
getMainSplitters().dispose();
// Dispose created editors. We do not use use closeEditor method because
// it fires event and changes history.
// Dispose created editors. We do not use use closeEditor method because
// it fires event and changes history.
closeAllFiles();
}
@@ -1,5 +1,5 @@
/*
* 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.
@@ -23,6 +23,7 @@ import com.intellij.openapi.preview.PreviewPanelProvider;
import com.intellij.openapi.preview.PreviewProviderId;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.wm.IdeFocusManager;
@@ -38,14 +39,15 @@ public class FilePreviewPanelProvider extends PreviewPanelProvider<VirtualFile,
private final FileEditorManagerImpl myManager;
private final Project myProject;
private EditorWindow myWindow;
private EditorsSplitters myEditorsSplitters;
private final EditorWindow myWindow;
private final EditorsSplitters myEditorsSplitters;
public FilePreviewPanelProvider(@NotNull Project project, @NotNull FileEditorManagerImpl manager, @NotNull DockManager dockManager) {
super(ID);
myProject = project;
myManager = manager;
myEditorsSplitters = new MyEditorsSplitters(manager, dockManager, false);
Disposer.register(this, myEditorsSplitters);
myEditorsSplitters.createCurrentWindow();
myWindow = myEditorsSplitters.getCurrentWindow();
myWindow.setTabsPlacement(UISettings.TABS_NONE);
@@ -53,7 +55,6 @@ public class FilePreviewPanelProvider extends PreviewPanelProvider<VirtualFile,
@Override
public void dispose() {
myEditorsSplitters.dispose();
}
@NotNull
@@ -120,7 +121,7 @@ public class FilePreviewPanelProvider extends PreviewPanelProvider<VirtualFile,
}
private class MyEditorsSplitters extends EditorsSplitters {
public MyEditorsSplitters(final FileEditorManagerImpl manager, DockManager dockManager, boolean createOwnDockableContainer) {
private MyEditorsSplitters(final FileEditorManagerImpl manager, DockManager dockManager, boolean createOwnDockableContainer) {
super(manager, dockManager, createOwnDockableContainer);
}
@@ -1,5 +1,5 @@
/*
* 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.
@@ -16,6 +16,7 @@
package com.intellij.openapi.keymap.impl;
import com.intellij.ide.WelcomeWizardUtil;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.actionSystem.IdeActions;
import com.intellij.openapi.components.*;
import com.intellij.openapi.keymap.Keymap;
@@ -25,6 +26,7 @@ import com.intellij.openapi.options.BaseSchemeProcessor;
import com.intellij.openapi.options.SchemesManager;
import com.intellij.openapi.options.SchemesManagerFactory;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.InvalidDataException;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.util.registry.Registry;
@@ -56,28 +58,27 @@ public class KeymapManagerImpl extends KeymapManagerEx implements PersistentStat
public static boolean ourKeymapManagerInitialized = false;
KeymapManagerImpl(DefaultKeymap defaultKeymap, SchemesManagerFactory factory) {
mySchemesManager = factory.createSchemesManager(KEYMAPS_DIR_PATH,
new BaseSchemeProcessor<KeymapImpl>() {
@NotNull
@Override
public KeymapImpl readScheme(@NotNull Element element) throws InvalidDataException {
KeymapImpl keymap = new KeymapImpl();
keymap.readExternal(element, getAllIncludingDefaultsKeymaps());
return keymap;
}
BaseSchemeProcessor<KeymapImpl> schemeProcessor = new BaseSchemeProcessor<KeymapImpl>() {
@NotNull
@Override
public KeymapImpl readScheme(@NotNull Element element) throws InvalidDataException {
KeymapImpl keymap = new KeymapImpl();
keymap.readExternal(element, getAllIncludingDefaultsKeymaps());
return keymap;
}
@Override
public Element writeScheme(@NotNull final KeymapImpl scheme) {
return scheme.writeExternal();
}
@Override
public Element writeScheme(@NotNull final KeymapImpl scheme) {
return scheme.writeExternal();
}
@NotNull
@Override
public State getState(@NotNull KeymapImpl scheme) {
return scheme.canModify() ? State.POSSIBLY_CHANGED : State.NON_PERSISTENT;
}
},
RoamingType.PER_USER);
@NotNull
@Override
public State getState(@NotNull KeymapImpl scheme) {
return scheme.canModify() ? State.POSSIBLY_CHANGED : State.NON_PERSISTENT;
}
};
mySchemesManager = factory.createSchemesManager(KEYMAPS_DIR_PATH, schemeProcessor, RoamingType.PER_USER);
Keymap[] keymaps = defaultKeymap.getKeymaps();
String systemDefaultKeymap = WelcomeWizardUtil.getWizardMacKeymap() != null
@@ -231,6 +232,18 @@ public class KeymapManagerImpl extends KeymapManagerEx implements PersistentStat
myListeners.add(listener);
}
@Override
public void addKeymapManagerListener(@NotNull final KeymapManagerListener listener, @NotNull Disposable parentDisposable) {
pollQueue();
myListeners.add(listener);
Disposer.register(parentDisposable, new Disposable() {
@Override
public void dispose() {
removeKeymapManagerListener(listener);
}
});
}
private void pollQueue() {
// assume it is safe to remove elements during iteration, as is the case with the COWAL
for (KeymapManagerListener listener : myListeners) {
@@ -37,7 +37,7 @@ public class ColorProgressBar extends JComponent {
private static final Dimension PREFERRED_SIZE = new Dimension(146, 17);
public static final Color GREEN = new JBColor(new Color(0x6cad74), new Color(0x4a8c53));
public static final Color RED = new JBColor(new Color(0xb81708), new Color(0xdb5c5c));
public static final Color RED = new JBColor(new Color(0xd67b76), new Color(0xb25050));
public static final Color BLUE = new JBColor(new Color(1, 68, 208), JBColor.blue);
public static final Color YELLOW = new JBColor(new Color(0xa67a21), new Color(0x91703a));
private static final Color SHADOW1 = new JBColor(Gray._190, UIUtil.getBorderColor()) ;
@@ -42,11 +42,11 @@ public abstract class ProjectManagerEx extends ProjectManager {
@Nullable
public abstract Project loadProject(@NotNull String filePath) throws IOException, JDOMException, InvalidDataException;
public abstract boolean openProject(Project project);
public abstract boolean openProject(@NotNull Project project);
public abstract boolean isProjectOpened(Project project);
public abstract boolean canClose(Project project);
public abstract boolean canClose(@NotNull Project project);
public abstract void saveChangedProjectFile(@NotNull VirtualFile file, @NotNull Project project);
@@ -71,5 +71,5 @@ public abstract class ProjectManagerEx extends ProjectManager {
}
@Nullable
public abstract Project convertAndLoadProject(String filePath) throws IOException;
public abstract Project convertAndLoadProject(@NotNull String filePath) throws IOException;
}
@@ -75,13 +75,9 @@ import java.io.IOException;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
@State(
name = "ProjectManager",
storages = {
@Storage(
file = StoragePathMacros.APP_CONFIG + "/project.default.xml"
)}
)
@State(name = "ProjectManager", storages = @Storage(
file = StoragePathMacros.APP_CONFIG + "/project.default.xml"
))
public class ProjectManagerImpl extends ProjectManagerEx implements PersistentStateComponent<Element>, ExportableApplicationComponent {
private static final Logger LOG = Logger.getInstance(ProjectManagerImpl.class);
@@ -89,9 +85,9 @@ public class ProjectManagerImpl extends ProjectManagerEx implements PersistentSt
private static final Key<List<ProjectManagerListener>> LISTENERS_IN_PROJECT_KEY = Key.create("LISTENERS_IN_PROJECT_KEY");
@SuppressWarnings({"FieldAccessedSynchronizedAndUnsynchronized"})
@SuppressWarnings("FieldAccessedSynchronizedAndUnsynchronized")
private ProjectImpl myDefaultProject; // Only used asynchronously in save and dispose, which itself are synchronized.
@SuppressWarnings({"FieldAccessedSynchronizedAndUnsynchronized"})
@SuppressWarnings("FieldAccessedSynchronizedAndUnsynchronized")
private Element myDefaultProjectRootElement; // Only used asynchronously in save and dispose, which itself are synchronized.
private boolean myDefaultProjectConfigurationChanged;
@@ -101,13 +97,13 @@ public class ProjectManagerImpl extends ProjectManagerEx implements PersistentSt
private final Set<Project> myTestProjects = new THashSet<Project>();
private final MultiMap<Project, Pair<VirtualFile, StateStorage>> myChangedProjectFiles = MultiMap.createSet();
private final MultiMap<Project, Pair<VirtualFile, StateStorage>> myChangedProjectFiles = MultiMap.createWeakSet(); //guarded by myChangedProjectFiles
private final SingleAlarm myChangedFilesAlarm;
private final List<Pair<VirtualFile, StateStorage>> myChangedApplicationFiles = new SmartList<Pair<VirtualFile, StateStorage>>();
private final AtomicInteger myReloadBlockCount = new AtomicInteger(0);
private final ProgressManager myProgressManager;
private volatile boolean myDefaultProjectWasDisposed = false;
private volatile boolean myDefaultProjectWasDisposed;
private final Runnable restartApplicationOrReloadProjectTask = new Runnable() {
@Override
@@ -119,7 +115,7 @@ public class ProjectManagerImpl extends ProjectManagerEx implements PersistentSt
};
@NotNull
private static List<ProjectManagerListener> getListeners(Project project) {
private static List<ProjectManagerListener> getListeners(@NotNull Project project) {
List<ProjectManagerListener> array = project.getUserData(LISTENERS_IN_PROJECT_KEY);
if (array == null) return Collections.emptyList();
return array;
@@ -222,7 +218,7 @@ public class ProjectManagerImpl extends ProjectManagerEx implements PersistentSt
}
}
public static int TEST_PROJECTS_CREATED = 0;
public static int TEST_PROJECTS_CREATED;
private static final boolean LOG_PROJECT_LEAKAGE_IN_TESTS = false;
private static final int MAX_LEAKY_PROJECTS = 42;
@SuppressWarnings("FieldCanBeLocal") private final Map<Project, String> myProjects = new WeakHashMap<Project, String>();
@@ -234,7 +230,7 @@ public class ProjectManagerImpl extends ProjectManagerEx implements PersistentSt
}
@Nullable
public Project newProject(final String projectName, @NotNull String filePath, boolean useDefaultProjectSettings, boolean isDummy,
public Project newProject(@Nullable String projectName, @NotNull String filePath, boolean useDefaultProjectSettings, boolean isDummy,
boolean optimiseTestLoadSpeed) {
filePath = toCanonicalName(filePath);
@@ -285,7 +281,8 @@ public class ProjectManagerImpl extends ProjectManagerEx implements PersistentSt
}
@NonNls
private static String message(Throwable e) {
@NotNull
private static String message(@NotNull Throwable e) {
String message = e.getMessage();
if (message != null) return message;
message = e.getLocalizedMessage();
@@ -336,7 +333,7 @@ public class ProjectManagerImpl extends ProjectManagerEx implements PersistentSt
: new ProjectImpl(this, new File(filePath).getAbsolutePath(), isOptimiseTestLoadSpeed, projectName);
}
private static void scheduleDispose(final ProjectImpl project) {
private static void scheduleDispose(@NotNull final ProjectImpl project) {
if (project.isDefault()) {
return;
}
@@ -442,7 +439,7 @@ public class ProjectManagerImpl extends ProjectManagerEx implements PersistentSt
}
@Override
public boolean openProject(final Project project) {
public boolean openProject(@NotNull final Project project) {
if (isLight(project)) {
throw new AssertionError("must not open light project");
}
@@ -533,7 +530,7 @@ public class ProjectManagerImpl extends ProjectManagerEx implements PersistentSt
myOpenProjectsArrayCache = myOpenProjects.toArray(new Project[myOpenProjects.size()]);
}
private static void waitForFileWatcher(ProgressIndicator indicator) {
private static void waitForFileWatcher(@NotNull ProgressIndicator indicator) {
LocalFileSystem fs = LocalFileSystem.getInstance();
if (!(fs instanceof LocalFileSystemImpl)) return;
@@ -582,7 +579,7 @@ public class ProjectManagerImpl extends ProjectManagerEx implements PersistentSt
*/
@Override
@Nullable
public Project convertAndLoadProject(String filePath) throws IOException {
public Project convertAndLoadProject(@NotNull String filePath) throws IOException {
final String fp = toCanonicalName(filePath);
final ConversionResult conversionResult = ConversionService.getInstance().convert(fp);
if (conversionResult.openingIsCanceled()) {
@@ -696,9 +693,8 @@ public class ProjectManagerImpl extends ProjectManagerEx implements PersistentSt
}
Collection<Pair<VirtualFile, StateStorage>> causes = new SmartList<Pair<VirtualFile, StateStorage>>();
Collection<Pair<VirtualFile, StateStorage>> changes;
synchronized (myChangedProjectFiles) {
changes = myChangedProjectFiles.remove(project);
Collection<Pair<VirtualFile, StateStorage>> changes = myChangedProjectFiles.remove(project);
if (!ContainerUtil.isEmpty(changes)) {
for (Pair<VirtualFile, StateStorage> change : changes) {
causes.add(change);
@@ -739,6 +735,7 @@ public class ProjectManagerImpl extends ProjectManagerEx implements PersistentSt
}
}
@NotNull
@Override
public Collection<Project> closeTestProject(@NotNull Project project) {
synchronized (myOpenProjects) {
@@ -769,7 +766,9 @@ public class ProjectManagerImpl extends ProjectManagerEx implements PersistentSt
myChangedApplicationFiles.add(Pair.create(file, storage));
}
else {
myChangedProjectFiles.putValue(project, Pair.create(file, storage));
synchronized (myChangedProjectFiles) {
myChangedProjectFiles.putValue(project, Pair.create(file, storage));
}
}
if (storage instanceof StateStorageBase) {
@@ -783,7 +782,9 @@ public class ProjectManagerImpl extends ProjectManagerEx implements PersistentSt
@Override
public void reloadProject(@NotNull Project project) {
myChangedProjectFiles.remove(project);
synchronized (myChangedProjectFiles) {
myChangedProjectFiles.remove(project);
}
doReloadProject(project);
}
@@ -847,7 +848,9 @@ public class ProjectManagerImpl extends ProjectManagerEx implements PersistentSt
myTestProjects.remove(project);
}
myChangedProjectFiles.remove(project);
synchronized (myChangedProjectFiles) {
myChangedProjectFiles.remove(project);
}
fireProjectClosed(project);
@@ -864,6 +867,7 @@ public class ProjectManagerImpl extends ProjectManagerEx implements PersistentSt
return true;
}
@TestOnly
public static boolean isLight(@NotNull Project project) {
return ApplicationManager.getApplication().isUnitTestMode() && project.toString().contains("light_temp_");
}
@@ -873,7 +877,7 @@ public class ProjectManagerImpl extends ProjectManagerEx implements PersistentSt
return closeProject(project, true, true, true);
}
private void fireProjectClosing(Project project) {
private void fireProjectClosing(@NotNull Project project) {
if (LOG.isDebugEnabled()) {
LOG.debug("enter: fireProjectClosing()");
}
@@ -928,7 +932,7 @@ public class ProjectManagerImpl extends ProjectManagerEx implements PersistentSt
LOG.assertTrue(removed);
}
private void fireProjectOpened(Project project) {
private void fireProjectOpened(@NotNull Project project) {
if (LOG.isDebugEnabled()) {
LOG.debug("projectOpened");
}
@@ -943,7 +947,7 @@ public class ProjectManagerImpl extends ProjectManagerEx implements PersistentSt
}
}
private void fireProjectClosed(Project project) {
private void fireProjectClosed(@NotNull Project project) {
if (LOG.isDebugEnabled()) {
LOG.debug("projectClosed");
}
@@ -959,7 +963,7 @@ public class ProjectManagerImpl extends ProjectManagerEx implements PersistentSt
}
@Override
public boolean canClose(Project project) {
public boolean canClose(@NotNull Project project) {
if (LOG.isDebugEnabled()) {
LOG.debug("enter: canClose()");
}
@@ -1057,7 +1061,7 @@ public class ProjectManagerImpl extends ProjectManagerEx implements PersistentSt
private Project myProject;
public VirtualFile[] myFiles;
public UnableToSaveProjectNotification(@NotNull final Project project, final VirtualFile[] readOnlyFiles) {
public UnableToSaveProjectNotification(@NotNull final Project project, @NotNull VirtualFile[] readOnlyFiles) {
super("Project Settings", "Could not save project", "Unable to save project files. Please ensure project files are writable and you have permissions to modify them." +
" <a href=\"\">Try to save project again</a>.", NotificationType.ERROR, new NotificationListener() {
@Override
@@ -32,9 +32,9 @@ import com.intellij.openapi.vfs.impl.ZipHandler;
import com.intellij.openapi.vfs.newvfs.persistent.FSRecords;
import com.intellij.openapi.vfs.newvfs.persistent.FlushingDaemon;
import com.intellij.util.CommonProcessors;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.MultiMap;
import com.intellij.util.io.*;
import gnu.trove.THashMap;
import gnu.trove.THashSet;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -344,10 +344,10 @@ public class JarHandler extends ZipHandler {
}
})));
final List<String> invalidLibraryFilePaths = new ArrayList<String>();
final List<String> allLibraryFilePaths = new ArrayList<String>();
final List<String> invalidLibraryFilePaths = ContainerUtil.newArrayList();
final List<String> allLibraryFilePaths = ContainerUtil.newArrayList();
MultiMap<String, String> jarSnapshotFileToLibraryFilePaths = new MultiMap<String, String>();
Map<String, String> validLibraryFilePathToJarSnapshotFilePaths = new THashMap<String, String>();
Set<String> validLibraryFilePathToJarSnapshotFilePaths = ContainerUtil.newTroveSet();
info.processKeys(new CommonProcessors.CollectProcessor<String>(allLibraryFilePaths));
for(String filePath:allLibraryFilePaths) {
@@ -356,7 +356,7 @@ public class JarHandler extends ZipHandler {
jarSnapshotFileToLibraryFilePaths.putValue(libraryInfo.mySnapshotPath, filePath);
if (new File(filePath).exists()) {
validLibraryFilePathToJarSnapshotFilePaths.put(filePath, libraryInfo.mySnapshotPath);
validLibraryFilePathToJarSnapshotFilePaths.add(filePath);
} else {
invalidLibraryFilePaths.add(filePath);
}
@@ -368,7 +368,7 @@ public class JarHandler extends ZipHandler {
}
for(Map.Entry<String, Collection<String>> e: jarSnapshotFileToLibraryFilePaths.entrySet()) {
for(String libraryFilePath:e.getValue()) {
if (validLibraryFilePathToJarSnapshotFilePaths.containsKey(libraryFilePath)) {
if (validLibraryFilePathToJarSnapshotFilePaths.contains(libraryFilePath)) {
availableLibrarySnapshots.remove(e.getKey());
break;
}
@@ -18,6 +18,7 @@ package com.intellij.openapi.wm.impl;
import com.intellij.featureStatistics.FeatureUsageTracker;
import com.intellij.ide.actions.ActivateToolWindowAction;
import com.intellij.ide.ui.UISettings;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.actionSystem.ActionGroup;
import com.intellij.openapi.actionSystem.ActionManager;
import com.intellij.openapi.actionSystem.ActionPlaces;
@@ -46,7 +47,7 @@ import java.awt.image.BufferedImage;
* @author Eugene Belyaev
* @author Vladimir Kondratyev
*/
public final class StripeButton extends AnchoredButton implements ActionListener {
public final class StripeButton extends AnchoredButton implements ActionListener, Disposable {
private final Color ourBackgroundColor = new Color(247, 243, 239);
/**
@@ -125,7 +126,7 @@ public final class StripeButton extends AnchoredButton implements ActionListener
processDrag(e);
}
});
KeymapManager.getInstance().addKeymapManagerListener(myKeymapListener);
KeymapManager.getInstance().addKeymapManagerListener(myKeymapListener, this);
}
@@ -302,8 +303,7 @@ public final class StripeButton extends AnchoredButton implements ActionListener
setSelected(info.isVisible() || info.isActive());
}
void dispose() {
KeymapManager.getInstance().removeKeymapManagerListener(myKeymapListener);
public void dispose() {
}
private void showPopup(final Component component, final int x, final int y) {
@@ -1,5 +1,5 @@
/*
* 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.
@@ -1295,7 +1295,7 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements
mySideStack.remove(id);
// Destroy stripe button
final StripeButton button = getStripeButton(id);
button.dispose();
Disposer.dispose(button);
myId2StripeButton.remove(id);
//
ToolWindowFocusWatcher watcher = (ToolWindowFocusWatcher)myId2FocusWatcher.remove(id);
@@ -392,6 +392,8 @@ action.ShowSiblings.text=Show Siblings
action.ShowSiblings.description=Show a popup window with the symbol siblings content
action.ParameterInfo.text=_Parameter Info
action.ParameterInfo.description=Show parameters of the method call at caret
action.TypeInfo.text=_Type Info
action.TypeInfo.description=Show type of the selected expression
action.EditorContextInfo.text=_Context Info
action.EditorContextInfo.description=Show the current method or class declaration when it is not visible
action.ShowErrorDescription.text=E_rror Description
@@ -556,6 +556,9 @@
<extensionPoint name="codeInsight.parameterInfo" beanClass="com.intellij.lang.LanguageExtensionPoint">
<with attribute="implementationClass" implements="com.intellij.lang.parameterInfo.ParameterInfoHandler"/>
</extensionPoint>
<extensionPoint name="codeInsight.typeInfo" beanClass="com.intellij.lang.LanguageExtensionPoint">
<with attribute="implementationClass" implements="com.intellij.lang.ExpressionTypeProvider"/>
</extensionPoint>
<extensionPoint name="codeInsight.fillParagraph" beanClass="com.intellij.lang.LanguageExtensionPoint">
<with attribute="implementationClass" implements="com.intellij.codeInsight.editorActions.fillParagraph.ParagraphFillHandler"/>
@@ -422,6 +422,9 @@
<action id="ParameterInfo">
<keyboard-shortcut first-keystroke="control P"/>
</action>
<action id="TypeInfo">
<keyboard-shortcut first-keystroke="control shift P"/>
</action>
<action id="ChangeSignature">
<keyboard-shortcut first-keystroke="control F6"/>
</action>
@@ -165,6 +165,7 @@
<group id="CodeEditorViewGroup">
<action id="ExternalJavaDoc" class="com.intellij.ide.actions.ExternalJavaDocAction"/>
<action id="ParameterInfo" class="com.intellij.codeInsight.hint.actions.ShowParameterInfoAction"/>
<action id="TypeInfo" class="com.intellij.codeInsight.hint.actions.ShowExpressionTypeAction"/>
<action id="EditorContextInfo" class="com.intellij.codeInsight.hint.actions.ShowContainerInfoAction"/>
<action id="ShowErrorDescription" class="com.intellij.codeInsight.daemon.impl.actions.ShowErrorDescriptionAction"/>
</group>
@@ -221,8 +221,7 @@ public class ProjectJdkImpl extends UserDataHolderBase implements JDOMExternaliz
final boolean changes = myHomePath == null? path != null : !myHomePath.equals(path);
myHomePath = path;
if (changes) {
myVersionString = null; // clear cached value if home path changed
myVersionDefined = false;
resetVersionString(); // clear cached value if home path changed
}
}
@@ -389,7 +388,12 @@ public class ProjectJdkImpl extends UserDataHolderBase implements JDOMExternaliz
}
public void update() {
myRootContainer.update();
try {
myRootContainer.update();
}
finally {
resetVersionString();
}
}
@Override
@@ -1,7 +1,21 @@
/*
* 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 org.jetbrains.debugger.sourcemap;
import com.intellij.openapi.editor.Document;
import com.intellij.util.Processor;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -161,8 +175,12 @@ public abstract class MappingList {
return mappings.get(index);
}
public interface MappingsProcessorInLine {
boolean process(@NotNull MappingEntry entry, @Nullable MappingEntry nextEntry);
}
// entries will be processed in this list order
public boolean processMappingsInLine(int line, @NotNull Processor<MappingEntry> entryProcessor) {
public boolean processMappingsInLine(int line, @NotNull MappingsProcessorInLine entryProcessor) {
int low = 0;
int high = mappings.size() - 1;
while (low <= high) {
@@ -176,12 +194,20 @@ public abstract class MappingList {
firstIndex--;
}
MappingEntry entry = mappings.get(firstIndex);
do {
if (!entryProcessor.process(mappings.get(firstIndex))) {
MappingEntry nextEntry = ++firstIndex < mappings.size() ? mappings.get(firstIndex) : null;
if (nextEntry != null && getLine(nextEntry) != line) {
nextEntry = null;
}
if (!entryProcessor.process(entry, nextEntry)) {
return true;
}
entry = nextEntry;
}
while (++firstIndex < mappings.size() && getLine(mappings.get(firstIndex)) == line);
while (entry != null);
return true;
}
else if (line > mappingLine) {
@@ -1,8 +1,22 @@
/*
* 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 org.jetbrains.debugger.sourcemap;
import com.intellij.openapi.util.NullableLazyValue;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.Processor;
import com.intellij.util.Url;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -73,7 +87,7 @@ public class SourceMap {
public boolean processMappingsInLine(@NotNull List<Url> sourceUrls,
int sourceLine,
@NotNull Processor<MappingEntry> mappingProcessor,
@NotNull MappingList.MappingsProcessorInLine mappingProcessor,
@Nullable VirtualFile sourceFile,
@Nullable NullableLazyValue<SourceResolver.Resolver> resolver) {
MappingList mappings = findMappingList(sourceUrls, sourceFile, resolver);
@@ -1,3 +1,18 @@
/*
* 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.jetbrains.javascript.debugger;
import com.intellij.openapi.editor.Document;
@@ -71,4 +86,12 @@ public abstract class JavaScriptDebugAware {
public PsiElement getNavigationElementForSourcemapInspector(@NotNull PsiFile file) {
return null;
}
@Nullable
// return null if unsupported
// cannot be in MemberFilter because creation of MemberFilter could be async
// the problem - GWT mangles name (https://code.google.com/p/google-web-toolkit/issues/detail?id=9106 https://github.com/sdbg/sdbg/issues/6 https://youtrack.jetbrains.com/issue/IDEA-135356), but doesn't add name mappings
public String normalizeMemberName(@NotNull String name) {
return null;
}
}
@@ -32,7 +32,7 @@ import static org.jetbrains.rpc.CommandProcessor.LOG;
public class NameMapper {
public static final String S1 = ",()[]{}=";
private static final CharMatcher NAME_TRIMMER = CharMatcher.INVISIBLE.or(CharMatcher.anyOf(S1 + ".&:"));
protected static final CharMatcher NAME_TRIMMER = CharMatcher.INVISIBLE.or(CharMatcher.anyOf(S1 + ".&:"));
// don't trim trailing .&: - could be part of expression
private static final CharMatcher OPERATOR_TRIMMER = CharMatcher.INVISIBLE.or(CharMatcher.anyOf(S1));
@@ -75,7 +75,7 @@ public class NameMapper {
}
String sourceEntryName = sourceEntry.getName();
String generatedName = extractName(getGeneratedName(generatedDocument, sourceMap, sourceEntry), true);
String generatedName = extractName(getGeneratedName(generatedDocument, sourceMap, sourceEntry));
if (!generatedName.isEmpty()) {
String sourceName = sourceEntryName;
if (sourceName == null) {
@@ -106,8 +106,8 @@ public class NameMapper {
}
@NotNull
protected String extractName(@NotNull CharSequence rawGeneratedName, boolean isLastToken) {
return trimName(rawGeneratedName, isLastToken);
protected String extractName(@NotNull CharSequence rawGeneratedName) {
return NAME_TRIMMER.trimFrom(rawGeneratedName);
}
@NotNull
@@ -296,4 +296,8 @@ public abstract class DebugProcessImpl<C extends VmConnection> extends XDebugPro
return true;
}
}
public void saveResolvedFile(@NotNull Url url, @NotNull VirtualFile file) {
urlToFileCache.putIfAbsent(url, file);
}
}
@@ -27,7 +27,7 @@ public interface MemberFilter {
Collection<Variable> getAdditionalVariables();
@NotNull
String getName(@NotNull Variable variable);
String rawNameToSource(@NotNull Variable variable);
@Nullable
String sourceNameToRaw(@NotNull String name);
@@ -40,7 +40,7 @@ public abstract class MemberFilterBase implements MemberFilter {
@NotNull
@Override
public String getName(@NotNull Variable variable) {
public String rawNameToSource(@NotNull Variable variable) {
return variable.getName();
}
@@ -1,16 +1,31 @@
/*
* 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 org.jetbrains.debugger;
import com.intellij.util.ObjectUtils;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Collections;
import java.util.Map;
public class MemberFilterWithNameMappings extends MemberFilterBase {
protected final Map<String, String> rawNameToSource;
public MemberFilterWithNameMappings(@NotNull Map<String, String> rawNameToSource) {
this.rawNameToSource = rawNameToSource;
public MemberFilterWithNameMappings(@Nullable Map<String, String> rawNameToSource) {
this.rawNameToSource = rawNameToSource == null ? Collections.<String, String>emptyMap() : rawNameToSource;
}
@Override
@@ -20,9 +35,15 @@ public class MemberFilterWithNameMappings extends MemberFilterBase {
@NotNull
@Override
public String getName(@NotNull Variable variable) {
public String rawNameToSource(@NotNull Variable variable) {
String name = variable.getName();
return ObjectUtils.chooseNotNull(sourceNameToRaw(name), name);
String sourceName = rawNameToSource.get(name);
return sourceName == null ? normalizeMemberName(name) : sourceName;
}
@NotNull
protected String normalizeMemberName(@NotNull String name) {
return name;
}
@Nullable
@@ -468,7 +468,7 @@ public final class VariableView extends XNamedValue implements VariableContext {
for (int i = notGroupedVariablesOffset; i < variables.size(); i++) {
Variable variable = variables.get(i);
groupList.add(new VariableView(memberFilter.getName(variable), variable, this));
groupList.add(new VariableView(memberFilter.rawNameToSource(variable), variable, this));
}
node.addChildren(groupList, true);
@@ -97,7 +97,7 @@ public final class Variables {
Comparator<Variable> comparator = memberFilter.hasNameMappings() ? new Comparator<Variable>() {
@Override
public int compare(@NotNull Variable o1, @NotNull Variable o2) {
return naturalCompare(memberFilter.getName(o1), memberFilter.getName(o2));
return naturalCompare(memberFilter.rawNameToSource(o1), memberFilter.rawNameToSource(o2));
}
} : NATURAL_NAME_COMPARATOR;
@@ -172,7 +172,7 @@ public final class Variables {
@NotNull MemberFilter memberFilter) {
ol: for (Variable variable : additionalVariables) {
for (Variable frameVariable : variables) {
if (memberFilter.getName(frameVariable).equals(memberFilter.getName(variable))) {
if (memberFilter.rawNameToSource(frameVariable).equals(memberFilter.rawNameToSource(variable))) {
continue ol;
}
}
@@ -280,7 +280,7 @@ public final class Variables {
VariableContext getterOrSetterContext = null;
for (int i = from; i < to; i++) {
Variable variable = variables.get(i);
String normalizedName = memberFilter == null ? variable.getName() : memberFilter.getName(variable);
String normalizedName = memberFilter == null ? variable.getName() : memberFilter.rawNameToSource(variable);
list.add(new VariableView(normalizedName, variable, variableContext));
if (variable instanceof ObjectProperty) {
ObjectProperty property = (ObjectProperty)variable;
@@ -1,3 +1,18 @@
/*
* 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 org.jetbrains.debugger.frame;
import com.intellij.icons.AllIcons;
@@ -132,8 +147,7 @@ public final class CallFrameView extends XStackFrame implements VariableContext
String fileName = sourceInfo.getFile().getName();
int line = sourceInfo.getLine() + 1;
boolean isInLibraryContent = inLibraryContent;
SimpleTextAttributes textAttributes = isInLibraryContent ? SimpleTextAttributes.GRAYED_ATTRIBUTES : SimpleTextAttributes.REGULAR_ATTRIBUTES;
SimpleTextAttributes textAttributes = inLibraryContent ? SimpleTextAttributes.GRAYED_ATTRIBUTES : SimpleTextAttributes.REGULAR_ATTRIBUTES;
String functionName = sourceInfo.getFunctionName();
if (functionName == null || (functionName.isEmpty() && callFrame.hasOnlyGlobalScope())) {
@@ -141,7 +155,7 @@ public final class CallFrameView extends XStackFrame implements VariableContext
}
else {
if (functionName.isEmpty()) {
component.append("anonymous", isInLibraryContent ? SimpleTextAttributes.GRAYED_ITALIC_ATTRIBUTES : SimpleTextAttributes.REGULAR_ITALIC_ATTRIBUTES);
component.append("anonymous", inLibraryContent ? SimpleTextAttributes.GRAYED_ITALIC_ATTRIBUTES : SimpleTextAttributes.REGULAR_ITALIC_ATTRIBUTES);
}
else {
component.append(functionName, textAttributes);
@@ -47,7 +47,7 @@ public class TestStatusLine extends JPanel {
progressPanel.setMinimumSize(size);
progressPanel.setPreferredSize(size);
progressPanel.add(myProgressBar, new GridBagConstraints(0, 0, 0, 0, 1, 1, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL,
new Insets(2, 2, 0, 8), 0, 0));
new Insets(2, 8, 0, 8), 0, 0));
setStatusColor(ColorProgressBar.GREEN);
add(myState, BorderLayout.CENTER);
myState.append(ExecutionBundle.message("junit.runing.info.starting.label"));
@@ -92,38 +92,6 @@ public abstract class JBIterable<E> implements Iterable<E> {
};
}
@NotNull
public static <T, E> JBIterable<E> from(@Nullable Iterable<T> iterable, final Function<? super T, Iterable<E>> fun) {
if (iterable == null) return empty();
final Iterable<T> thatIt = iterable;
return new JBIterable<E>() {
@Override
public Iterator<E> iterator() {
final Iterator<T> it = thatIt.iterator();
return new Iterator<E>() {
Iterator<E> cur;
@Override
public boolean hasNext() {
while ((cur == null || !cur.hasNext()) && it.hasNext()) {
cur = fun.fun(it.next()).iterator();
}
return cur != null && cur.hasNext();
}
@Override
public E next() {
return cur.next();
}
@Override
public void remove() {
cur.remove();
}
};
}
};
}
/**
* Returns a fluent iterable containing {@code elements} in the specified order.
*/
@@ -190,7 +158,7 @@ public abstract class JBIterable<E> implements Iterable<E> {
}
public final <T> JBIterable<E> append(@Nullable Iterable<T> other, @NotNull Function<? super T, Iterable<E>> fun) {
return other == null ? this : this == EMPTY ? from(other, fun) : append(from(other, fun));
return other == null ? this : this == EMPTY ? from(other).flatten(fun) : append(from(other).flatten(fun));
}
/**
@@ -302,6 +270,47 @@ public abstract class JBIterable<E> implements Iterable<E> {
});
}
/**
* Returns a fluent iterable that applies {@code function} to each element of this
* fluent iterable and concats the produced iterables in one.
* <p/>
* <p>The returned fluent iterable's iterator supports {@code remove()} if an underlying iterable's
* iterator does. After a successful {@code remove()} call, this fluent iterable no longer
* contains the corresponding element.
*/
@NotNull
public <T> JBIterable<T> flatten(final Function<? super E, Iterable<T>> function) {
if (this == EMPTY) return empty();
final Iterable<E> thatIt = myIterable;
return new JBIterable<T>() {
@Override
public Iterator<T> iterator() {
final Iterator<E> it = thatIt.iterator();
return new Iterator<T>() {
Iterator<T> cur;
@Override
public boolean hasNext() {
while ((cur == null || !cur.hasNext()) && it.hasNext()) {
cur = function.fun(it.next()).iterator();
}
return cur != null && cur.hasNext();
}
@Override
public T next() {
return cur.next();
}
@Override
public void remove() {
cur.remove();
}
};
}
};
}
/**
* Returns the first element in this fluent iterable or null.
*/
@@ -26,9 +26,9 @@ import java.io.Serializable;
import java.util.*;
/**
* Consider to use factory methods {@link #createLinked()}, {@link #createSet()}, {@link #createSmart()}, {@link #create(gnu.trove.TObjectHashingStrategy)} instead of override.
* @see com.intellij.util.containers.BidirectionalMultiMap
* @see com.intellij.util.containers.ConcurrentMultiMap
* Consider to use factory methods {@link #createLinked()}, {@link #createSet()}, {@link #createSmart()}, {@link #create(TObjectHashingStrategy)} instead of override.
* @see BidirectionalMultiMap
* @see ConcurrentMultiMap
* @author Dmitry Avdeev
*/
public class MultiMap<K, V> implements Serializable {
@@ -52,8 +52,8 @@ public class MultiMap<K, V> implements Serializable {
return new MultiMap<K, V>(this);
}
public MultiMap(int i, float v) {
myMap = createMap(i, v);
public MultiMap(int initialCapacity, float loadFactor) {
myMap = createMap(initialCapacity, loadFactor);
}
@NotNull
@@ -62,7 +62,7 @@ public class MultiMap<K, V> implements Serializable {
}
@NotNull
protected Map<K, Collection<V>> createMap(int initialCapacity, float loadFactor) {
protected Map<K, Collection<V>> createMap(int initialCapacity, float loadFactor) {
return new HashMap<K, Collection<V>>(initialCapacity, loadFactor);
}
@@ -249,7 +249,7 @@ public class MultiMap<K, V> implements Serializable {
@NotNull
public static <K, V> MultiMap<K, V> emptyInstance() {
@SuppressWarnings({"unchecked"}) final MultiMap<K, V> empty = EMPTY;
@SuppressWarnings("unchecked") final MultiMap<K, V> empty = EMPTY;
return empty;
}
@@ -355,6 +355,29 @@ public class MultiMap<K, V> implements Serializable {
};
}
@NotNull
public static <K, V> MultiMap<K, V> createWeakSet() {
return new MultiMap<K, V>() {
@NotNull
@Override
protected Collection<V> createCollection() {
return new SmartHashSet<V>();
}
@NotNull
@Override
protected Collection<V> createEmptyCollection() {
return Collections.emptySet();
}
@NotNull
@Override
protected Map<K, Collection<V>> createMap() {
return new WeakHashMap<K, Collection<V>>();
}
};
}
@NotNull
public static <K, V> MultiMap<K, V> createWeakKey() {
return new MultiMap<K, V>() {
@@ -366,8 +389,8 @@ public class MultiMap<K, V> implements Serializable {
};
}
public static <K, V> MultiMap<K, V> create(int i, float v) {
return new MultiMap<K, V>(i, v);
public static <K, V> MultiMap<K, V> create(int initialCapacity, float loadFactor) {
return new MultiMap<K, V>(initialCapacity, loadFactor);
}
@Override
@@ -16,6 +16,7 @@
package com.intellij.util.ui;
import javax.swing.tree.TreePath;
import java.util.Collection;
/**
* @author Konstantin Bulenkov
@@ -29,7 +30,8 @@ public interface EditableTreeModel {
*/
TreePath addNode(TreePath parentOrNeighbour);
void removeNode(TreePath parent);
void removeNode(TreePath path);
void removeNodes(Collection<TreePath> path);
void moveNodeTo(TreePath parentOrNeighbour);
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2012 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.
@@ -128,7 +128,7 @@ class XBreakpointItem extends BreakpointItem {
@Override
public void navigate(boolean requestFocus) {
Navigatable navigatable = myBreakpoint.getNavigatable();
if (navigatable != null) {
if (navigatable != null && navigatable.canNavigate()) {
navigatable.navigate(requestFocus);
}
}
@@ -890,7 +890,7 @@ public class AntExplorer extends SimpleToolWindowPanel implements DataProvider,
final KeymapManagerEx keymapManager = KeymapManagerEx.getInstanceEx();
final Keymap activeKeymap = keymapManager.getActiveKeymap();
listenTo(activeKeymap);
keymapManager.addKeymapManagerListener(this);
keymapManager.addKeymapManagerListener(this, AntExplorer.this);
}
public void activeKeymapChanged(Keymap keymap) {
@@ -918,7 +918,6 @@ public class AntExplorer extends SimpleToolWindowPanel implements DataProvider,
public void stopListen() {
listenTo(null);
KeymapManagerEx.getInstanceEx().removeKeymapManagerListener(this);
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2009 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.
@@ -15,12 +15,12 @@
*/
package org.jetbrains.idea.maven.tasks;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.actionSystem.Shortcut;
import com.intellij.openapi.keymap.Keymap;
import com.intellij.openapi.keymap.KeymapManager;
import com.intellij.openapi.keymap.KeymapManagerListener;
import com.intellij.openapi.keymap.KeymapUtil;
import com.intellij.openapi.keymap.ex.KeymapManagerEx;
import com.intellij.openapi.project.DumbAwareRunnable;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Pair;
@@ -49,7 +49,7 @@ import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicBoolean;
public class MavenShortcutsManager extends MavenSimpleProjectComponent {
public class MavenShortcutsManager extends MavenSimpleProjectComponent implements Disposable {
private static final String ACTION_ID_PREFIX = "Maven_";
private final AtomicBoolean isInitialized = new AtomicBoolean();
@@ -69,6 +69,11 @@ public class MavenShortcutsManager extends MavenSimpleProjectComponent {
myProjectsManager = projectsManager;
}
@Override
public void dispose() {
}
@Override
public void initComponent() {
if (!isNormalProject()) return;
@@ -147,7 +152,7 @@ public class MavenShortcutsManager extends MavenSimpleProjectComponent {
public MyKeymapListener() {
KeymapManager keymapManager = KeymapManager.getInstance();
listenTo(keymapManager.getActiveKeymap());
keymapManager.addKeymapManagerListener(this);
keymapManager.addKeymapManagerListener(this, MavenShortcutsManager.this);
}
@Override
@@ -173,7 +178,6 @@ public class MavenShortcutsManager extends MavenSimpleProjectComponent {
public void stopListen() {
listenTo(null);
KeymapManagerEx.getInstanceEx().removeKeymapManagerListener(this);
}
}
@@ -84,19 +84,20 @@ public class PropertiesImplUtil extends PropertiesUtil {
}
});
for (final PsiFile psiFile : psiFiles) {
final PropertiesFile propertiesFile = getPropertiesFile(psiFile);
if (propertiesFile == null) {
continue;
}
if (baseName.equals(bundleBaseNameManager.getBaseName(psiFile))) {
final PropertiesFile propertiesFile = getPropertiesFile(psiFile);
if (propertiesFile != null) {
if (defaultPropertiesFile == null) {
if (defaultPropertiesFile == null) {
defaultPropertiesFile = propertiesFile;
} else {
final int nameDiff = FileUtil.getNameWithoutExtension(defaultPropertiesFile.getName()).compareTo(FileUtil.getNameWithoutExtension(propertiesFile.getName()));
if (nameDiff > 0) {
defaultPropertiesFile = propertiesFile;
} else {
final int nameDiff = FileUtil.getNameWithoutExtension(defaultPropertiesFile.getName()).compareTo(FileUtil.getNameWithoutExtension(propertiesFile.getName()));
if (nameDiff > 0) {
defaultPropertiesFile = propertiesFile;
} else if (nameDiff == 0) {
//means 2 default properties files
return null;
}
} else if (nameDiff == 0) {
//means 2 default properties files
return null;
}
}
}
+3
View File
@@ -70,6 +70,9 @@
<stacktrace.fold substring="at org.testng.TestRunner."/>
<stacktrace.fold substring="at org.testng.SuiteRunner."/>
<stacktrace.fold substring="at org.testng.TestNG.run"/>
<localInspection groupPath="Java" language="JAVA" shortName="TestNGDataProvider"
implementationClass="com.theoryinpractice.testng.inspection.TestNGDataProviderInspection" displayName="Data provider problems"
groupName="TestNG" enabledByDefault="true" level="WARNING"/>
</extensions>
<extensionPoints >
<extensionPoint qualifiedName="com.theoryinpractice.testng.listener" interface="org.testng.IDEATestNGListener"/>
@@ -0,0 +1,92 @@
/*
* 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.theoryinpractice.testng;
import com.intellij.codeInsight.AnnotationUtil;
import com.intellij.codeInsight.lookup.LookupValueFactory;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.*;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiUtil;
import com.theoryinpractice.testng.util.TestNGUtil;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.testng.annotations.DataProvider;
import java.util.ArrayList;
import java.util.List;
public class DataProviderReference extends PsiReferenceBase<PsiLiteral> {
public DataProviderReference(PsiLiteral element) {
super(element, false);
}
@Nullable
public PsiElement resolve() {
final PsiClass cls = TestNGUtil.getProviderClass(getElement(), PsiUtil.getTopLevelClass(getElement()));
if (cls != null) {
PsiMethod[] methods = cls.getAllMethods();
@NonNls String val = getValue();
for (PsiMethod method : methods) {
PsiAnnotation dataProviderAnnotation = AnnotationUtil.findAnnotation(method, DataProvider.class.getName());
if (dataProviderAnnotation != null) {
final PsiAnnotationMemberValue dataProviderMethodName = dataProviderAnnotation.findDeclaredAttributeValue("name");
if (dataProviderMethodName != null && val.equals(StringUtil.unquoteString(dataProviderMethodName.getText()))) {
return method;
}
if (val.equals(method.getName())) {
return method;
}
}
}
}
return null;
}
@NotNull
public Object[] getVariants() {
final List<Object> list = new ArrayList<Object>();
final PsiClass topLevelClass = PsiUtil.getTopLevelClass(getElement());
final PsiClass cls = TestNGUtil.getProviderClass(getElement(), topLevelClass);
final boolean needToBeStatic = cls != topLevelClass;
if (cls != null) {
final PsiMethod current = PsiTreeUtil.getParentOfType(getElement(), PsiMethod.class);
final PsiMethod[] methods = cls.getAllMethods();
for (PsiMethod method : methods) {
if (current != null && method.getName().equals(current.getName())) continue;
if (needToBeStatic) {
if (!method.hasModifierProperty(PsiModifier.STATIC)) continue;
} else {
if (cls != method.getContainingClass() && method.hasModifierProperty(PsiModifier.PRIVATE)) continue;
}
final PsiAnnotation dataProviderAnnotation = AnnotationUtil.findAnnotation(method, DataProvider.class.getName());
if (dataProviderAnnotation != null) {
final PsiAnnotationMemberValue memberValue = dataProviderAnnotation.findDeclaredAttributeValue("name");
if (memberValue != null) {
list.add(LookupValueFactory.createLookupValue(StringUtil.unquoteString(memberValue.getText()), null));
} else {
list.add(LookupValueFactory.createLookupValue(method.getName(), null));
}
}
}
}
return list.toArray();
}
}
@@ -44,7 +44,6 @@ import com.theoryinpractice.testng.util.TestNGUtil;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.testng.annotations.DataProvider;
import java.util.ArrayList;
import java.util.List;
@@ -82,80 +81,6 @@ public class TestNGReferenceContributor extends PsiReferenceContributor {
});
}
private static class DataProviderReference extends PsiReferenceBase<PsiLiteral> {
public DataProviderReference(PsiLiteral element) {
super(element, false);
}
@Nullable
public PsiElement resolve() {
final PsiClass cls = getProviderClass(PsiUtil.getTopLevelClass(getElement()));
if (cls != null) {
PsiMethod[] methods = cls.getAllMethods();
@NonNls String val = getValue();
for (PsiMethod method : methods) {
PsiAnnotation dataProviderAnnotation = AnnotationUtil.findAnnotation(method, DataProvider.class.getName());
if (dataProviderAnnotation != null) {
final PsiAnnotationMemberValue dataProviderMethodName = dataProviderAnnotation.findDeclaredAttributeValue("name");
if (dataProviderMethodName != null && val.equals(StringUtil.unquoteString(dataProviderMethodName.getText()))) {
return method;
}
if (val.equals(method.getName())) {
return method;
}
}
}
}
return null;
}
@NotNull
public Object[] getVariants() {
final List<Object> list = new ArrayList<Object>();
final PsiClass topLevelClass = PsiUtil.getTopLevelClass(getElement());
final PsiClass cls = getProviderClass(topLevelClass);
final boolean needToBeStatic = cls != topLevelClass;
if (cls != null) {
final PsiMethod current = PsiTreeUtil.getParentOfType(getElement(), PsiMethod.class);
final PsiMethod[] methods = cls.getAllMethods();
for (PsiMethod method : methods) {
if (current != null && method.getName().equals(current.getName())) continue;
if (needToBeStatic) {
if (!method.hasModifierProperty(PsiModifier.STATIC)) continue;
} else {
if (cls != method.getContainingClass() && method.hasModifierProperty(PsiModifier.PRIVATE)) continue;
}
final PsiAnnotation dataProviderAnnotation = AnnotationUtil.findAnnotation(method, DataProvider.class.getName());
if (dataProviderAnnotation != null) {
final PsiAnnotationMemberValue memberValue = dataProviderAnnotation.findDeclaredAttributeValue("name");
if (memberValue != null) {
list.add(LookupValueFactory.createLookupValue(StringUtil.unquoteString(memberValue.getText()), null));
} else {
list.add(LookupValueFactory.createLookupValue(method.getName(), null));
}
}
}
}
return list.toArray();
}
private PsiClass getProviderClass(final PsiClass topLevelClass) {
final PsiAnnotation annotation = PsiTreeUtil.getParentOfType(getElement(), PsiAnnotation.class);
if (annotation != null) {
final PsiAnnotationMemberValue value = annotation.findDeclaredAttributeValue("dataProviderClass");
if (value instanceof PsiClassObjectAccessExpression) {
final PsiTypeElement operand = ((PsiClassObjectAccessExpression)value).getOperand();
final PsiClass psiClass = PsiUtil.resolveClassInType(operand.getType());
if (psiClass != null) {
return psiClass;
}
}
}
return topLevelClass;
}
}
private static class MethodReference extends PsiReferenceBase<PsiLiteral> {
public MethodReference(PsiLiteral element) {
@@ -0,0 +1,103 @@
/*
* 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.theoryinpractice.testng.inspection;
import com.intellij.codeInsight.daemon.impl.quickfix.CreateMethodQuickFix;
import com.intellij.codeInspection.BaseJavaLocalInspectionTool;
import com.intellij.codeInspection.LocalQuickFix;
import com.intellij.codeInspection.ProblemsHolder;
import com.intellij.ide.fileTemplates.FileTemplate;
import com.intellij.ide.fileTemplates.FileTemplateDescriptor;
import com.intellij.ide.fileTemplates.FileTemplateManager;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.*;
import com.intellij.psi.util.PsiUtil;
import com.theoryinpractice.testng.DataProviderReference;
import com.theoryinpractice.testng.TestNGFramework;
import com.theoryinpractice.testng.util.TestNGUtil;
import org.jetbrains.annotations.NotNull;
import org.testng.annotations.DataProvider;
import java.io.IOException;
import java.util.Properties;
public class TestNGDataProviderInspection extends BaseJavaLocalInspectionTool {
@NotNull
@Override
public PsiElementVisitor buildVisitor(final @NotNull ProblemsHolder holder, final boolean isOnTheFly) {
return new JavaElementVisitor() {
@Override
public void visitAnnotation(PsiAnnotation annotation) {
if (TestNGUtil.TEST_ANNOTATION_FQN.equals(annotation.getQualifiedName())) {
final PsiAnnotationMemberValue provider = annotation.findDeclaredAttributeValue("dataProvider");
if (provider != null && !TestNGUtil.isDisabled(annotation)) {
for (PsiReference reference : provider.getReferences()) {
if (reference instanceof DataProviderReference) {
final PsiElement dataProviderMethod = reference.resolve();
final PsiElement element = reference.getElement();
final PsiClass topLevelClass = PsiUtil.getTopLevelClass(element);
final PsiClass providerClass = TestNGUtil.getProviderClass(element, topLevelClass);
if (!(dataProviderMethod instanceof PsiMethod)) {
final LocalQuickFix[] fixes;
if (isOnTheFly) {
fixes = new LocalQuickFix[] {createMethodFix(provider, providerClass, topLevelClass)};
}
else {
fixes = LocalQuickFix.EMPTY_ARRAY;
}
holder.registerProblem(provider, "Data provider does not exist", fixes);
} else {
final PsiMethod providerMethod = (PsiMethod)dataProviderMethod;
if (providerClass != topLevelClass && !providerMethod.hasModifierProperty(PsiModifier.STATIC)) {
holder.registerProblem(provider, "Data provider from foreign class need to be static");
}
}
break;
}
}
}
}
}
};
}
private static CreateMethodQuickFix createMethodFix(PsiAnnotationMemberValue provider, PsiClass providerClass, PsiClass topLevelClass) {
FileTemplateDescriptor templateDesc = new TestNGFramework().getParametersMethodFileTemplateDescriptor();
assert templateDesc != null;
final FileTemplate fileTemplate = FileTemplateManager.getInstance(provider.getProject()).getCodeTemplate(templateDesc.getFileName());
String body = "";
try {
body = fileTemplate.getText(new Properties());
body = body.replace("${BODY}", "");
}
catch (IOException ignored) {}
if (StringUtil.isEmptyOrSpaces(body)) {
body = "return new Object[][]{};";
}
String signature = "@" + DataProvider.class.getName() + " public ";
if (providerClass == topLevelClass) {
signature += "static ";
}
signature += "Object[][] " + StringUtil.unquoteString(provider.getText()) + "()";
return CreateMethodQuickFix.createFix(providerClass, signature, body);
}
}
@@ -36,6 +36,7 @@ import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.search.searches.AllClassesSearch;
import com.intellij.psi.util.PsiElementFilter;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiUtil;
import com.intellij.util.PathUtil;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.xml.NanoXmlUtil;
@@ -545,4 +546,19 @@ public class TestNGUtil {
}
return false;
}
public static PsiClass getProviderClass(final PsiElement element, final PsiClass topLevelClass) {
final PsiAnnotation annotation = PsiTreeUtil.getParentOfType(element, PsiAnnotation.class);
if (annotation != null) {
final PsiAnnotationMemberValue value = annotation.findDeclaredAttributeValue("dataProviderClass");
if (value instanceof PsiClassObjectAccessExpression) {
final PsiTypeElement operand = ((PsiClassObjectAccessExpression)value).getOperand();
final PsiClass psiClass = PsiUtil.resolveClassInType(operand.getType());
if (psiClass != null) {
return psiClass;
}
}
}
return topLevelClass;
}
}
@@ -0,0 +1,3 @@
<html><body>
This inspection checks that data provider method exists and is accessible.
</body></html>
@@ -0,0 +1,10 @@
public class InstanceDataProviderFromForeignClass {
@org.testng.annotations.Test(dataProvider = <warning descr="Data provider from foreign class need to be static">"data"</warning>, dataProviderClass = A.class)
public void test() {
}
}
class A {
@org.testng.annotations.DataProvider
public Object[][] data () {return null;}
}
@@ -0,0 +1,5 @@
public class MissedDataProvider {
@org.testng.annotations.Test(dataProvider = <warning descr="Data provider does not exist">"data"</warning>)
public void test() {
}
}
@@ -0,0 +1,49 @@
/*
* 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.theoryinpractice.testng.inspection;
import com.intellij.openapi.application.PluginPathManager;
import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase;
import org.jetbrains.annotations.NotNull;
public class TestNGDataProviderInspectionTest extends LightCodeInsightFixtureTestCase {
public void testMissedDataProvider() throws Exception {
myFixture.testHighlighting(true, false, false, "MissedDataProvider.java");
}
public void testInstanceDataProviderFromForeignClass() throws Exception {
myFixture.testHighlighting(true, false, false, "InstanceDataProviderFromForeignClass.java");
}
@NotNull
@Override
protected String getTestDataPath() {
return PluginPathManager.getPluginHomePath("testng") + "/testData/inspection/dataProvider/";
}
@Override
protected void setUp() throws Exception {
super.setUp();
myFixture.addClass("package org.testng.annotations;\n" +
"public @interface DataProvider {}");
myFixture.addClass("package org.testng.annotations;\n" +
"public @interface Test { java.lang.String dataProvider() default {};" +
" Class dataProviderClass() default {};" +
"}");
myFixture.enableInspections(new TestNGDataProviderInspection());
}
}
+1
View File
@@ -1028,6 +1028,7 @@
<codeInsight.parameterInfo language="JAVA" implementationClass="com.intellij.codeInsight.hint.api.impls.ReferenceParameterInfoHandler"/>
<codeInsight.parameterInfo language="JAVA"
implementationClass="com.intellij.codeInsight.hint.api.impls.AnnotationParameterInfoHandler"/>
<codeInsight.typeInfo language="JAVA" implementationClass="com.intellij.codeInsight.hint.JavaTypeProvider"/>
<codeInsight.overrideMethod language="JAVA" implementationClass="com.intellij.codeInsight.generation.JavaOverrideMethodsHandler"/>
<codeInsight.implementMethod language="JAVA" implementationClass="com.intellij.codeInsight.generation.JavaImplementMethodsHandler"/>