mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Merge remote-tracking branch 'origin/master'
This commit is contained in:
@@ -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")
|
||||
|
||||
+21
-5
@@ -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) {
|
||||
|
||||
+9
-15
@@ -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() {
|
||||
|
||||
+1
-1
@@ -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;
|
||||
}
|
||||
|
||||
+5
-3
@@ -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();
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -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;
|
||||
}
|
||||
|
||||
+17
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -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 {
|
||||
/**
|
||||
|
||||
+1
-5
@@ -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");
|
||||
}
|
||||
}
|
||||
+4
-4
@@ -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());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+47
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
+9
-3
@@ -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,
|
||||
|
||||
+2
-2
@@ -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 |
+57
@@ -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
|
||||
|
||||
|
||||
+3
-1
@@ -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;
|
||||
|
||||
+28
-28
@@ -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;
|
||||
|
||||
+4
-6
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
+6
-5
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
+34
-21
@@ -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;
|
||||
}
|
||||
|
||||
+33
-29
@@ -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>
|
||||
|
||||
+7
-3
@@ -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
|
||||
|
||||
+30
-4
@@ -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) {
|
||||
|
||||
+16
-2
@@ -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);
|
||||
|
||||
+23
@@ -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;
|
||||
}
|
||||
}
|
||||
+4
-4
@@ -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);
|
||||
|
||||
+1
-1
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
+26
-5
@@ -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;
|
||||
|
||||
+17
-3
@@ -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);
|
||||
}
|
||||
|
||||
+2
-2
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+9
-5
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+12
-11
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
+103
@@ -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>
|
||||
+10
@@ -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() {
|
||||
}
|
||||
}
|
||||
+49
@@ -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());
|
||||
}
|
||||
}
|
||||
@@ -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"/>
|
||||
|
||||
Reference in New Issue
Block a user