Merge remote-tracking branch 'origin/master'

This commit is contained in:
Dmitry Batkovich
2016-06-01 09:05:05 +03:00
63 changed files with 629 additions and 197 deletions
-1
View File
@@ -952,7 +952,6 @@ def layoutJps(String home, String targetDir, String buildNumber, Closure additio
include(name: "ecj*.jar")
include(name: "netty-all-*.jar")
include(name: "snappy-in-java-*.jar")
include(name: "picocontainer.jar")
}
fileset(dir: "$home/jps/lib") {
include(name: "optimizedFileManager.jar")
@@ -16,52 +16,78 @@
package com.intellij.testIntegration
import com.intellij.execution.RunnerAndConfigurationSettings
import com.intellij.execution.testframework.sm.runner.states.TestStateInfo
import com.intellij.execution.testframework.sm.runner.states.TestStateInfo.Magnitude
import com.intellij.openapi.vfs.VirtualFileManager
import com.intellij.util.containers.ContainerUtil
import java.util.*
fun SuiteEntry.isMyTest(test: SingleTestEntry): Boolean {
val testName = VirtualFileManager.extractPath(test.url)
return testName.startsWith(this.suiteName)
}
class RecentTestsData {
private val runConfigurationSuites = hashMapOf<String, RunConfigurationEntry>()
private var testsWithoutSuites: MutableList<SingleTestEntry> = ContainerUtil.newArrayList<SingleTestEntry>()
fun addSuite(url: String,
magnitude: TestStateInfo.Magnitude,
runDate: Date,
runConfiguration: RunnerAndConfigurationSettings)
{
private var unmatchedRunConfigurationTests = arrayListOf<SingleTestEntry>()
val suiteInfo = SuiteEntry(url, magnitude, runDate, runConfiguration)
private val urlSuites = mutableListOf<SuiteEntry>()
private var unmatchedUrlTests = mutableListOf<SingleTestEntry>()
val configurationId = runConfiguration.uniqueID
val suitePack = runConfigurationSuites[configurationId]
if (suitePack != null) {
suitePack.addSuite(suiteInfo)
return
fun addSuite(url: String, magnitude: Magnitude, runDate: Date, runConfiguration: RunnerAndConfigurationSettings?) {
val suite = SuiteEntry(url, magnitude, runDate)
if (runConfiguration != null) {
addRunConfigurationSuite(suite, runConfiguration)
}
else {
addUrlSuite(suite)
}
}
fun addTest(url: String, magnitude: Magnitude, runDate: Date, runConfiguration: RunnerAndConfigurationSettings?) {
val test = SingleTestEntry(url, magnitude, runDate)
if (runConfiguration != null) {
addRunConfigurationTest(test, runConfiguration)
}
else {
addUrlTest(test)
}
}
private fun addUrlSuite(suite: SuiteEntry) {
val suiteTests = unmatchedUrlTests.filter { suite.isMyTest(it) }
suiteTests.forEach { suite.addTest(it) }
runConfigurationSuites[configurationId] = RunConfigurationEntry(runConfiguration, suiteInfo)
unmatchedUrlTests = unmatchedUrlTests.filterTo(arrayListOf(), { !suite.isMyTest(it) })
urlSuites.add(suite)
}
private fun addRunConfigurationSuite(suite: SuiteEntry, config: RunnerAndConfigurationSettings) {
val suiteTests = unmatchedRunConfigurationTests.filter { suite.isMyTest(it) }
suiteTests.forEach { suite.addTest(it) }
unmatchedRunConfigurationTests = unmatchedRunConfigurationTests.filterTo(arrayListOf(), { !suite.isMyTest(it) })
fun addTest(url: String,
magnitude: TestStateInfo.Magnitude,
runDate: Date,
runConfiguration: RunnerAndConfigurationSettings) {
val testInfo = SingleTestEntry(url, magnitude, runDate, runConfiguration)
val suite = findSuite(url, runConfiguration)
if (suite != null) {
suite.addTest(testInfo)
return
}
testsWithoutSuites.add(testInfo)
val id = config.uniqueID
runConfigurationSuites[id]?.addSuite(suite) ?: runConfigurationSuites.put(id, RunConfigurationEntry(config, suite))
}
private fun findSuite(url: String, runConfiguration: RunnerAndConfigurationSettings): SuiteEntry? {
private fun addUrlTest(test: SingleTestEntry) {
findUrlSuite(test.url)?.addTest(test) ?: unmatchedUrlTests.add(test)
}
private fun addRunConfigurationTest(test: SingleTestEntry, runConfiguration: RunnerAndConfigurationSettings) {
findRunConfigurationSuite(test.url, runConfiguration)?.addTest(test) ?: unmatchedRunConfigurationTests.add(test)
}
private fun findUrlSuite(url: String) = urlSuites.find {
val testName = VirtualFileManager.extractPath(url)
testName.startsWith(it.suiteName)
}
private fun findRunConfigurationSuite(url: String, runConfiguration: RunnerAndConfigurationSettings): SuiteEntry? {
val pack: RunConfigurationEntry = runConfigurationSuites[runConfiguration.uniqueID] ?: return null
val testName = VirtualFileManager.extractPath(url)
@@ -75,13 +101,15 @@ class RecentTestsData {
}
fun getTestsToShow(): List<RecentTestsPopupEntry> {
testsWithoutSuites.forEach {
val url = it.url
findSuite(url, it.runConfiguration)?.addTest(it)
}
val packsByDate = runConfigurationSuites.values.sortedByDescending { it.runDate }
return packsByDate.fold(listOf(), { list, pack -> list + pack.entriesToShow() })
val allEntries: List<RecentTestsPopupEntry> = runConfigurationSuites.values + urlSuites
return allEntries
.sortedByDescending { it.runDate }
.fold(listOf(), { popupList, currentEntry ->
when (currentEntry) {
is RunConfigurationEntry -> popupList + currentEntry.entriesToShow()
else -> popupList + currentEntry
}
})
}
}
@@ -99,9 +99,7 @@ public class RecentTestsListProvider {
RunnerAndConfigurationSettings runConfiguration = myConfigurationProvider.getConfiguration(record);
if (TestLocator.isSuite(url)) {
if (runConfiguration != null) {
data.addSuite(url, magnitude, record.date, runConfiguration);
}
data.addSuite(url, magnitude, record.date, runConfiguration);
}
else {
data.addTest(url, magnitude, record.date, runConfiguration);
@@ -35,10 +35,9 @@ interface RecentTestsPopupEntry {
open fun navigatableElement(locator: TestLocator): PsiElement? = null
}
open class SingleTestEntry(val url: String,
override val magnitude: TestStateInfo.Magnitude,
override val runDate: Date,
val runConfiguration: RunnerAndConfigurationSettings) : RecentTestsPopupEntry
open class SingleTestEntry(val url: String,
override val magnitude: TestStateInfo.Magnitude,
override val runDate: Date) : RecentTestsPopupEntry
{
override val presentation = VirtualFileManager.extractPath(url)
@@ -52,10 +51,8 @@ open class SingleTestEntry(val url: String,
}
class SuiteEntry(url: String, magnitude: TestStateInfo.Magnitude, runDate: Date, runConfiguration: RunnerAndConfigurationSettings)
: SingleTestEntry(url, magnitude, runDate, runConfiguration)
{
class SuiteEntry(url: String, magnitude: TestStateInfo.Magnitude, runDate: Date) : SingleTestEntry(url, magnitude, runDate) {
private val tests = hashSetOf<SingleTestEntry>()
override val testsUrls: List<String>
@@ -213,6 +213,8 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
}
catch (IndexNotReadyException ignored) { }
}
myHolder.add(DefaultHighlightUtil.checkBadCharacter(element));
}
@Override
@@ -220,6 +220,7 @@ public class AnonymousCanBeLambdaInspection extends BaseJavaBatchLocalInspection
aClass.getInitializers().length == 0) {
final PsiMethod method = methods[0];
return method.getBody() != null &&
method.getDocComment() == null &&
!hasForbiddenRefsInsideBody(method, aClass) &&
!hasRuntimeAnnotations(method, ignoredRuntimeAnnotations) &&
!method.hasModifierProperty(PsiModifier.SYNCHRONIZED);
@@ -23,19 +23,22 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.*;
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.RedundantCastUtil;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.util.Collection;
import java.util.Collections;
/**
* User: anna
*/
public class AnonymousCanBeMethodReferenceInspection extends BaseJavaBatchLocalInspectionTool {
public static final Logger LOG = Logger.getInstance("#" + AnonymousCanBeMethodReferenceInspection.class.getName());
private static final Logger LOG = Logger.getInstance("#" + AnonymousCanBeMethodReferenceInspection.class.getName());
public boolean reportNotAnnotatedInterfaces = true;
@@ -132,19 +135,38 @@ public class AnonymousCanBeMethodReferenceInspection extends BaseJavaBatchLocalI
final String methodRefText =
LambdaCanBeMethodReferenceInspection.convertToMethodReference(methods[0].getBody(), parameters, anonymousClass.getBaseClassType(), anonymousClass.getParent());
if (methodRefText != null) {
final String canonicalText = anonymousClass.getBaseClassType().getCanonicalText();
final PsiExpression psiExpression = JavaPsiFacade.getElementFactory(project).createExpressionFromText("(" + canonicalText + ")" + methodRefText, anonymousClass);
PsiElement castExpr = anonymousClass.getParent().replace(psiExpression);
if (RedundantCastUtil.isCastRedundant((PsiTypeCastExpression)castExpr)) {
final PsiExpression operand = ((PsiTypeCastExpression)castExpr).getOperand();
LOG.assertTrue(operand != null);
castExpr = castExpr.replace(operand);
}
JavaCodeStyleManager.getInstance(project).shortenClassReferences(castExpr);
}
replaceWithMethodReference(project, methodRefText, anonymousClass.getBaseClassType(), anonymousClass.getParent());
}
}
}
static void replaceWithMethodReference(@NotNull Project project,
String methodRefText,
PsiType castType,
PsiElement replacementTarget) {
final Collection<PsiComment> comments = ContainerUtil.map(PsiTreeUtil.findChildrenOfType(replacementTarget, PsiComment.class),
comment -> (PsiComment)comment.copy());
if (methodRefText != null) {
final String canonicalText = castType.getCanonicalText();
final PsiExpression psiExpression = JavaPsiFacade
.getElementFactory(project).createExpressionFromText("(" + canonicalText + ")" + methodRefText, replacementTarget);
PsiElement castExpr = replacementTarget.replace(psiExpression);
if (RedundantCastUtil.isCastRedundant((PsiTypeCastExpression)castExpr)) {
final PsiExpression operand = ((PsiTypeCastExpression)castExpr).getOperand();
LOG.assertTrue(operand != null);
castExpr = castExpr.replace(operand);
}
PsiElement anchor = PsiTreeUtil.getParentOfType(castExpr, PsiStatement.class);
if (anchor == null) {
anchor = castExpr;
}
for (PsiComment comment : comments) {
anchor.getParent().addBefore(comment, anchor);
}
JavaCodeStyleManager.getInstance(project).shortenClassReferences(castExpr);
}
}
}
@@ -19,14 +19,14 @@ import com.intellij.lang.Language;
import com.intellij.lang.java.JavaLanguage;
import com.intellij.psi.JavaTokenType;
import com.intellij.psi.TokenType;
import com.intellij.psi.impl.source.codeStyle.JavaLikeLangLineIndentProvider;
import com.intellij.psi.impl.source.codeStyle.lineIndent.JavaLikeLangLineIndentProvider;
import com.intellij.psi.impl.source.codeStyle.SemanticEditorPosition;
import com.intellij.psi.tree.IElementType;
import com.intellij.util.containers.HashMap;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import static com.intellij.psi.impl.source.codeStyle.JavaLikeLangLineIndentProvider.JavaLikeElement.*;
import static com.intellij.psi.impl.source.codeStyle.lineIndent.JavaLikeLangLineIndentProvider.JavaLikeElement.*;
/**
* @author Rustam Vishnyakov
@@ -337,7 +337,13 @@ public class CopyClassesHandler extends CopyHandlerDelegateBase {
final PsiClass[] sources = entry.getValue();
if (psiFile instanceof PsiClassOwner && sources != null) {
final PsiFile createdFile = copy(psiFile, targetDirectory, copyClassName, map == null ? null : map.get(psiFile), choice);
if (createdFile == null) return null;
if (createdFile == null) {
//do not touch unmodified classes
for (PsiClass aClass : ((PsiClassOwner)psiFile).getClasses()) {
oldToNewMap.remove(aClass);
}
continue;
}
for (final PsiClass destination : ((PsiClassOwner)createdFile).getClasses()) {
if (isSynthetic(destination)) {
continue;
@@ -15,6 +15,8 @@
*/
package com.intellij.rt.execution.testFrameworks;
import com.intellij.rt.execution.junit.RepeatCount;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
@@ -39,9 +41,13 @@ public abstract class ForkedSplitter extends ForkedByModuleSplitter {
}
sendTree(myRootDescription);
if (myWorkingDirsPath == null || new File(myWorkingDirsPath).length() == 0) {
final String classpath = System.getProperty("java.class.path");
if (RepeatCount.getCount(repeatCount) != 0 && myForkMode.equals("repeat")) {
return startChildFork(createChildArgs(myRootDescription), null, classpath, repeatCount);
}
final List children = getChildren(myRootDescription);
final boolean forkTillMethod = myForkMode.equalsIgnoreCase("method");
return splitChildren(children, 0, forkTillMethod, null, System.getProperty("java.class.path"), repeatCount);
return splitChildren(children, 0, forkTillMethod, null, classpath, repeatCount);
}
else {
return splitPerModule(repeatCount);
@@ -0,0 +1,13 @@
// "Replace with lambda" "false"
class Test {
{
Runnable r = new Ru<caret>nnable() {
/**
* important javadoc
*/
@Override
public void run() {
}
};
}
}
@@ -0,0 +1,13 @@
// "Replace with method reference" "true"
class Test {
private void doTest (){}
void foo(Runnable r){}
{
//some comment
foo (this::doTest);
}
}
@@ -0,0 +1,18 @@
// "Replace with method reference" "true"
class Test {
private void doTest (){}
void foo(Runnable r){}
{
foo (new Ru<caret>nnable() {
@Override
public void run() {
//some comment
doTest();
}
});
}
}
@@ -16,6 +16,7 @@
package com.intellij.codeInsight.daemon.lambda;
import com.intellij.JavaTestUtil;
import com.intellij.idea.Bombed;
import com.intellij.psi.*;
import com.intellij.psi.impl.search.JavaFunctionalExpressionSearcher;
import com.intellij.psi.search.GlobalSearchScope;
@@ -26,31 +27,45 @@ import com.intellij.testFramework.LightProjectDescriptor;
import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase;
import org.jetbrains.annotations.NotNull;
import java.util.Calendar;
import java.util.Collection;
import java.util.function.Predicate;
public class FindFunctionalInterfaceTest extends LightCodeInsightFixtureTestCase {
public void testMethodArgument() throws Exception {
myFixture.configureByFile(getTestName(false) + ".java");
final PsiElement elementAtCaret = myFixture.getElementAtCaret();
assertNotNull(elementAtCaret);
final PsiClass psiClass = PsiTreeUtil.getParentOfType(elementAtCaret, PsiClass.class, false);
assertTrue(psiClass != null && psiClass.isInterface());
final Collection<PsiFunctionalExpression> expressions = FunctionalExpressionSearch.search(psiClass).findAll();
assertTrue(expressions.size() == 1);
final PsiFunctionalExpression next = expressions.iterator().next();
assertNotNull(next);
assertEquals("() -> {}", next.getText());
doTestOneExpression();
}
public void testMethodArgumentByTypeParameter() throws Exception {
doTestOneExpression();
}
@Bombed(month = Calendar.AUGUST, day = 1, user = "ann peter")
public void testFieldDeclaredInFileWithoutFunctionalInterfaces() throws Exception {
myFixture.addClass("class B {" +
" void f(A a) {" +
" a.r = () -> {};" +
" }" +
"}");
myFixture.addClass("public class A {" +
" public I r;" +
"}");
for (int i = 0; i < JavaFunctionalExpressionSearcher.SMART_SEARCH_THRESHOLD + 1; i++) {
myFixture.addClass("class B" + i + " { {Runnable r = () -> {};}}"); //ensure common case is used
}
doTestOneExpression();
}
private void doTestOneExpression() {
myFixture.configureByFile(getTestName(false) + ".java");
final PsiElement elementAtCaret = myFixture.getElementAtCaret();
assertNotNull(elementAtCaret);
final PsiClass psiClass = PsiTreeUtil.getParentOfType(elementAtCaret, PsiClass.class, false);
assertTrue(psiClass != null && psiClass.isInterface());
final Collection<PsiFunctionalExpression> expressions = FunctionalExpressionSearch.search(psiClass).findAll();
assertTrue(expressions.size() == 1);
int size = expressions.size();
assertEquals(1, size);
final PsiFunctionalExpression next = expressions.iterator().next();
assertNotNull(next);
assertEquals("() -> {}", next.getText());
@@ -16,7 +16,8 @@
package com.intellij.testIntergration
import com.intellij.execution.RunnerAndConfigurationSettings
import com.intellij.execution.testframework.sm.runner.states.TestStateInfo
import com.intellij.execution.testframework.sm.runner.states.TestStateInfo.Magnitude.FAILED_INDEX
import com.intellij.execution.testframework.sm.runner.states.TestStateInfo.Magnitude.PASSED_INDEX
import com.intellij.testFramework.LightIdeaTestCase
import com.intellij.testIntegration.RecentTestsData
import org.assertj.core.api.Assertions.assertThat
@@ -24,6 +25,9 @@ import org.mockito.Mockito.`when`
import org.mockito.Mockito.mock
import java.util.*
fun String.suite() = "java:suite://$this"
fun String.test() = "java:test://$this"
class RecentTestsStepTest: LightIdeaTestCase() {
lateinit var data: RecentTestsData
@@ -38,16 +42,24 @@ class RecentTestsStepTest: LightIdeaTestCase() {
`when`(allTests.name).thenAnswer { "all tests" }
now = Date()
}
fun `test show suites without run configuration`() {
data.addTest("Test.x".test(), PASSED_INDEX, now, null)
data.addSuite("Test".suite(), PASSED_INDEX, now, null)
val tests = data.getTestsToShow()
assertThat(tests).hasSize(1)
}
fun `test all tests passed`() {
data.addTest("java:test://Test.textXXX", TestStateInfo.Magnitude.PASSED_INDEX, now, allTests)
data.addSuite("java:suite://Test", TestStateInfo.Magnitude.PASSED_INDEX, now, allTests)
data.addSuite("java:suite://JavaFormatterSuperDuperTest", TestStateInfo.Magnitude.PASSED_INDEX, now, allTests)
data.addTest("java:test://Test.textYYY", TestStateInfo.Magnitude.PASSED_INDEX, now, allTests)
data.addTest("java:test://JavaFormatterSuperDuperTest.testItMakesMeSadToFixIt", TestStateInfo.Magnitude.PASSED_INDEX, now, allTests)
data.addTest("java:test://Test.textZZZ", TestStateInfo.Magnitude.PASSED_INDEX, now, allTests)
data.addTest("java:test://Test.textQQQ", TestStateInfo.Magnitude.PASSED_INDEX, now, allTests)
data.addTest("java:test://JavaFormatterSuperDuperTest.testUnconditionalAlignmentErrorneous", TestStateInfo.Magnitude.PASSED_INDEX, now, allTests)
data.addTest("Test.textXXX".test(), PASSED_INDEX, now, allTests)
data.addSuite("Test".suite(), PASSED_INDEX, now, allTests)
data.addSuite("JFSDTest".suite(), PASSED_INDEX, now, allTests)
data.addTest("Test.textYYY".test(), PASSED_INDEX, now, allTests)
data.addTest("JFSDTest.testItMakesMeSadToFixIt".test(), PASSED_INDEX, now, allTests)
data.addTest("Test.textZZZ".test(), PASSED_INDEX, now, allTests)
data.addTest("Test.textQQQ".test(), PASSED_INDEX, now, allTests)
data.addTest("JFSDTest.testUnconditionalAlignmentErrorneous".test(), PASSED_INDEX, now, allTests)
val tests = data.getTestsToShow()
assertThat(tests).hasSize(1)
@@ -56,31 +68,31 @@ class RecentTestsStepTest: LightIdeaTestCase() {
fun `test if one failed in run configuration show failed suite`() {
data.addSuite("java:suite://JavaFormatterSuperDuperTest", TestStateInfo.Magnitude.FAILED_INDEX, now, allTests)
data.addSuite("java:suite://Test", TestStateInfo.Magnitude.PASSED_INDEX, now, allTests)
data.addSuite("JFSDTest".suite(), FAILED_INDEX, now, allTests)
data.addSuite("Test".test(), PASSED_INDEX, now, allTests)
data.addTest("java:test://JavaFormatterSuperDuperTest.testItMakesMeSadToFixIt", TestStateInfo.Magnitude.FAILED_INDEX, now, allTests)
data.addTest("java:test://JavaFormatterSuperDuperTest.testUnconditionalAlignmentErrorneous", TestStateInfo.Magnitude.PASSED_INDEX, now, allTests)
data.addTest("JFSDTest.testItMakesMeSadToFixIt".test(), FAILED_INDEX, now, allTests)
data.addTest("JFSDTest.testUnconditionalAlignmentErrorneous".test(), PASSED_INDEX, now, allTests)
data.addTest("java:test://Test.textXXX", TestStateInfo.Magnitude.PASSED_INDEX, now, allTests)
data.addTest("Test.textXXX".test(), PASSED_INDEX, now, allTests)
val tests = data.getTestsToShow()
assertThat(tests).hasSize(2)
assertThat(tests[0].presentation).isEqualTo("JavaFormatterSuperDuperTest")
assertThat(tests[0].presentation).isEqualTo("JFSDTest")
assertThat(tests[1].presentation).isEqualTo("all tests")
}
fun `test if configuration with single test show failed test`() {
data.addSuite("java:suite://JavaFormatterSuperDuperTest", TestStateInfo.Magnitude.FAILED_INDEX, now, allTests)
data.addTest("java:test://JavaFormatterSuperDuperTest.testItMakesMeSadToFixIt", TestStateInfo.Magnitude.FAILED_INDEX, now, allTests)
data.addTest("java:test://JavaFormatterSuperDuperTest.testUnconditionalAlignmentErrorneous", TestStateInfo.Magnitude.PASSED_INDEX, now, allTests)
data.addSuite("JFSDTest".suite(), FAILED_INDEX, now, allTests)
data.addTest("JFSDTest.testItMakesMeSadToFixIt".test(), FAILED_INDEX, now, allTests)
data.addTest("JFSDTest.testUnconditionalAlignmentErrorneous".test(), PASSED_INDEX, now, allTests)
val tests = data.getTestsToShow()
assertThat(tests).hasSize(2)
assertThat(tests[0].presentation).isEqualTo("JavaFormatterSuperDuperTest.testItMakesMeSadToFixIt")
assertThat(tests[1].presentation).isEqualTo("JavaFormatterSuperDuperTest")
assertThat(tests[0].presentation).isEqualTo("JFSDTest.testItMakesMeSadToFixIt")
assertThat(tests[1].presentation).isEqualTo("JFSDTest")
}
@@ -0,0 +1,39 @@
/*
* Copyright 2000-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.codeInsight.daemon.impl;
import com.intellij.lang.ASTNode;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.PsiElement;
import com.intellij.psi.TokenType;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class DefaultHighlightUtil {
@Nullable
public static HighlightInfo checkBadCharacter(@NotNull PsiElement element) {
ASTNode node = element.getNode();
if (node != null && node.getElementType() == TokenType.BAD_CHARACTER) {
char c = element.textToCharArray()[0];
boolean printable = StringUtil.isPrintableUnicode(c) && !Character.isSpaceChar(c);
String hex = String.format("U+%04X", (int)c);
String text = "Illegal character: " + (printable ? c + " (" + hex + ")" : hex);
return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(element).descriptionAndTooltip(text).create();
}
return null;
}
}
@@ -18,7 +18,6 @@ package com.intellij.codeInsight.daemon.impl;
import com.intellij.codeInsight.daemon.impl.analysis.ErrorQuickFixProvider;
import com.intellij.codeInsight.daemon.impl.analysis.HighlightInfoHolder;
import com.intellij.codeInsight.highlighting.HighlightErrorFilter;
import com.intellij.lang.ASTNode;
import com.intellij.lang.LanguageUtil;
import com.intellij.lang.annotation.Annotation;
import com.intellij.lang.annotation.Annotator;
@@ -29,7 +28,10 @@ import com.intellij.openapi.project.DumbService;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.*;
import com.intellij.psi.FileViewProvider;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiErrorElement;
import com.intellij.psi.PsiFile;
import org.jetbrains.annotations.NotNull;
import java.util.List;
@@ -47,18 +49,22 @@ class DefaultHighlightVisitor implements HighlightVisitor, DumbAware {
private final DumbService myDumbService;
private HighlightInfoHolder myHolder;
private final boolean myBatchMode;
private final CachedAnnotators cachedAnnotators;
private final CachedAnnotators myCachedAnnotators;
@SuppressWarnings("UnusedDeclaration")
DefaultHighlightVisitor(@NotNull Project project, @NotNull CachedAnnotators cachedAnnotators) {
this(project, true, true, false, cachedAnnotators);
}
DefaultHighlightVisitor(@NotNull Project project, boolean highlightErrorElements, boolean runAnnotators, boolean batchMode, @NotNull CachedAnnotators cachedAnnotators) {
DefaultHighlightVisitor(@NotNull Project project,
boolean highlightErrorElements,
boolean runAnnotators,
boolean batchMode,
@NotNull CachedAnnotators cachedAnnotators) {
myProject = project;
myHighlightErrorElements = highlightErrorElements;
myRunAnnotators = runAnnotators;
this.cachedAnnotators = cachedAnnotators;
myCachedAnnotators = cachedAnnotators;
myErrorFilters = Extensions.getExtensions(HighlightErrorFilter.EP_NAME, project);
myDumbService = DumbService.getInstance(project);
myBatchMode = batchMode;
@@ -93,15 +99,6 @@ class DefaultHighlightVisitor implements HighlightVisitor, DumbAware {
if (myHighlightErrorElements) visitErrorElement((PsiErrorElement)element);
}
else {
ASTNode node = element.getNode();
if (node != null && node.getElementType() == TokenType.BAD_CHARACTER) {
char c = element.textToCharArray()[0];
boolean printable = StringUtil.isPrintableUnicode(c) && !Character.isSpaceChar(c);
String hex = String.format("U+%04X", (int)c);
String text = "Illegal character: " + (printable ? c + " (" + hex + ")" : hex);
myHolder.add(HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(element).descriptionAndTooltip(text).create());
}
if (myRunAnnotators) runAnnotators(element);
}
@@ -117,7 +114,7 @@ class DefaultHighlightVisitor implements HighlightVisitor, DumbAware {
@Override
@NotNull
public HighlightVisitor clone() {
return new DefaultHighlightVisitor(myProject, myHighlightErrorElements, myRunAnnotators, myBatchMode,cachedAnnotators);
return new DefaultHighlightVisitor(myProject, myHighlightErrorElements, myRunAnnotators, myBatchMode, myCachedAnnotators);
}
@Override
@@ -126,7 +123,7 @@ class DefaultHighlightVisitor implements HighlightVisitor, DumbAware {
}
private void runAnnotators(PsiElement element) {
List<Annotator> annotators = cachedAnnotators.get(element.getLanguage().getID());
List<Annotator> annotators = myCachedAnnotators.get(element.getLanguage().getID());
if (annotators.isEmpty()) return;
final boolean dumb = myDumbService.isDumb();
@@ -203,4 +200,4 @@ class DefaultHighlightVisitor implements HighlightVisitor, DumbAware {
}
return info;
}
}
}
@@ -533,30 +533,34 @@ public abstract class PsiDocumentManagerBase extends PsiDocumentManager implemen
@Override
public void performLaterWhenAllCommitted(@NotNull final Runnable runnable) {
final ModalityState modalityState = ModalityState.current();
UIUtil.invokeLaterIfNeeded(new Runnable() {
final ModalityState modalityState = ModalityState.defaultModalityState();
final Runnable whenAllCommitted = new Runnable() {
@Override
public void run() {
performWhenAllCommitted(new Runnable() {
ApplicationManager.getApplication().invokeLater(new Runnable() {
@Override
public void run() {
// later because we may end up in write action here if there was a synchronous commit
ApplicationManager.getApplication().invokeLater(new Runnable() {
@Override
public void run() {
if (hasUncommitedDocuments()) {
// no luck, will try later
performLaterWhenAllCommitted(runnable);
}
else {
runnable.run();
}
}
}, modalityState, myProject.getDisposed());
if (hasUncommitedDocuments()) {
// no luck, will try later
performLaterWhenAllCommitted(runnable);
}
else {
runnable.run();
}
}
});
}, modalityState, myProject.getDisposed());
}
});
};
if (ApplicationManager.getApplication().isDispatchThread() && isInsideCommitHandler()) {
whenAllCommitted.run();
} else {
UIUtil.invokeLaterIfNeeded(new Runnable() {
@Override
public void run() {
performWhenAllCommitted(whenAllCommitted);
}
});
}
}
private static class CompositeRunnable extends ArrayList<Runnable> implements Runnable {
@@ -586,7 +590,7 @@ public abstract class PsiDocumentManagerBase extends PsiDocumentManager implemen
if (!hasUncommitedDocuments() && !actionsWhenAllDocumentsAreCommitted.isEmpty()) {
List<Map.Entry<Object, Runnable>> entries = new ArrayList<Map.Entry<Object, Runnable>>(new LinkedHashMap<Object, Runnable>(actionsWhenAllDocumentsAreCommitted).entrySet());
weAreInsideAfterCommitHandler();
beforeCommitHandler();
try {
for (Map.Entry<Object, Runnable> entry : entries) {
@@ -605,15 +609,19 @@ public abstract class PsiDocumentManagerBase extends PsiDocumentManager implemen
}
}
private void weAreInsideAfterCommitHandler() {
private void beforeCommitHandler() {
actionsWhenAllDocumentsAreCommitted.put(PERFORM_ALWAYS_KEY, EmptyRunnable.getInstance()); // to prevent listeners from registering new actions during firing
}
private void checkWeAreOutsideAfterCommitHandler() {
if (actionsWhenAllDocumentsAreCommitted.get(PERFORM_ALWAYS_KEY) == EmptyRunnable.getInstance()) {
if (isInsideCommitHandler()) {
throw new IncorrectOperationException("You must not call performWhenAllCommitted()/cancelAndRunWhenCommitted() from within after-commit handler");
}
}
private boolean isInsideCommitHandler() {
return actionsWhenAllDocumentsAreCommitted.get(PERFORM_ALWAYS_KEY) == EmptyRunnable.getInstance();
}
@Override
public void addListener(@NotNull Listener listener) {
myListeners.add(listener);
@@ -15,6 +15,7 @@
*/
package com.intellij.psi.impl.source;
import com.intellij.concurrency.JobScheduler;
import com.intellij.extapi.psi.StubBasedPsiElementBase;
import com.intellij.psi.impl.source.tree.AstPath;
import com.intellij.psi.impl.source.tree.CompositeElement;
@@ -26,6 +27,7 @@ import org.jetbrains.annotations.Nullable;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.WeakReference;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.TimeUnit;
/**
* A weak cache for all instantiated stub-based PSI to allow {@link CompositeElement#getPsi()} return it when AST is reloaded.<p/>
@@ -39,6 +41,16 @@ class AstPathPsiMap {
*/
private final ConcurrentMap<AstPath, MyReference> myMap = ContainerUtil.newConcurrentMap();
static {
JobScheduler.getScheduler().scheduleWithFixedDelay(new Runnable() {
@Override
public void run() {
// clean up AstPath objects when no PSI is accessed, e.g. after project closing
processQueue();
}
}, 5, 5, TimeUnit.SECONDS);
}
void invalidatePsi() {
processQueue();
for (MyReference reference : myMap.values()) {
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2015 JetBrains s.r.o.
* Copyright 2000-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -24,6 +24,7 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.picocontainer.*;
import org.picocontainer.defaults.*;
import org.picocontainer.defaults.ConstructorInjectionComponentAdapter;
import java.io.Serializable;
import java.util.*;
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.psi.impl.source.codeStyle;
package com.intellij.psi.codeStyle.lineIndent;
import com.intellij.lang.Language;
import com.intellij.openapi.editor.Editor;
@@ -13,10 +13,11 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.psi.impl.source.codeStyle;
package com.intellij.psi.codeStyle.lineIndent;
import com.intellij.lang.Language;
import com.intellij.openapi.extensions.ExtensionPointName;
import com.intellij.psi.codeStyle.lineIndent.LineIndentProvider;
import org.jetbrains.annotations.Nullable;
/**
@@ -27,9 +27,10 @@ import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.options.Configurable;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.PsiFile;
import com.intellij.psi.codeStyle.CodeStyleManager;
import com.intellij.psi.codeStyle.CodeStyleSettingsManager;
import com.intellij.psi.codeStyle.lineIndent.LineIndentProvider;
import com.intellij.psi.codeStyle.lineIndent.LineIndentProviderEP;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.psi.impl.source.codeStyle;
package com.intellij.psi.impl.source.codeStyle.lineIndent;
import com.intellij.lang.Language;
import com.intellij.openapi.editor.Document;
@@ -21,6 +21,7 @@ import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.codeStyle.CodeStyleManager;
import com.intellij.psi.codeStyle.lineIndent.LineIndentProvider;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.psi.impl.source.codeStyle;
package com.intellij.psi.impl.source.codeStyle.lineIndent;
import com.intellij.formatting.IndentInfo;
import com.intellij.lang.Language;
@@ -26,6 +26,7 @@ import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.PsiFile;
import com.intellij.psi.codeStyle.CodeStyleSettingsManager;
import com.intellij.psi.codeStyle.CommonCodeStyleSettings;
import com.intellij.psi.impl.source.codeStyle.SemanticEditorPosition;
import com.intellij.psi.impl.source.codeStyle.SemanticEditorPosition.SyntaxElement;
import com.intellij.psi.tree.IElementType;
import com.intellij.util.text.CharArrayUtil;
@@ -34,7 +35,7 @@ import org.jetbrains.annotations.Nullable;
import static com.intellij.formatting.Indent.Type;
import static com.intellij.formatting.Indent.Type.*;
import static com.intellij.psi.impl.source.codeStyle.JavaLikeLangLineIndentProvider.JavaLikeElement.*;
import static com.intellij.psi.impl.source.codeStyle.lineIndent.JavaLikeLangLineIndentProvider.JavaLikeElement.*;
/**
* A base class Java-like language line indent provider. If JavaLikeLangLineIndentProvider is unable to calculate
@@ -88,6 +89,11 @@ public abstract class JavaLikeLangLineIndentProvider extends FormatterBasedLineI
)) {
return createIndentData(CONTINUATION, ArrayOpeningBracket);
}
else if (getPosition(editor, offset).matchesRule(
position -> position.before().isAt(LeftParenthesis)
)) {
return createIndentData(CONTINUATION, LeftParenthesis);
}
else if (getPosition(editor, offset).matchesRule(
position -> position.before().isAt(BlockOpeningBrace)
)) {
@@ -44,6 +44,7 @@ import com.intellij.ui.UIBundle;
import com.intellij.ui.border.CustomLineBorder;
import com.intellij.ui.components.JBOptionButton;
import com.intellij.ui.components.JBScrollPane;
import com.intellij.ui.components.panels.NonOpaquePanel;
import com.intellij.util.Alarm;
import com.intellij.util.ArrayUtil;
import com.intellij.util.TimeoutUtil;
@@ -468,8 +469,15 @@ public abstract class DialogWrapper {
actions = ArrayUtil.remove(actions, getHelpAction());
}
JPanel panel = new JPanel(new BorderLayout());
final JPanel lrButtonsPanel = new JPanel(new GridBagLayout());
JPanel panel = new JPanel(new BorderLayout()) {
@Override
public Color getBackground() {
final Color bg = UIManager.getColor("DialogWrapper.southPanelBackground");
return bg != null ? bg : super.getBackground();
}
};
final JPanel lrButtonsPanel = new NonOpaquePanel(new GridBagLayout());
//noinspection UseDPIAwareInsets
final Insets insets = SystemInfo.isMacOSLeopard ? UIUtil.isUnderIntelliJLaF() ? JBUI.insets(0, 8) : JBUI.emptyInsets() : new Insets(8, 0, 0, 0); //don't wrap to JBInsets
if (actions.length > 0 || leftSideActions.length > 0) {
@@ -551,12 +559,12 @@ public abstract class DialogWrapper {
}
if (getStyle() == DialogStyle.COMPACT) {
Border line = new CustomLineBorder(OnePixelDivider.BACKGROUND, 1, 0, 0, 0);
final Color color = UIManager.getColor("DialogWrapper.southPanelDivider");
Border line = new CustomLineBorder(color != null ? color : OnePixelDivider.BACKGROUND, 1, 0, 0, 0);
panel.setBorder(new CompoundBorder(line, JBUI.Borders.empty(8, 12)));
} else {
panel.setBorder(JBUI.Borders.emptyTop(8));
}
return panel;
}
@@ -636,7 +644,7 @@ public abstract class DialogWrapper {
}
}
JPanel buttonsPanel = new JPanel(new GridLayout(1, actions.length, SystemInfo.isMacOSLeopard ? UIUtil.isUnderIntelliJLaF() ? 8 : 0 : 5, 0));
JPanel buttonsPanel = new NonOpaquePanel(new GridLayout(1, actions.length, SystemInfo.isMacOSLeopard ? UIUtil.isUnderIntelliJLaF() ? 8 : 0 : 5, 0));
for (final Action action : actions) {
JButton button = createJButtonForAction(action);
final Object value = action.getValue(Action.MNEMONIC_KEY);
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2015 JetBrains s.r.o.
* Copyright 2000-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -36,7 +36,10 @@ import java.awt.event.MouseEvent;
* @author Konstantin Bulenkov
*/
public class OnePixelDivider extends Divider {
public static final Color BACKGROUND = new JBColor(Gray.xC5, Gray.x51);
public static final Color BACKGROUND = new JBColor(() -> {
final Color bg = UIManager.getColor("OnePixelDivider.background");
return bg != null ? bg : new JBColor(Gray.xC5, Gray.x51);
});
private boolean myVertical;
private Splittable mySplitter;
@@ -187,6 +187,7 @@ public class CheckBoxList<T> extends JBList {
public void addItem(T item, String text, boolean selected) {
JCheckBox checkBox = new JCheckBox(text, selected);
checkBox.setOpaque(true); // to paint selection background
myItemMap.put(item, checkBox);
//noinspection unchecked
((DefaultListModel)getModel()).addElement(checkBox);
@@ -22,6 +22,7 @@ import javax.swing.event.TreeModelEvent;
import javax.swing.event.TreeModelListener;
import javax.swing.table.AbstractTableModel;
import javax.swing.tree.TreePath;
import java.util.concurrent.atomic.AtomicInteger;
/**
* This is a wrapper class takes a TreeTableModel and implements
@@ -35,6 +36,9 @@ import javax.swing.tree.TreePath;
* @author Scott Violet
*/
public class TreeTableModelAdapter extends AbstractTableModel {
private final AtomicInteger modificationStamp = new AtomicInteger();
private final JTree tree;
private final TreeTableModel treeTableModel;
private final JTable table;
@@ -123,7 +127,12 @@ public class TreeTableModelAdapter extends AbstractTableModel {
* processed. SwingUtilities.invokeLater is used to handle this.
*/
protected void delayedFireTableDataChanged() {
SwingUtilities.invokeLater(() -> fireTableDataChanged());
long stamp = modificationStamp.incrementAndGet();
//noinspection SSBasedInspection
SwingUtilities.invokeLater(() -> {
if (stamp != modificationStamp.get()) return;
fireTableDataChanged();
});
}
public void fireTableDataChanged() {
@@ -949,6 +949,9 @@ public class HintManagerImpl extends HintManager implements Disposable {
myQuestionAction = null;
myQuestionHint = null;
if (myLastEditor != null && project == myLastEditor.getProject()) {
updateLastEditor(null);
}
}
}
@@ -162,13 +162,19 @@ public class DarculaButtonUI extends BasicButtonUI {
@Override
public void update(Graphics g, JComponent c) {
super.update(g, c);
if (isDefaultButton(c) && !SystemInfo.isMac) {
if (!c.getFont().isBold()) {
c.setFont(new FontUIResource(c.getFont().deriveFont(Font.BOLD)));
if (isDefaultButton(c)) {
setupDefaultButton((JButton)c);
}
}
protected void setupDefaultButton(JButton button) {
if (!SystemInfo.isMac) {
if (!button.getFont().isBold()) {
button.setFont(new FontUIResource(button.getFont().deriveFont(Font.BOLD)));
}
}
}
public static boolean isHelpButton(JComponent button) {
return (SystemInfo.isMac || (SystemInfo.isWindows && Registry.is("ide.intellij.laf.win10.ui")))
&& button instanceof JButton
@@ -35,15 +35,9 @@ public class WinIntelliJButtonPainter implements Border, UIResource {
@Override
public void paintBorder(Component c, Graphics graphics, int x, int y, int width, int height) {
Graphics2D g = (Graphics2D)graphics;
final Insets ins = getBorderInsets(c);
final int yOff = (ins.top + ins.bottom) / 4;
final boolean square = DarculaButtonUI.isSquare(c);
int offset = JBUI.scale(square ? 1 : getOffset());
int w = c.getWidth();
int h = c.getHeight();
int diam = JBUI.scale(22);
if (c.hasFocus() || DarculaButtonUI.isDefaultButton((JComponent)c)) {
final boolean hasFocus = c.hasFocus();
final boolean isDefault = DarculaButtonUI.isDefaultButton((JComponent)c);
if (hasFocus || isDefault) {
if (DarculaButtonUI.isHelpButton((JComponent)c)) {
//todo
} else {
@@ -52,7 +46,7 @@ public class WinIntelliJButtonPainter implements Border, UIResource {
g.translate(x,y);
g.drawRect(JBUI.scale(1), JBUI.scale(1), width-2*JBUI.scale(1), height-2*JBUI.scale(1));
if (c.hasFocus()) {
if (hasFocus) {
g.setStroke(new BasicStroke(JBUI.scale(1f)));
g.setColor(Gray.x00);
UIUtil.drawDottedRectangle(g, JBUI.scale(1) + 1, JBUI.scale(1) + 1, width-2*JBUI.scale(1) - 1, height-2*JBUI.scale(1) - 1);
@@ -72,12 +66,12 @@ public class WinIntelliJButtonPainter implements Border, UIResource {
@Override
public Insets getBorderInsets(Component c) {
if (c.getParent() instanceof ActionToolbar) {
return JBUI.insets(4, 16, 4, 16);
return JBUI.insets(4, 16).asUIResource();
}
if (DarculaButtonUI.isSquare(c)) {
return JBUI.insets(2, 0, 2, 0).asUIResource();
return JBUI.insets(2, 0).asUIResource();
}
return JBUI.insets(3, 17, 3, 15).asUIResource();
return JBUI.insets(3, 17).asUIResource();
}
protected int getOffset() {
@@ -74,6 +74,11 @@ public class WinIntelliJButtonUI extends DarculaButtonUI {
return true;
}
@Override
protected void setupDefaultButton(JButton button) {
//do nothing
}
@Override
protected void paintDisabledText(Graphics g, String text, JComponent c, Rectangle textRect, FontMetrics metrics) {
g.setColor(UIManager.getColor("Button.disabledText"));
@@ -67,4 +67,9 @@ public class WinIntelliJCheckBoxUI extends IntelliJCheckBoxUI {
UIUtil.drawDottedRectangle(g, textRect.x - 2, textRect.y - 1, textRect.width + textRect.x + 1, textRect.height + 3);
}
}
@Override
public Icon getDefaultIcon() {
return JBUI.emptyIcon(18).asUIResource();
}
}
@@ -18,6 +18,9 @@ textInactiveText=999999
textText=000000
infoText=000000
OptionPane.messageForeground=000000
DialogWrapper.southPanelDivider=f0f0f0
DialogWrapper.southPanelBackground=f0f0f0
OnePixelDivider.background=ffffff
Menu.maxGutterIconWidth=18
MenuItem.maxGutterIconWidth=18
@@ -289,7 +289,7 @@
<extensionPoint name="preFormatProcessor" interface="com.intellij.psi.impl.source.codeStyle.PreFormatProcessor"/>
<extensionPoint name="postFormatProcessor" interface="com.intellij.psi.impl.source.codeStyle.PostFormatProcessor"/>
<extensionPoint name="disabledIndentRangesProvider" interface="com.intellij.psi.impl.source.DisabledIndentRangesProvider"/>
<extensionPoint name="lineIndentProvider" interface="com.intellij.psi.impl.source.codeStyle.LineIndentProvider"/>
<extensionPoint name="lineIndentProvider" interface="com.intellij.psi.codeStyle.lineIndent.LineIndentProvider"/>
<extensionPoint name="declarationRangeHandler" beanClass="com.intellij.util.MixinEP">
<with attribute="implementationClass" implements="com.intellij.codeInsight.hint.DeclarationRangeHandler"/>
@@ -953,7 +953,7 @@
<nonProjectFileWritingAccessExtension implementation="com.intellij.ide.actions.EditCustomPropertiesAction$AccessExtension"/>
<nonProjectFileWritingAccessExtension implementation="com.intellij.ide.actions.EditCustomVmOptionsAction$AccessExtension"/>
<lineIndentProvider implementation="com.intellij.psi.impl.source.codeStyle.FormatterBasedLineIndentProvider"/>
<lineIndentProvider implementation="com.intellij.psi.impl.source.codeStyle.lineIndent.FormatterBasedLineIndentProvider"/>
</extensions>
</idea-plugin>
@@ -671,4 +671,22 @@ public class PsiDocumentManagerImplTest extends PlatformTestCase {
assertTrue(PsiDocumentManager.getInstance(myProject).isCommitted(document));
}
@SuppressWarnings("ConstantConditions")
public void testPerformLaterWhenAllCommittedFromCommitHandler() throws Exception {
PsiFile file = getPsiManager().findFile(getVirtualFile(createTempFile("X.txt", "")));
Document document = file.getViewProvider().getDocument();
PsiDocumentManager pdm = PsiDocumentManager.getInstance(myProject);
WriteCommandAction.runWriteCommandAction(null, () -> document.insertString(0, "a"));
pdm.performWhenAllCommitted(
() -> pdm.performLaterWhenAllCommitted(
() -> WriteCommandAction.runWriteCommandAction(null, () -> document.insertString(1, "b"))));
assertTrue(pdm.hasUncommitedDocuments());
assertEquals("a", document.getText());
DocumentCommitThread.getInstance().waitForAllCommits();
assertEquals("ab", document.getText());
}
}
@@ -58,10 +58,16 @@ public abstract class UsageContextPanelBase extends JPanel implements UsageConte
@Override
public final void updateLayout(@Nullable final List<UsageInfo> infos) {
PsiDocumentManager.getInstance(myProject).performLaterWhenAllCommitted(() -> {
if (isDisposed || myProject.isDisposed()) return;
PsiDocumentManager pdm = PsiDocumentManager.getInstance(myProject);
if (!pdm.hasUncommitedDocuments()) {
updateLayoutLater(infos);
});
} else {
pdm.performLaterWhenAllCommitted(() -> {
if (isDisposed || myProject.isDisposed()) return;
updateLayoutLater(infos);
});
}
}
protected abstract void updateLayoutLater(@Nullable List<UsageInfo> infos);
@@ -17,6 +17,7 @@
package com.intellij.usages.impl;
import com.intellij.lang.injection.InjectedLanguageManager;
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.*;
@@ -34,6 +35,7 @@ import com.intellij.usageView.UsageViewBundle;
import com.intellij.usages.UsageContextPanel;
import com.intellij.usages.UsageView;
import com.intellij.usages.UsageViewPresentation;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -44,7 +46,7 @@ import java.util.List;
/**
* @author cdr
*/
public class UsagePreviewPanel extends UsageContextPanelBase {
public class UsagePreviewPanel extends UsageContextPanelBase implements DataProvider {
private static final Logger LOG = Logger.getInstance("#com.intellij.usages.impl.UsagePreviewPanel");
private Editor myEditor;
private final boolean myIsEditor;
@@ -61,6 +63,15 @@ public class UsagePreviewPanel extends UsageContextPanelBase {
myIsEditor = isEditor;
}
@Nullable
@Override
public Object getData(@NonNls String dataId) {
if (CommonDataKeys.EDITOR.getName().equals(dataId) && myEditor != null) {
return myEditor;
}
return null;
}
public static class Provider implements UsageContextPanel.Provider {
@NotNull
@Override
@@ -211,6 +222,8 @@ public class UsagePreviewPanel extends UsageContextPanelBase {
}
}
@Override
public void updateLayoutLater(@Nullable final List<UsageInfo> infos) {
if (infos == null) {
@@ -1572,7 +1572,10 @@ public class UsageViewImpl implements UsageView, UsageModelTracker.UsageModelTra
VirtualFile[] data = UsageDataUtil.provideVirtualFileArray(ua, getSelectedUsageTargets());
sink.put(CommonDataKeys.VIRTUAL_FILE_ARRAY, data);
}
else if (key == CommonDataKeys.EDITOR && myCurrentUsageContextPanel instanceof DataProvider) {
Object editor = ((DataProvider)myCurrentUsageContextPanel).getData(key.getName());
if (editor != null) sink.put(key, editor);
}
else if (key == PlatformDataKeys.HELP_ID) {
sink.put(PlatformDataKeys.HELP_ID, HELP_ID);
}
@@ -268,7 +268,7 @@ vcs.log.recent.commits.count=1000
vcs.log.recent.commits.count.description=Before full log is loaded (which can take some time), a number of recent commits is loaded to show quickly
vcs.log.open.another.log.visible=false
vcs.log.open.another.log.visible.description=An action that opens a new tab with log
vcs.log.keep.up.to.date=false
vcs.log.keep.up.to.date=true
vcs.log.keep.up.to.date.description=Load log on start after heavy tasks are completed and keep it up to date even when not visible
vcs.executable.validator.timeout.sec=60
@@ -33,7 +33,6 @@ import org.jdom.Document;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.picocontainer.PicoContainer;
import java.io.*;
import java.net.URL;
@@ -455,7 +454,6 @@ public class PathManager {
Document.class, // jDOM
Appender.class, // log4j
THashSet.class, // trove4j
PicoContainer.class, // PicoContainer
TypeMapper.class, // JNA
FileUtils.class, // JNA (jna-platform)
PatternMatcher.class, // OROMatcher
@@ -98,6 +98,10 @@ public class FileUtil extends FileUtilRt {
return new File(path).isAbsolute();
}
public static boolean exists(@Nullable String path) {
return path != null && new File(path).exists();
}
/**
* Check if the {@code ancestor} is an ancestor of {@code file}.
*
-1
View File
@@ -15,7 +15,6 @@
<orderEntry type="library" name="JDOM" level="project" />
<orderEntry type="library" name="Log4J" level="project" />
<orderEntry type="library" exported="" name="Trove4j" level="project" />
<orderEntry type="library" name="picocontainer" level="project" />
<orderEntry type="module" module-name="platform-resources-en" />
<orderEntry type="module" module-name="annotations" exported="" />
<orderEntry type="module" module-name="util-rt" exported="" />
@@ -17,7 +17,9 @@ package com.siyeh.ig.naming;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiMethod;
import com.intellij.psi.PsiSubstitutor;
import com.intellij.psi.util.MethodSignatureUtil;
import com.intellij.psi.util.TypeConversionUtil;
import com.siyeh.InspectionGadgetsBundle;
import com.siyeh.ig.BaseInspection;
import com.siyeh.ig.BaseInspectionVisitor;
@@ -65,7 +67,11 @@ public class OverloadedVarargsMethodInspection extends BaseInspection {
final String methodName = method.getName();
final PsiMethod[] sameNameMethods = aClass.findMethodsByName(methodName, true);
for (PsiMethod sameNameMethod : sameNameMethods) {
if (!MethodSignatureUtil.areSignaturesEqual(sameNameMethod, method)) {
PsiClass superClass = sameNameMethod.getContainingClass();
PsiSubstitutor substitutor = superClass != null ? TypeConversionUtil.getSuperClassSubstitutor(superClass, aClass, PsiSubstitutor.EMPTY)
: PsiSubstitutor.EMPTY;
if (!MethodSignatureUtil.areSignaturesEqual(sameNameMethod.getSignature(substitutor),
method.getSignature(PsiSubstitutor.EMPTY))) {
registerMethodError(method, method);
return;
}
@@ -55,4 +55,14 @@ public class OverloadedVarargsMethodInspectionTest extends LightInspectionTestCa
" public void test(String... ss) {}" +
"}");
}
public void testGenericMethods() throws Exception {
doTest("interface Foo<T> {" +
" void makeItSo(T command, int... values);" +
" }" +
" class Bar implements Foo<String> {" +
" public void makeItSo(final String command, final int... values) {" +
" }" +
" }");
}
}
+8 -1
View File
@@ -51,6 +51,8 @@ import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import static com.intellij.openapi.util.io.FileUtil.toSystemDependentName;
/**
* @author anna
* @since Nov 22, 2004
@@ -325,8 +327,13 @@ public class IdeaJdk extends JavaDependentSdkType implements JavaSdkType {
LocalFileSystem localFileSystem = LocalFileSystem.getInstance();
VirtualFile out = localFileSystem.refreshAndFindFileByPath(sdkHome + OUT_CLASSES);
if (out != null) {
for (VirtualFile dir : out.getChildren()) {
List<String> suppressed = Arrays.asList("jps-plugin-system");
for (VirtualFile dir : JBIterable.of(out.findChild("resources")).append(out.getChildren())) {
if (!dir.isDirectory()) continue;
String name = dir.getName();
if (name.endsWith("-ide") || suppressed.contains(name)) continue;
if (!name.equals("ultimate-resources") &&
FileUtil.exists(toSystemDependentName(dir.getPath() + "/META-INF/plugin.xml"))) continue;
sdkModificator.addRoot(dir, OrderRootType.CLASSES);
}
}
@@ -186,8 +186,6 @@ public class PluginRunConfiguration extends RunConfigurationBase implements Modu
if (fromIdeaProject) {
for (String url : usedIdeaJdk.getRootProvider().getUrls(OrderRootType.CLASSES)) {
String s = StringUtil.trimEnd(VfsUtilCore.urlToPath(url), JarFileSystem.JAR_SEPARATOR);
if (s.endsWith("plugin-system")) continue;
if (new File(toSystemDependentName(s+ "/META-INF/plugin.xml")).exists()) continue;
params.getClassPath().add(toSystemDependentName(s));
}
}
@@ -63,6 +63,7 @@ public class JUnitConfiguration extends JavaTestConfigurationBase {
@NonNls public static final String FORK_NONE = "none";
@NonNls public static final String FORK_METHOD = "method";
@NonNls public static final String FORK_KLASS = "class";
@NonNls public static final String FORK_REPEAT = "repeat";
// See #26522
@NonNls public static final String JUNIT_START_CLASS = "com.intellij.rt.execution.junit.JUnitStarter";
@NonNls private static final String PATTERN_EL_NAME = "pattern";
@@ -20,10 +20,12 @@ import com.intellij.execution.ExecutionBundle;
import com.intellij.execution.ExecutionException;
import com.intellij.execution.JavaExecutionUtil;
import com.intellij.execution.configurations.*;
import com.intellij.execution.junit2.configuration.JUnitConfigurationModel;
import com.intellij.execution.runners.ExecutionEnvironment;
import com.intellij.openapi.util.Comparing;
import com.intellij.psi.*;
import com.intellij.refactoring.listeners.RefactoringElementListener;
import org.jetbrains.annotations.NotNull;
class TestClass extends TestObject {
public TestClass(JUnitConfiguration configuration, ExecutionEnvironment environment) {
@@ -38,6 +40,13 @@ class TestClass extends TestObject {
return javaParameters;
}
@NotNull
@Override
protected String getForkMode() {
String forkMode = super.getForkMode();
return JUnitConfiguration.FORK_KLASS.equals(forkMode) ? JUnitConfiguration.FORK_REPEAT : forkMode;
}
@Override
public String suggestActionName() {
String name = getConfiguration().getPersistentData().MAIN_CLASS_NAME;
@@ -233,7 +233,16 @@ public class JUnitConfigurable<T extends JUnitConfiguration> extends SettingsEdi
}
}
);
myModel.setType(JUnitConfigurationModel.CLASS);
myRepeatCb.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if ((Integer) myTypeChooser.getSelectedItem() == JUnitConfigurationModel.CLASS) {
myForkCb.setModel(getForkModelBasedOnRepeat());
}
}
});
//myModel.setType(JUnitConfigurationModel.CLASS);
installDocuments();
addRadioButtonsListeners(new JRadioButton[]{myWholeProjectScope, mySingleModuleScope, myModuleWDScope}, null);
myWholeProjectScope.addChangeListener(new ChangeListener() {
@@ -286,6 +295,11 @@ public class JUnitConfigurable<T extends JUnitConfiguration> extends SettingsEdi
}
public void resetEditorFrom(final JUnitConfiguration configuration) {
final int count = configuration.getRepeatCount();
myRepeatCountField.setText(String.valueOf(count));
myRepeatCountField.setEnabled(count > 1);
myRepeatCb.setSelectedItem(configuration.getRepeatMode());
myModel.reset(configuration);
myCommonJavaParameters.reset(configuration);
getModuleSelector().reset(configuration);
@@ -302,10 +316,6 @@ public class JUnitConfigurable<T extends JUnitConfiguration> extends SettingsEdi
myJrePathEditor
.setPathOrName(configuration.getAlternativeJrePath(), configuration.isAlternativeJrePathEnabled());
myForkCb.setSelectedItem(configuration.getForkMode());
final int count = configuration.getRepeatCount();
myRepeatCountField.setText(String.valueOf(count));
myRepeatCountField.setEnabled(count > 1);
myRepeatCb.setSelectedItem(configuration.getRepeatMode());
}
private void changePanel () {
@@ -346,7 +356,7 @@ public class JUnitConfigurable<T extends JUnitConfiguration> extends SettingsEdi
myCategory.setVisible(false);
myMethod.setVisible(false);
myForkCb.setEnabled(true);
myForkCb.setModel(new DefaultComboBoxModel(FORK_MODE));
myForkCb.setModel(getForkModelBasedOnRepeat());
myForkCb.setSelectedItem(selectedItem != JUnitConfiguration.FORK_KLASS ? selectedItem : JUnitConfiguration.FORK_METHOD);
}
else if (selectedType == JUnitConfigurationModel.METHOD){
@@ -385,6 +395,10 @@ public class JUnitConfigurable<T extends JUnitConfiguration> extends SettingsEdi
}
}
private DefaultComboBoxModel getForkModelBasedOnRepeat() {
return new DefaultComboBoxModel(RepeatCount.ONCE.equals(myRepeatCb.getSelectedItem()) ? FORK_MODE : FORK_MODE_ALL);
}
public ModulesComboBox getModulesComponent() {
return myModule.getComponent();
}
@@ -15,12 +15,15 @@
*/
package com.jetbrains.python.psi.resolve;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.vfs.*;
import com.intellij.psi.PsiElement;
import com.intellij.psi.util.QualifiedName;
import com.intellij.util.containers.ConcurrentHashMap;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@@ -28,28 +31,37 @@ import java.util.Map;
* @author yole
*/
public abstract class PythonPathCache {
private final Map<QualifiedName, List<PsiElement>> myCache = new ConcurrentHashMap<QualifiedName, List<PsiElement>>();
private final Map<VirtualFile, List<QualifiedName>> myQNameCache = new ConcurrentHashMap<VirtualFile, List<QualifiedName>>();
private final Map<QualifiedName, List<PsiElement>> myCache = ContainerUtil.newConcurrentMap();
private final Map<VirtualFile, List<QualifiedName>> myQNameCache = ContainerUtil.newConcurrentMap();
public void clearCache() {
myCache.clear();
myQNameCache.clear();
}
@Nullable
public List<PsiElement> get(QualifiedName qualifiedName) {
return myCache.get(qualifiedName);
final List<PsiElement> result = myCache.get(qualifiedName);
if (result == null) {
return null;
}
final boolean staleElementRemoved = result.removeIf(e -> !e.isValid());
if (staleElementRemoved) {
Logger.getInstance(PythonPathCache.class).warn("Removing invalid element from cache");
}
return (!result.isEmpty() ? result : null);
}
public void put(QualifiedName qualifiedName, List<PsiElement> results) {
myCache.put(qualifiedName, results);
myCache.put(qualifiedName, new ArrayList<>(results));
}
public List<QualifiedName> getNames(VirtualFile vFile) {
return myQNameCache.get(vFile);
}
public void putNames(VirtualFile vFile, List<QualifiedName> qNames) {
myQNameCache.put(vFile, qNames);
myQNameCache.put(vFile, new ArrayList<>(qNames));
}
protected class MyVirtualFileAdapter extends VirtualFileAdapter {
@@ -15,12 +15,12 @@
*/
package com.jetbrains.env;
import com.intellij.execution.ExecutionException;
import com.intellij.execution.process.ProcessAdapter;
import com.intellij.execution.process.ProcessEvent;
import com.intellij.execution.process.ProcessOutputTypes;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ModalityState;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.Ref;
@@ -53,6 +53,7 @@ import java.lang.reflect.InvocationTargetException;
* @author Ilya.Kazakevich
*/
public abstract class PyProcessWithConsoleTestTask<T extends ProcessWithConsoleRunner> extends PyExecutionFixtureTestTask {
private static final Logger LOG = Logger.getInstance(PyProcessWithConsoleTestTask.class);
@NotNull
private final SdkCreationType myRequiredSdkType;
@@ -91,6 +92,7 @@ public abstract class PyProcessWithConsoleTestTask<T extends ProcessWithConsoleR
public void processTerminated(final ProcessEvent event) {
super.processTerminated(event);
processFinishedSemaphore.up();
LOG.info(String.format("Thread finished %s", Thread.currentThread()));
}
@Override
@@ -121,7 +123,9 @@ public abstract class PyProcessWithConsoleTestTask<T extends ProcessWithConsoleR
}, ModalityState.NON_MODAL);
assert processFinishedSemaphore.waitFor(60000): "Timeout waiting semaphore";
LOG.info(String.format("Waiting for result on thread %s", Thread.currentThread()));
final boolean waitResult = processFinishedSemaphore.waitFor(60000);
assert waitResult : "Timeout waiting semaphore";
XDebuggerTestUtil.waitForSwing();
if (failed.get()) {
Assert.fail("Failed to run test, see logs for exceptions");
@@ -0,0 +1,58 @@
/*
* Copyright 2000-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.xml;
import com.intellij.javaee.ExternalResourceManagerExImpl;
import com.intellij.testFramework.PlatformTestUtil;
import com.intellij.testFramework.fixtures.LightPlatformCodeInsightFixtureTestCase;
import com.intellij.xml.util.CheckXmlFileWithXercesValidatorInspection;
import java.io.File;
/**
* @author ibessonov
*/
public class XmlEntityManagerCachingTest extends LightPlatformCodeInsightFixtureTestCase {
@Override
protected void setUp() throws Exception {
super.setUp();
ExternalResourceManagerExImpl.registerResourceTemporarily("http://dl.google.com/gwt/DTD/xhtml.ent",
getTestDataPath() + "xhtml.ent", getTestRootDisposable());
ExternalResourceManagerExImpl.registerResourceTemporarily("urn:ui:com.google.gwt.uibinder",
getTestDataPath() + "UiBinder.xsd", getTestRootDisposable());
myFixture.enableInspections(CheckXmlFileWithXercesValidatorInspection.class);
}
public void testXmlEntityManagerCaching() {
myFixture.configureByFile(getTestName(false) + ".ui.xml");
myFixture.checkHighlighting();
myFixture.type('\b'); // edit content, document has to be valid after that
myFixture.checkHighlighting();
}
@Override
protected String getBasePath() {
return "/xml/tests/testData/xml/";
}
@Override
protected String getTestDataPath() {
return PlatformTestUtil.getCommunityPath().replace(File.separatorChar, '/') + getBasePath();
}
}
+30
View File
@@ -0,0 +1,30 @@
<?xml version="1.0"?>
<xs:schema
xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="urn:ui:com.google.gwt.uibinder"
xmlns="urn:ui:com.google.gwt.uibinder"
elementFormDefault="qualified">
<xs:element
name="UiBinder">
<xs:complexType
mixed="true">
<xs:choice
minOccurs="0"
maxOccurs="unbounded">
<!-- Allow any elements (e.g. widgets from any package) -->
<xs:any
processContents="lax" />
</xs:choice>
<!-- Allow any attributes (e.g. namespace definitions) -->
<xs:anyAttribute
processContents="lax" />
</xs:complexType>
</xs:element>
</xs:schema>
@@ -0,0 +1,5 @@
<!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent">
<ui:UiBinder xmlns:ui='urn:ui:com.google.gwt.uibinder'
>
Hello&nbsp;World<caret>
</ui:UiBinder>
+1
View File
@@ -0,0 +1 @@
<!ENTITY nbsp "&#160;"> <!-- no-break space = non-breaking space, U+00A0 ISOnum -->