Merge remote-tracking branch 'origin/master'

This commit is contained in:
Roman Shevchenko
2017-03-31 15:55:34 +02:00
46 changed files with 1886 additions and 1401 deletions
+1 -1
View File
@@ -12,7 +12,7 @@
<module fileurl="file://$PROJECT_DIR$/plugins/ShortcutPromoter/ShortcutPromoter.iml" filepath="$PROJECT_DIR$/plugins/ShortcutPromoter/ShortcutPromoter.iml" group="plugins" />
<module fileurl="file://$PROJECT_DIR$/android/adt-branding/adt-branding.iml" filepath="$PROJECT_DIR$/android/adt-branding/adt-branding.iml" group="android" />
<module fileurl="file://$PROJECT_DIR$/android/adt-ui/adt-ui.iml" filepath="$PROJECT_DIR$/android/adt-ui/adt-ui.iml" group="android" />
<module fileurl="file://$PROJECT_DIR$/plugins/maven/aether-dependency-resolver/aether-dependency-resolver.iml" filepath="$PROJECT_DIR$/plugins/maven/aether-dependency-resolver/aether-dependency-resolver.iml" />
<module fileurl="file://$PROJECT_DIR$/aether-dependency-resolver/aether-dependency-resolver.iml" filepath="$PROJECT_DIR$/aether-dependency-resolver/aether-dependency-resolver.iml" group="community" />
<module fileurl="file://$PROJECT_DIR$/platform/analysis-api/analysis-api.iml" filepath="$PROJECT_DIR$/platform/analysis-api/analysis-api.iml" group="platform" />
<module fileurl="file://$PROJECT_DIR$/platform/analysis-impl/analysis-impl.iml" filepath="$PROJECT_DIR$/platform/analysis-impl/analysis-impl.iml" group="platform" />
<module fileurl="file://$PROJECT_DIR$/android/android/android.iml" filepath="$PROJECT_DIR$/android/android/android.iml" group="android" />
+1 -2
View File
@@ -16,7 +16,6 @@
import static org.jetbrains.jps.idea.IdeaProjectLoader.guessHome
includeTargets << new File("${guessHome(this)}/build/scripts/utils.gant")
includeTargets << new File("${guessHome(this)}/build/scripts/cucumber-tests.gant")
requireProperty("out", "$home/out")
@@ -108,5 +107,5 @@ target('run_tests': 'Run java tests') {
}
target('default' : "Run all tests") {
depends([compile, run_tests, run_cucumber_tests])
depends([compile, run_tests])
}
-60
View File
@@ -1,60 +0,0 @@
/*
* Copyright 2000-2013 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.
*/
target('run_cucumber_tests': "Run cucumber tests") {
if (!isDefined("cucumber_test_dirs")) {
return
}
cucumber_test_dirs.each {
def m = findModule(it[0])
def platformPrefix = it[1]
def testsDir = it[2]
def stepDefsPackage = it[3]
ant.java(failonerror: "true", classname: "com.intellij.cucumber.CucumberMain", fork: "true", dir: testsDir) {
jvmarg(line: "-Xmx512m")
jvmarg(line: "-XX:MaxPermSize=350m")
jvmarg(line: "-XX:+HeapDumpOnOutOfMemoryError")
jvmarg(line: "-ea")
jvmarg(line: "-Didea.platform.prefix=$platformPrefix")
System.getProperties().entrySet().each {
if (it.key.startsWith("pass.")) {
def trimmed = it.key.substring("pass.".length());
jvmarg(value: "-D${trimmed}=${it.value}");
};
}
arg(value: "--format")
arg(value: "org.jetbrains.plugins.cucumber.java.run.CucumberJvmSMFormatter")
arg(value: "--glue")
arg(value: stepDefsPackage)
arg(value: ".")
classpath() {
projectBuilder.moduleRuntimeClasspath(findModule("cucumber-test-runner"), false).each {
pathelement(location: it)
}
projectBuilder.moduleRuntimeClasspath(m, true).each {
pathelement(location: it)
}
}
}
}
}
@@ -48,7 +48,9 @@ import com.intellij.psi.*;
import com.intellij.util.StringBuilderSpinAllocator;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.MultiMap;
import com.intellij.xdebugger.XDebuggerManager;
import com.intellij.xdebugger.breakpoints.XBreakpoint;
import com.intellij.xdebugger.breakpoints.XBreakpointListener;
import com.sun.jdi.*;
import com.sun.jdi.event.LocatableEvent;
import com.sun.jdi.event.MethodEntryEvent;
@@ -69,6 +71,7 @@ import org.jetbrains.org.objectweb.asm.Opcodes;
import javax.swing.*;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Consumer;
import java.util.stream.Stream;
@@ -132,7 +135,7 @@ public class MethodBreakpoint extends BreakpointWithHighlighter<JavaMethodBreakp
debugProcess.getVirtualMachineProxy().clearCaches(); // to force reload classes available so far
}
AtomicReference<ProgressIndicator> indicatorRef = new AtomicReference<>();
AtomicReference<ProgressWindowWithNotification> indicatorRef = new AtomicReference<>();
ApplicationManager.getApplication().invokeAndWait(
() -> {
ProgressWindowWithNotification progress =
@@ -140,13 +143,35 @@ public class MethodBreakpoint extends BreakpointWithHighlighter<JavaMethodBreakp
progress.setDelayInMillis(2000);
indicatorRef.set(progress);
});
ProgressIndicator indicator = indicatorRef.get();
ProgressWindowWithNotification indicator = indicatorRef.get();
AtomicBoolean changed = new AtomicBoolean();
XBreakpointListener<XBreakpoint<?>> listener = new XBreakpointListener<XBreakpoint<?>>() {
void changed(@NotNull XBreakpoint b) {
if (b == breakpoint.getXBreakpoint()) {
changed.set(true);
indicator.cancel();
}
}
@Override
public void breakpointRemoved(@NotNull XBreakpoint b) {
changed(b);
}
@Override
public void breakpointChanged(@NotNull XBreakpoint b) {
changed(b);
}
};
XDebuggerManager.getInstance(debugProcess.getProject()).getBreakpointManager().addBreakpointListener(listener, indicator);
ProgressManager.getInstance().executeProcessUnderProgress(
() -> processPreparedSubTypes(baseType,
subType -> createRequestForPreparedClassEmulated(breakpoint, debugProcess, subType, false),
indicator),
indicator);
if (indicator.isCanceled()) {
if (indicator.isCanceled() && !changed.get()) {
breakpoint.disableEmulation();
}
}
@@ -197,6 +197,7 @@ public class ModuleHighlightUtil {
String message = JavaErrorMessages.message(key, refText);
HighlightInfo info = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(statement).descriptionAndTooltip(message).create();
QuickFixAction.registerQuickFixAction(info, factory().createDeleteFix(statement));
QuickFixAction.registerQuickFixAction(info, MergeModuleStatementsFix.createFix(statement));
results.add(info);
}
}
@@ -0,0 +1,103 @@
/*
* Copyright 2000-2017 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.quickfix;
import com.intellij.codeInspection.LocalQuickFixAndIntentionActionOnPsiElement;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
import com.intellij.psi.codeStyle.CodeStyleManager;
import com.intellij.psi.util.PsiUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Iterator;
import java.util.List;
import java.util.StringJoiner;
/**
* @author Pavel.Dolgov
*/
public abstract class MergeModuleStatementsFix<T extends PsiElement> extends LocalQuickFixAndIntentionActionOnPsiElement {
protected final SmartPsiElementPointer<T> myOtherStatement;
protected MergeModuleStatementsFix(@NotNull T thisStatement, @NotNull T otherStatement) {
super(thisStatement);
final PsiFile file = otherStatement.getContainingFile();
myOtherStatement = SmartPointerManager.getInstance(otherStatement.getProject()).createSmartPsiElementPointer(otherStatement, file);
}
@Override
public boolean isAvailable(@NotNull Project project,
@NotNull PsiFile file,
@NotNull PsiElement startElement,
@NotNull PsiElement endElement) {
final T otherStatement = myOtherStatement.getElement();
return otherStatement != null && otherStatement.isValid() && PsiUtil.isLanguageLevel9OrHigher(file);
}
@Override
public void invoke(@NotNull Project project,
@NotNull PsiFile file,
@Nullable Editor editor,
@NotNull PsiElement thisStatement,
@NotNull PsiElement endElement) {
final T otherStatement = myOtherStatement.getElement();
if (otherStatement != null) {
final PsiElement parent = otherStatement.getParent();
if (parent instanceof PsiJavaModule) {
final String moduleName = ((PsiJavaModule)parent).getName();
final String moduleText = PsiKeyword.MODULE + " " + moduleName + " {" + getReplacementText(otherStatement) + "}";
final PsiElementFactory factory = JavaPsiFacade.getInstance(project).getElementFactory();
final PsiJavaModule tempModule = factory.createModuleFromText(moduleText);
final Iterator<T> statementIterator = getStatements(tempModule).iterator();
LOG.assertTrue(statementIterator.hasNext());
final T replacement = statementIterator.next();
final CodeStyleManager codeStyleManager = CodeStyleManager.getInstance(project);
codeStyleManager.reformat(otherStatement.replace(replacement));
thisStatement.delete();
}
}
}
@NotNull
protected abstract String getReplacementText(@NotNull T otherStatement);
@NotNull
protected abstract Iterable<T> getStatements(@NotNull PsiJavaModule javaModule);
@NotNull
protected static String joinNames(@NotNull List<String> oldNames, @NotNull List<String> newNames) {
final StringJoiner joiner = new StringJoiner(",");
oldNames.forEach(joiner::add);
newNames.stream().filter(name -> !oldNames.contains(name)).forEach(joiner::add);
return joiner.toString();
}
@Nullable
public static MergeModuleStatementsFix createFix(@Nullable PsiElement statement) {
if (statement instanceof PsiPackageAccessibilityStatement) {
return MergePackageAccessibilityStatementsFix.createFix((PsiPackageAccessibilityStatement)statement);
}
else if (statement instanceof PsiProvidesStatement) {
return MergeProvidesStatementsFix.createFix((PsiProvidesStatement)statement);
}
return null;
}
}
@@ -0,0 +1,128 @@
/*
* Copyright 2000-2017 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.quickfix;
import com.intellij.codeInsight.daemon.QuickFixBundle;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiJavaModule;
import com.intellij.psi.PsiKeyword;
import com.intellij.psi.PsiPackageAccessibilityStatement;
import com.intellij.psi.PsiPackageAccessibilityStatement.Role;
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Collections;
import java.util.List;
/**
* @author Pavel.Dolgov
*/
public class MergePackageAccessibilityStatementsFix
extends MergeModuleStatementsFix<PsiPackageAccessibilityStatement> {
private static final Logger LOG = Logger.getInstance(MergePackageAccessibilityStatementsFix.class);
private final String myPackageName;
private final List<String> myModuleNames;
private final Role myRole;
protected MergePackageAccessibilityStatementsFix(@NotNull PsiPackageAccessibilityStatement thisStatement,
@NotNull String packageName,
@NotNull List<String> moduleNames,
@NotNull PsiPackageAccessibilityStatement otherStatement) {
super(thisStatement, otherStatement);
myPackageName = packageName;
myModuleNames = moduleNames;
myRole = thisStatement.getRole();
}
@Nls
@NotNull
@Override
public String getText() {
return QuickFixBundle.message("java.9.merge.module.statements.fix.name", getKeyword(), myPackageName);
}
@Nls
@NotNull
@Override
public String getFamilyName() {
return QuickFixBundle.message("java.9.merge.module.statements.fix.family.name", getKeyword());
}
@NotNull
@Override
protected String getReplacementText(@NotNull PsiPackageAccessibilityStatement otherStatement) {
return getKeyword() + " " + myPackageName + " " + PsiKeyword.TO + " " +
joinNames(otherStatement.getModuleNames(), myModuleNames) + ";";
}
@NotNull
@Override
protected Iterable<PsiPackageAccessibilityStatement> getStatements(@NotNull PsiJavaModule javaModule) {
return getStatements(javaModule, myRole);
}
@Nullable
public static MergeModuleStatementsFix createFix(@Nullable PsiPackageAccessibilityStatement statement) {
if (statement != null) {
final PsiElement parent = statement.getParent();
if (parent instanceof PsiJavaModule) {
final PsiJavaModule javaModule = (PsiJavaModule)parent;
final String packageName = statement.getPackageName();
if (packageName != null) {
final List<String> moduleNames = statement.getModuleNames();
if (!moduleNames.isEmpty()) {
for (PsiPackageAccessibilityStatement candidate : getStatements(javaModule, statement.getRole())) {
if (candidate != statement &&
packageName.equals(candidate.getPackageName()) &&
candidate.getModuleNames().iterator().hasNext()) {
return new MergePackageAccessibilityStatementsFix(statement, packageName, moduleNames, candidate);
}
}
}
}
}
}
return null;
}
@NotNull
private static Iterable<PsiPackageAccessibilityStatement> getStatements(@NotNull PsiJavaModule javaModule, @NotNull Role role) {
switch (role) {
case OPENS:
return javaModule.getOpens();
case EXPORTS:
return javaModule.getExports();
}
LOG.error("Unexpected role " + role);
return Collections.emptyList();
}
@NotNull
private String getKeyword() {
switch (myRole) {
case OPENS:
return PsiKeyword.OPENS;
case EXPORTS:
return PsiKeyword.EXPORTS;
}
LOG.error("Unexpected role " + myRole);
return "";
}
}
@@ -0,0 +1,112 @@
/*
* Copyright 2000-2017 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.quickfix;
import com.intellij.codeInsight.daemon.QuickFixBundle;
import com.intellij.psi.*;
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
/**
* @author Pavel.Dolgov
*/
public class MergeProvidesStatementsFix extends MergeModuleStatementsFix<PsiProvidesStatement> {
private final String myInterfaceName;
private final List<String> myImplementationNames;
MergeProvidesStatementsFix(@NotNull PsiProvidesStatement thisStatement,
@NotNull String interfaceName,
@NotNull List<String> implementationNames,
@NotNull PsiProvidesStatement otherStatement) {
super(thisStatement, otherStatement);
myInterfaceName = interfaceName;
myImplementationNames = implementationNames;
}
@NotNull
@Override
public String getText() {
return QuickFixBundle.message("java.9.merge.module.statements.fix.name", PsiKeyword.PROVIDES, myInterfaceName);
}
@Nls
@NotNull
@Override
public String getFamilyName() {
return QuickFixBundle.message("java.9.merge.module.statements.fix.family.name", PsiKeyword.PROVIDES);
}
@NotNull
@Override
protected String getReplacementText(@NotNull PsiProvidesStatement otherStatement) {
return PsiKeyword.PROVIDES + " " + myInterfaceName + " " + PsiKeyword.WITH + " " +
joinNames(getImplementationNames(otherStatement), myImplementationNames) + ";";
}
@NotNull
@Override
protected Iterable<PsiProvidesStatement> getStatements(@NotNull PsiJavaModule javaModule) {
return javaModule.getProvides();
}
@NotNull
private static List<String> getImplementationNames(@Nullable PsiProvidesStatement statement) {
if (statement != null) {
final PsiReferenceList implementationList = statement.getImplementationList();
if (implementationList != null) {
return Arrays.stream(implementationList.getReferenceElements())
.map(PsiJavaCodeReferenceElement::getQualifiedName)
.filter(Objects::nonNull)
.collect(Collectors.toList());
}
}
return Collections.emptyList();
}
@Nullable
public static MergeModuleStatementsFix createFix(@Nullable PsiProvidesStatement statement) {
if (statement != null) {
final PsiElement parent = statement.getParent();
if (parent instanceof PsiJavaModule) {
final PsiJavaModule javaModule = (PsiJavaModule)parent;
final PsiJavaCodeReferenceElement interfaceReference = statement.getInterfaceReference();
if (interfaceReference != null) {
final String interfaceName = interfaceReference.getQualifiedName();
if (interfaceName != null) {
final List<String> implementationNames = getImplementationNames(statement);
if (!implementationNames.isEmpty()) {
for (PsiProvidesStatement candidate : javaModule.getProvides()) {
final PsiJavaCodeReferenceElement candidateInterfaceReference = candidate.getInterfaceReference();
if (candidateInterfaceReference != null && interfaceName.equals(candidateInterfaceReference.getQualifiedName())) {
return new MergeProvidesStatementsFix(statement, interfaceName, implementationNames, candidate);
}
}
}
}
}
}
}
return null;
}
}
@@ -0,0 +1,4 @@
module M {
exports my.api to M4;
exports <caret>my.api to M6;
}
@@ -0,0 +1,3 @@
module M {
exports my.api to M4, M6;
}
@@ -0,0 +1,5 @@
module M {
exports my.api;
exports <caret>my.api to M2, M4;
exports my.api to M6;
}
@@ -0,0 +1,4 @@
module M {
exports my.api;
exports my.api to M6, M2, M4;
}
@@ -0,0 +1,4 @@
module M {
opens my.api to M4;
opens <caret>my.api to M6;
}
@@ -0,0 +1,3 @@
module M {
opens my.api to M4, M6;
}
@@ -0,0 +1,5 @@
module M {
opens my.api;
opens <caret>my.api to M2, M4;
opens my.api to M6;
}
@@ -0,0 +1,4 @@
module M {
opens my.api;
opens my.api to M6, M2, M4;
}
@@ -0,0 +1,4 @@
module M {
provides my.api.MyService with my.impl.MyServiceImpl;
provides my.api.MyService with my.impl.<caret>MyServiceImpl1;
}
@@ -0,0 +1,3 @@
module M {
provides my.api.MyService with my.impl.MyServiceImpl,my.impl.MyServiceImpl1;
}
@@ -0,0 +1,8 @@
import my.impl.MyServiceImpl;
import my.impl.MyServiceImpl1;
import my.impl.MyServiceImpl2;
module M {
provides my.api.MyService with MyServiceImpl, MyServiceImpl2;
provides my.api.MyService with <caret>MyServiceImpl1;
}
@@ -0,0 +1,7 @@
import my.impl.MyServiceImpl;
import my.impl.MyServiceImpl1;
import my.impl.MyServiceImpl2;
module M {
provides my.api.MyService with MyServiceImpl,MyServiceImpl2,MyServiceImpl1;
}
@@ -0,0 +1,8 @@
import my.impl.MyServiceImpl;
import my.impl.MyServiceImpl1;
import my.impl.MyServiceImpl2;
module M {
provides my.api.MyService with MyServiceImpl;
provides my.api.MyService with <caret>MyServiceImpl1, MyServiceImpl2;
}
@@ -0,0 +1,7 @@
import my.impl.MyServiceImpl;
import my.impl.MyServiceImpl1;
import my.impl.MyServiceImpl2;
module M {
provides my.api.MyService with MyServiceImpl,MyServiceImpl1,MyServiceImpl2;
}
@@ -0,0 +1,72 @@
/*
* Copyright 2000-2017 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.quickFix
import com.intellij.JavaTestUtil.getRelativeJavaTestDataPath
import com.intellij.codeInsight.daemon.QuickFixBundle
import com.intellij.codeInsight.intention.IntentionAction
import com.intellij.testFramework.fixtures.LightJava9ModulesCodeInsightFixtureTestCase
import com.intellij.testFramework.fixtures.MultiModuleJava9ProjectDescriptor.ModuleDescriptor.*
/**
* @author Pavel.Dolgov
*/
class MergeModuleStatementsFixTest : LightJava9ModulesCodeInsightFixtureTestCase() {
override fun getBasePath() = getRelativeJavaTestDataPath() + "/codeInsight/daemonCodeAnalyzer/quickFix/mergeModuleStatementsFix"
fun testExports1() = doTest("exports", "my.api")
fun testExports2() = doTest("exports", "my.api")
fun testProvides1() = doTest("provides", "my.api.MyService")
fun testProvides2() = doTest("provides", "my.api.MyService")
fun testProvides3() = doTest("provides", "my.api.MyService")
fun testOpens1() = doTest("opens", "my.api")
fun testOpens2() = doTest("opens", "my.api")
override fun setUp() {
super.setUp()
addFile("module-info.java", "module M2 { }", M2)
addFile("module-info.java", "module M4 { }", M4)
addFile("module-info.java", "module M6 { }", M6)
addFile("my/api/MyService.java", "package my.api; public class MyService {}")
addFile("my/impl/MyServiceImpl.java", "package my.impl; public class MyServiceImpl extends my.api.MyService {}")
addFile("my/impl/MyServiceImpl1.java", "package my.impl; public class MyServiceImpl1 extends my.api.MyService {}")
addFile("my/impl/MyServiceImpl2.java", "package my.impl; public class MyServiceImpl2 extends my.api.MyService {}")
}
private fun doTest(type: String, name: String) {
val testName = getTestName(false)
val virtualFile = myFixture.copyFileToProject("${testName}.java", "module-info.java")
myFixture.configureFromExistingVirtualFile(virtualFile)
val action = findActionWithText(QuickFixBundle.message("java.9.merge.module.statements.fix.name", type, name))
myFixture.launchAction(action)
myFixture.checkResultByFile("${testName}_after.java")
}
private fun findActionWithText(actionText: String): IntentionAction {
myFixture.doHighlighting()
val actions = LightQuickFixTestCase.getAvailableActions(editor, file)
val action = LightQuickFixTestCase.findActionWithText(actions, actionText)
assertNotNull("No action [$actionText] in ${actions.map { it.text }}", action)
return action
}
}
@@ -21,6 +21,7 @@ import com.intellij.ide.passwordSafe.PasswordSafe
import com.intellij.openapi.application.ModalityState
import com.intellij.openapi.application.invokeAndWaitIfNeed
import com.intellij.openapi.project.Project
import com.intellij.ui.AppIcon
import com.intellij.ui.components.CheckBox
import com.intellij.ui.components.dialog
import com.intellij.ui.layout.*
@@ -83,6 +84,7 @@ fun askCredentials(project: Project?,
}
}
AppIcon.getInstance().requestAttention(project, true)
if (dialog(dialogTitle, project = project, panel = panel, focusedComponent = passwordField, errorText = error).showAndGet()) {
val isMemoryOnly = store.isMemoryOnly || !rememberCheckBox!!.isSelected
val credentials = Credentials(attributes.userName, passwordField.password.nullize())
@@ -28,7 +28,6 @@ import javax.swing.text.Position;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.geom.Path2D;
import java.awt.geom.RoundRectangle2D;
import static javax.swing.SwingConstants.EAST;
import static javax.swing.SwingConstants.WEST;
@@ -116,28 +115,52 @@ public class DarculaUIUtil {
}
public static void paintErrorBorder(Graphics2D g, int width, int height, int arc, boolean hasFocus) {
int lw = JBUI.scale(UIUtil.isUnderDefaultMacTheme() ? 4 : 3);
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, MacUIUtil.USE_QUARTZ ? RenderingHints.VALUE_STROKE_PURE : RenderingHints.VALUE_STROKE_NORMALIZE);
g.setPaint(hasFocus ? ACTIVE_ERROR_COLOR : INACTIVE_ERROR_COLOR);
Path2D path = new Path2D.Double(Path2D.WIND_EVEN_ODD);
path.append(new RoundRectangle2D.Double(0, 0, width, height, arc + lw * 2, arc + lw * 2), false);
path.append(new RoundRectangle2D.Double(lw, lw, width - lw * 2, height - lw * 2, arc, arc), false);
g.fill(path);
doPaint(g, width, height, arc);
}
public static void paintFocusBorder(Graphics2D g, int width, int height, int lw, int arc) {
public static void paintFocusBorder(Graphics2D g, int width, int height, int arc) {
g.setPaint(IntelliJLaf.isGraphite() ? MAC_GRAPHITE_COLOR : MAC_REGULAR_COLOR);
doPaint(g, width, height, arc);
}
@SuppressWarnings("SuspiciousNameCombination")
private static void doPaint(Graphics2D g, int width, int height, int arc) {
double bw = UIUtil.isRetina(g) ? 0.5 : 1.0;
double lw = JBUI.scale(UIUtil.isUnderDefaultMacTheme() ? 3 : 2);
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, MacUIUtil.USE_QUARTZ ? RenderingHints.VALUE_STROKE_PURE : RenderingHints.VALUE_STROKE_NORMALIZE);
g.setPaint(IntelliJLaf.isGraphite() ? MAC_GRAPHITE_COLOR : MAC_REGULAR_COLOR);
double outerArc = arc > 0 ? arc + lw - JBUI.scale(2) : lw;
double rightOuterArc = JBUI.scale(6);
Path2D outerRect = new Path2D.Double(Path2D.WIND_EVEN_ODD);
outerRect.moveTo(width - rightOuterArc, 0);
outerRect.quadTo(width, 0, width, rightOuterArc);
outerRect.lineTo(width, height - rightOuterArc);
outerRect.quadTo(width, height, width - rightOuterArc, height);
outerRect.lineTo(outerArc, height);
outerRect.quadTo(0, height, 0, height - outerArc);
outerRect.lineTo(0, outerArc);
outerRect.quadTo(0, 0, outerArc, 0);
outerRect.closePath();
lw += bw;
double rightInnerArc = JBUI.scale(7);
Path2D innerRect = new Path2D.Double(Path2D.WIND_EVEN_ODD);
innerRect.moveTo(width - rightInnerArc, lw);
innerRect.quadTo(width - lw, lw , width - lw, rightInnerArc);
innerRect.lineTo(width - lw, height - rightInnerArc);
innerRect.quadTo(width - lw, height - lw, width - rightInnerArc, height - lw);
innerRect.lineTo(outerArc, height - lw);
innerRect.quadTo(lw, height - lw, lw, height - outerArc);
innerRect.lineTo(lw, outerArc);
innerRect.quadTo(lw, lw, outerArc, lw);
innerRect.closePath();
Path2D path = new Path2D.Double(Path2D.WIND_EVEN_ODD);
path.append(new RoundRectangle2D.Double(0, 0, width, height, arc + lw * 2, arc + lw * 2), false);
path.append(new RoundRectangle2D.Double(lw, lw, width - lw * 2, height - lw * 2, arc, arc), false);
path.append(outerRect, false);
path.append(innerRect, false);
g.fill(path);
}
@@ -137,10 +137,8 @@ public class DarculaSpinnerUI extends BasicSpinnerUI {
}
protected void layoutEditor(@NotNull JComponent editor) {
if (editor != null) {
final Rectangle bounds = editor.getBounds();
Rectangle bounds = editor.getBounds();
editor.setBounds(bounds.x, bounds.y, bounds.width - 6, bounds.height);
}
}
protected void paintArrowButton(Graphics g,
@@ -16,9 +16,10 @@
package com.intellij.ide.ui.laf.intellij;
import com.intellij.ui.Gray;
import com.intellij.ui.paint.RectanglePainter;
import com.intellij.util.ui.JBInsets;
import com.intellij.util.ui.JBUI;
import com.intellij.util.ui.MacUIUtil;
import com.intellij.util.ui.UIUtil;
import javax.swing.*;
import java.awt.*;
@@ -27,6 +28,8 @@ import java.awt.geom.Path2D;
import java.awt.geom.Rectangle2D;
import java.awt.geom.RoundRectangle2D;
import static com.intellij.ide.ui.laf.intellij.MacIntelliJComboBoxUI.VALUE_OFFSET;
/**
* @author Konstantin Bulenkov
*/
@@ -34,11 +37,13 @@ public class MacComboBoxBorder extends MacIntelliJTextBorder {
@Override
public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {
Graphics2D g2 = (Graphics2D)g.create();
if (!(c instanceof JComponent)) return;
Graphics2D g2 = (Graphics2D)g.create();
try {
g2.translate(x, y);
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, MacUIUtil.USE_QUARTZ ? RenderingHints.VALUE_STROKE_PURE : RenderingHints.VALUE_STROKE_NORMALIZE);
Shape clip = g2.getClip();
Area area = new Area(new Rectangle2D.Double(0, 0, width, height));
@@ -46,26 +51,43 @@ public class MacComboBoxBorder extends MacIntelliJTextBorder {
area.intersect(new Area(clip));
g2.setClip(area);
int arc = isRound(c) ? JBUI.scale(8) : 0;
int arc = isRound(c) ? JBUI.scale(6) : 0;
Insets i = ((JComponent)c).getInsets();
if (c instanceof JComboBox) {
JComboBox comboBox = (JComboBox)c;
g2.setColor(UIManager.getColor(comboBox.isEnabled() ? "ComboBox.background" : "ComboBox.disabledBackground"));
Path2D path = new Path2D.Double(Path2D.WIND_EVEN_ODD);
path.moveTo(JBUI.scale(8), JBUI.scale(3));
path.lineTo(JBUI.scale(8), c.getHeight() - JBUI.scale(3));
path.lineTo(JBUI.scale(3) + arc, c.getHeight() - JBUI.scale(3));
path.quadTo(JBUI.scale(3), c.getHeight() - JBUI.scale(3), JBUI.scale(3), c.getHeight() - JBUI.scale(3) - arc);
path.lineTo(JBUI.scale(3), JBUI.scale(3) + arc);
path.quadTo(JBUI.scale(3), JBUI.scale(3), JBUI.scale(3) + arc, JBUI.scale(3));
path.lineTo(JBUI.scale(8), JBUI.scale(3));
g2.fill(path);
if (comboBox.isEditable()) {
Shape shape = new Rectangle2D.Double(i.left, i.top,
width - (i.left + i.right),
height - (i.top + i.bottom));
g2.fill(shape);
} else {
Path2D path = new Path2D.Double(Path2D.WIND_EVEN_ODD);
path.moveTo(i.left + VALUE_OFFSET, i.top);
path.lineTo(i.left + VALUE_OFFSET, c.getHeight() - i.bottom);
path.lineTo(i.left + arc, c.getHeight() - i.bottom);
path.quadTo(i.left, c.getHeight() - i.bottom, i.left, c.getHeight() - arc - i.bottom);
path.lineTo(i.left, arc + i.top);
path.quadTo(i.left, i.top, arc + i.left, i.top);
path.closePath();
g2.fill(path);
}
}
RectanglePainter.paint(g2, JBUI.scale(3), JBUI.scale(3),
c.getWidth() - JBUI.scale(6),
c.getHeight() - JBUI.scale(6),
arc, null, Gray.xBC);
Path2D border = new Path2D.Double(Path2D.WIND_EVEN_ODD);
double lw = UIUtil.isRetina(g2) ? 0.5 : 1.0;
border.append(new RoundRectangle2D.Double(JBUI.scale(3), JBUI.scale(3),
c.getWidth() - JBUI.scale(6),
c.getHeight() - JBUI.scale(6),
arc, arc), false);
double innerArc = arc > 0 ? arc - lw : 0.0;
border.append(new RoundRectangle2D.Double(JBUI.scale(3) + lw, JBUI.scale(3) + lw,
c.getWidth() - JBUI.scale(6) - lw * 2,
c.getHeight() - JBUI.scale(6) - lw * 2,
innerArc, innerArc), false);
g2.setColor(Gray.xBC);
g2.fill(border);
g2.setClip(clip); // Reset clip
paint(c, g2, width, height, arc);
@@ -109,14 +131,15 @@ public class MacComboBoxBorder extends MacIntelliJTextBorder {
@Override void clipForBorder(Component c, Graphics2D g2, int width, int height) {
Area area = new Area(new Rectangle2D.Double(0, 0, width, height));
double lw = UIUtil.isRetina(g2) ? 0.5 : 1.0;
Shape innerShape = isRound(c) ?
new RoundRectangle2D.Double(JBUI.scale(4), JBUI.scale(4),
width - JBUI.scale(8),
height - JBUI.scale(8),
JBUI.scale(10), JBUI.scale(10)) :
new Rectangle2D.Double(JBUI.scale(4), JBUI.scale(4),
width - JBUI.scale(8),
height - JBUI.scale(8));
new RoundRectangle2D.Double(JBUI.scale(3) + lw, JBUI.scale(3) + lw,
width - JBUI.scale(6) - lw * 2,
height - JBUI.scale(6) - lw * 2,
JBUI.scale(3) + lw, JBUI.scale(3) + lw) :
new Rectangle2D.Double(JBUI.scale(3) + lw, JBUI.scale(3) + lw,
width - JBUI.scale(6) - lw * 2,
height - JBUI.scale(6) - lw * 2);
area.subtract(new Area(innerShape));
area.add(getButtonBounds(c));
@@ -40,6 +40,7 @@ import java.beans.PropertyChangeListener;
public class MacIntelliJComboBoxUI extends BasicComboBoxUI {
private static final Border ourDefaultEditorBorder = JBUI.Borders.empty(1, 0);
static final int VALUE_OFFSET = JBUI.scale(5);
private Icon DEFAULT_ICON;
private PropertyChangeListener myEditorChangeListener;
@@ -243,8 +244,8 @@ public class MacIntelliJComboBoxUI extends BasicComboBoxUI {
@Override
protected Rectangle rectangleForCurrentValue() {
Rectangle rect = super.rectangleForCurrentValue();
rect.x += JBUI.scale(5);
rect.width -= JBUI.scale(5);
rect.x += VALUE_OFFSET;
rect.width -= VALUE_OFFSET;
return rect;
}
@@ -25,6 +25,8 @@ import javax.swing.*;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.basic.BasicArrowButton;
import java.awt.*;
import java.awt.geom.Path2D;
/**
* @author Konstantin Bulenkov
@@ -42,21 +44,31 @@ public class MacIntelliJSpinnerUI extends DarculaSpinnerUI {
Container parent = c.getParent();
if (c.isOpaque() && parent != null) {
g.setColor(parent.getBackground());
g.fillRect(0,0,c.getWidth(),c.getHeight());
g.fillRect(0, 0, c.getWidth(), c.getHeight());
}
Insets i = c.getInsets();
int x = c.getWidth() - DEFAULT_ICON.getIconWidth() - i.right;
Icon icon = MacIntelliJIconCache.getIcon("spinnerRight", false, false, c.isEnabled());
icon.paintIcon(c, g, x, i.top);
if (c instanceof JSpinner) {
JComponent editor = ((JSpinner)c).getEditor();
Rectangle editorBounds = editor.getBounds();
g.setColor(UIManager.getColor("FormattedTextField.background"));
g.fillRect(i.left + JBUI.scale(1), i.top + JBUI.scale(1), x - JBUI.scale(1) - i.left, editorBounds.height + JBUI.scale(2));
Graphics2D g2 = (Graphics2D)g;
g2.setColor(UIManager.getColor("FormattedTextField.background"));
double arc = JBUI.scale(6);
Path2D rect = new Path2D.Double(Path2D.WIND_EVEN_ODD);
rect.moveTo(x, i.top);
rect.lineTo(x, c.getHeight() - i.bottom);
rect.lineTo(i.left + arc, c.getHeight() - i.bottom);
rect.quadTo(i.left, c.getHeight() - i.bottom, i.left, c.getHeight() - i.bottom - arc);
rect.lineTo(i.left, i.top + arc);
rect.quadTo(i.left, i.top, i.left + arc, i.top);
rect.closePath();
g2.fill(rect);
}
Icon icon = MacIntelliJIconCache.getIcon("spinnerRight", false, false, c.isEnabled());
icon.paintIcon(c, g, x, i.top);
}
@Override protected void paintArrowButton(Graphics g, BasicArrowButton button, int direction) {}
@@ -20,12 +20,13 @@ import com.intellij.ide.ui.laf.darcula.ui.DarculaTextBorder;
import com.intellij.ide.ui.laf.darcula.ui.TextFieldWithPopupHandlerUI;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.ui.Gray;
import com.intellij.ui.paint.RectanglePainter;
import com.intellij.util.ui.JBUI;
import com.intellij.util.ui.UIUtil;
import javax.swing.*;
import java.awt.*;
import java.awt.geom.Area;
import java.awt.geom.Path2D;
import java.awt.geom.Rectangle2D;
/**
@@ -51,9 +52,17 @@ public class MacIntelliJTextBorder extends DarculaTextBorder {
Graphics2D g2 = (Graphics2D)g.create();
try {
g2.translate(x, y);
RectanglePainter.paint(g2, JBUI.scale(3), JBUI.scale(3),
c.getWidth() - JBUI.scale(6),
c.getHeight() - JBUI.scale(6), 0, null, Gray.xBC);
Path2D border = new Path2D.Double(Path2D.WIND_EVEN_ODD);
double lw = UIUtil.isRetina(g2) ? 0.5 : 1.0;
border.append(new Rectangle2D.Double(JBUI.scale(3), JBUI.scale(3),
c.getWidth() - JBUI.scale(6),
c.getHeight() - JBUI.scale(6)), false);
border.append(new Rectangle2D.Double(JBUI.scale(3) + lw, JBUI.scale(3) + lw,
c.getWidth() - JBUI.scale(6) - lw * 2,
c.getHeight() - JBUI.scale(6) - lw * 2), false);
g2.setColor(Gray.xBC);
g2.fill(border);
if (c.getParent() instanceof JComboBox) return;
@@ -70,7 +79,7 @@ public class MacIntelliJTextBorder extends DarculaTextBorder {
if (Registry.is("ide.inplace.errors.outline") && Boolean.parseBoolean(String.valueOf(eop))) {
DarculaUIUtil.paintErrorBorder(g2, width, height, arc, isFocused(c));
} else if (isFocused(c)) {
DarculaUIUtil.paintFocusBorder(g2, width, height, JBUI.scale(4), arc);
DarculaUIUtil.paintFocusBorder(g2, width, height, arc);
}
}
@@ -80,9 +89,10 @@ public class MacIntelliJTextBorder extends DarculaTextBorder {
void clipForBorder(Component c, Graphics2D g2, int width, int height) {
Area area = new Area(new Rectangle2D.Double(0, 0, width, height));
area.subtract(new Area(new Rectangle2D.Double(JBUI.scale(4), JBUI.scale(4),
width - JBUI.scale(8),
height - JBUI.scale(8))));
double lw = UIUtil.isRetina(g2) ? 0.5 : 1.0;
area.subtract(new Area(new Rectangle2D.Double(JBUI.scale(3) + lw, JBUI.scale(3) + lw,
width - JBUI.scale(6) - lw * 2,
height - JBUI.scale(6) - lw * 2)));
area.intersect(new Area(g2.getClip()));
g2.setClip(area);
}
@@ -19,8 +19,9 @@ import com.intellij.ide.ui.laf.darcula.DarculaUIUtil;
import com.intellij.ide.ui.laf.darcula.ui.TextFieldWithPopupHandlerUI;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.ui.Gray;
import com.intellij.ui.paint.RectanglePainter;
import com.intellij.util.ui.JBUI;
import com.intellij.util.ui.MacUIUtil;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
@@ -28,7 +29,9 @@ import javax.swing.plaf.ComponentUI;
import javax.swing.text.JTextComponent;
import java.awt.*;
import java.awt.geom.Area;
import java.awt.geom.Path2D;
import java.awt.geom.Rectangle2D;
import java.awt.geom.RoundRectangle2D;
/**
* @author Konstantin Bulenkov
@@ -160,16 +163,35 @@ public class MacIntelliJTextFieldUI extends TextFieldWithPopupHandlerUI {
protected void paintSearchField(Graphics2D g, JTextComponent c, Rectangle r) {
Graphics2D g2 = (Graphics2D)g.create();
try {
RectanglePainter.paint(g2, r.x + JBUI.scale(3), r.y + JBUI.scale(3),
r.width - JBUI.scale(6), r.height - JBUI.scale(6),
JBUI.scale(8), c.getBackground(), Gray.xBC);
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, MacUIUtil.USE_QUARTZ ? RenderingHints.VALUE_STROKE_PURE : RenderingHints.VALUE_STROKE_NORMALIZE);
g2.translate(r.x, r.y);
int arc = JBUI.scale(6);
double lw = UIUtil.isRetina(g2) ? 0.5 : 1.0;
Shape outerShape = new RoundRectangle2D.Double(JBUI.scale(3), JBUI.scale(3),
r.width - JBUI.scale(6),
r.height - JBUI.scale(6),
arc, arc);
g2.setColor(c.getBackground());
g2.fill(outerShape);
Path2D path = new Path2D.Double(Path2D.WIND_EVEN_ODD);
path.append(outerShape, false);
path.append(new RoundRectangle2D.Double(JBUI.scale(3) + lw, JBUI.scale(3) + lw,
r.width - JBUI.scale(6) - lw*2,
r.height - JBUI.scale(6) - lw*2,
arc-lw, arc-lw), false);
g2.setColor(Gray.xBC);
g2.fill(path);
if (c.hasFocus() && c.getClientProperty("JTextField.Search.noBorderRing") != Boolean.TRUE) {
g2.translate(r.x, r.y);
DarculaUIUtil.paintFocusBorder(g2, r.width, r.height, JBUI.scale(4), JBUI.scale(6));
g2.translate(-r.x, -r.y);
DarculaUIUtil.paintFocusBorder(g2, r.width, r.height, arc);
}
g2.translate(-r.x, -r.y);
boolean withHistoryPopup = isSearchFieldWithHistoryPopup(c);
Icon label = getSearchIcon(c);
boolean isEmpty = !hasText();
@@ -234,12 +256,31 @@ public class MacIntelliJTextFieldUI extends TextFieldWithPopupHandlerUI {
public static void paintAquaSearchFocusRing(Graphics2D g, Rectangle r, Component c) {
Graphics2D g2 = (Graphics2D)g.create();
try {
RectanglePainter.paint(g, r.x + JBUI.scale(3), r.y + JBUI.scale(3),
r.width - JBUI.scale(6), r.height - JBUI.scale(6),
JBUI.scale(8), c.getBackground(), Gray.xBC);
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, MacUIUtil.USE_QUARTZ ? RenderingHints.VALUE_STROKE_PURE : RenderingHints.VALUE_STROKE_NORMALIZE);
g2.translate(r.x, r.y);
int arc = JBUI.scale(6);
double lw = UIUtil.isRetina(g2) ? 0.5 : 1.0;
Shape outerShape = new RoundRectangle2D.Double(JBUI.scale(3), JBUI.scale(3),
r.width - JBUI.scale(6),
r.height - JBUI.scale(6),
arc, arc);
g2.setColor(c.getBackground());
g2.fill(outerShape);
Path2D path = new Path2D.Double(Path2D.WIND_EVEN_ODD);
path.append(outerShape, false);
path.append(new RoundRectangle2D.Double(JBUI.scale(3) + lw, JBUI.scale(3) + lw,
r.width - JBUI.scale(6) - lw*2,
r.height - JBUI.scale(6) - lw*2,
arc-lw, arc-lw), false);
g2.setColor(Gray.xBC);
g2.fill(path);
if (c.hasFocus()) {
g.translate(r.x, r.y);
DarculaUIUtil.paintFocusBorder(g, r.width, r.height, JBUI.scale(4), JBUI.scale(6));
DarculaUIUtil.paintFocusBorder(g2, r.width, r.height, arc);
}
}
finally {
@@ -156,6 +156,22 @@ public abstract class FinderRecursivePanel<T> extends OnePixelSplitter implement
return null;
}
/**
* Returns tooltip text for the given list item or null if no tooltip is available.
*
* <p>This method is invoked by panel's list cell render in order to set a tooltip text for the list cell render component.
* It is invoked before {@link #doCustomizeCellRenderer(SimpleColoredComponent, JList, Object, int, boolean, boolean)},
* thus the tooltip may still be reset in {@code doCustomizeCellRenderer}.
*
* @param t the list item
* @return the text to display in a tooltip for the given list item
* @since 2017.2
*/
@Nullable
protected String getItemTooltipText(T t) {
return null;
}
protected abstract boolean hasChildren(T t);
/**
@@ -190,7 +206,7 @@ public abstract class FinderRecursivePanel<T> extends OnePixelSplitter implement
ScrollPaneFactory.createScrollPane(myList,
ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED,
ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
return ListWithFilter.wrap(myList, pane, (Function<T, String>)o -> getItemText(o));
return ListWithFilter.wrap(myList, pane, o -> getItemText(o));
}
protected JBList<T> createList() {
@@ -298,13 +314,8 @@ public abstract class FinderRecursivePanel<T> extends OnePixelSplitter implement
}
private void installSpeedSearch(JBList list) {
final ListSpeedSearch search = new ListSpeedSearch(list, new Function<Object, String>() {
@Override
public String fun(Object o) {
//noinspection unchecked
return getItemText((T)o);
}
});
//noinspection unchecked
final ListSpeedSearch search = new ListSpeedSearch(list, (Function<Object, String>)o -> getItemText((T)o));
search.setComparator(new SpeedSearchComparator(false));
}
@@ -346,6 +357,7 @@ public abstract class FinderRecursivePanel<T> extends OnePixelSplitter implement
try {
setIcon(getItemIcon(t));
append(getItemText(t));
setToolTipText(getItemTooltipText(t));
}
catch (IndexNotReadyException e) {
append("loading...");
@@ -379,6 +391,7 @@ public abstract class FinderRecursivePanel<T> extends OnePixelSplitter implement
: AllIcons.Icons.Ide.NextStepGrayed);
result.add(this, BorderLayout.CENTER);
result.add(childrenLabel, BorderLayout.EAST);
result.setToolTipText(getToolTipText());
return result;
}
return this;
@@ -188,9 +188,9 @@ public class AbstractPopup implements JBPopup {
}
}
AbstractPopup() { }
protected AbstractPopup() { }
AbstractPopup init(Project project,
protected AbstractPopup init(Project project,
@NotNull JComponent component,
@Nullable JComponent preferredFocusedComponent,
boolean requestFocus,
@@ -68,6 +68,7 @@ import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseEvent;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
/**
* @author nik
@@ -162,8 +163,9 @@ public class XValueHint extends AbstractValueHint {
@Override
protected void evaluateAndShowHint() {
AtomicBoolean showEvaluating = new AtomicBoolean(true);
EdtExecutorService.getScheduledExecutorInstance().schedule(() -> {
if (myCurrentHint == null) {
if (myCurrentHint == null && showEvaluating.get()) {
SimpleColoredComponent component = HintUtil.createInformationComponent();
component.append(XDebuggerUIConstants.EVALUATING_EXPRESSION_MESSAGE);
showHint(component);
@@ -181,6 +183,7 @@ public class XValueHint extends AbstractValueHint {
public void applyPresentation(@Nullable Icon icon,
@NotNull XValuePresentation valuePresenter,
boolean hasChildren) {
showEvaluating.set(false);
if (isHintHidden()) {
return;
}
@@ -230,6 +233,10 @@ public class XValueHint extends AbstractValueHint {
@Override
public void errorOccurred(@NotNull final String errorMessage) {
showEvaluating.set(false);
if (myCurrentHint != null) {
myCurrentHint.hide();
}
if (getType() == ValueHintType.MOUSE_CLICK_HINT) {
ApplicationManager.getApplication().invokeLater(() -> showHint(HintUtil.createErrorLabel(errorMessage)));
}
File diff suppressed because it is too large Load Diff
@@ -20,6 +20,7 @@ import com.intellij.psi.tree.IElementType;
import com.intellij.psi.tree.TokenSet;
import com.intellij.util.containers.Stack;
import static com.intellij.util.ArrayUtil.indexOf;
import static org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes.*;
import static org.jetbrains.plugins.groovy.lang.lexer.TokenSets.KEYWORDS;
import static org.jetbrains.plugins.groovy.lang.lexer.TokenSets.LEFT_BRACES;
@@ -38,7 +39,6 @@ public abstract class GroovyLexerBase implements FlexLexer {
public final Stack<Integer> stateStack = new Stack<>();
private final Stack<IElementType> bracesStack = new Stack<>();
private IElementType lastToken = null;
protected void yybeginstate(int... states) {
for (int state : states) {
@@ -60,7 +60,6 @@ public abstract class GroovyLexerBase implements FlexLexer {
protected void resetState() {
stateStack.clear();
bracesStack.clear();
lastToken = null;
}
protected IElementType storeToken(IElementType tokenType) {
@@ -81,17 +80,19 @@ public abstract class GroovyLexerBase implements FlexLexer {
bracesStack.pop();
}
}
lastToken = tokenType;
if (indexOf(getDivisionStates(), yystate()) != -1 && DIVISION_IS_EXPECTED_AFTER.contains(tokenType)) {
yybeginstate(getDivisionExpectedState());
}
return tokenType;
}
protected boolean isRegexExpected() {
return !DIVISION_IS_EXPECTED_AFTER.contains(lastToken);
}
protected boolean isWithinBraces() {
return !bracesStack.empty() && bracesStack.peek() != mLCURLY;
}
protected abstract int getInitialState();
protected abstract int[] getDivisionStates();
protected abstract int getDivisionExpectedState();
}
@@ -34,13 +34,26 @@ import static org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes.*;
%type IElementType
%{
@Override
protected int getInitialState() {
return YYINITIAL;
}
@Override
protected int getDivisionExpectedState() {
return DIVISION_EXPECTED;
}
@Override
protected int[] getDivisionStates() {
return new int[] {YYINITIAL, IN_INNER_BLOCK};
}
%}
%state IN_INNER_BLOCK
%xstate DIVISION_EXPECTED
%xstate IN_SINGLE_GSTRING
%xstate IN_TRIPLE_GSTRING
%xstate IN_SLASHY_STRING
@@ -407,22 +420,32 @@ mGSTRING_LITERAL = {mDOUBLE_QUOTED_LITERAL} | {mTRIPLE_DOUBLE_QUOTED_LITERAL}
///////////////////////// Reserved shorthands //////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
<DIVISION_EXPECTED> {
{WHITE_SPACE} {
return TokenType.WHITE_SPACE;
}
"/"/[^/*=] {
yyendstate(DIVISION_EXPECTED);
return storeToken(mDIV);
}
"$/" {
yypushback(1);
yyendstate(DIVISION_EXPECTED);
return storeToken(mDOLLAR);
}
[^] {
yypushback(1);
yyendstate(DIVISION_EXPECTED);
}
}
"/" {
if (isRegexExpected()) {
yybeginstate(IN_SLASHY_STRING);
return storeToken(mREGEX_BEGIN);
} else {
return storeToken(mDIV);
}
yybeginstate(IN_SLASHY_STRING);
return storeToken(mREGEX_BEGIN);
}
"$/" {
if (isRegexExpected()) {
yybeginstate(IN_DOLLAR_SLASH_STRING);
return storeToken(mDOLLAR_SLASH_REGEX_BEGIN);
} else {
yypushback(1);
return storeToken(mDOLLAR);
}
yybeginstate(IN_DOLLAR_SLASH_STRING);
return storeToken(mDOLLAR_SLASH_REGEX_BEGIN);
}
"{" {
yybeginstate(YYINITIAL, NLS_AFTER_LBRACE);
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2016 JetBrains s.r.o.
* Copyright 2000-2017 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.
@@ -35,5 +35,6 @@ class CommentsParsingTest extends GroovyParsingTestCase {
void testNls2() throws Throwable { doTest() }
void testRocher3() throws Throwable { doTest() }
void testAfterIdentifier() throws Throwable { doTest() }
}
@@ -50,6 +50,8 @@ class ExpressionsParsingTest extends GroovyParsingTestCase {
void testarithmetic$mul3() throws Throwable { doTest() }
void testarithmetic$mul4() throws Throwable { doTest() }
void testarithmetic$post1() throws Throwable { doTest() }
void testarithmetic$sh1() throws Throwable { doTest() }
@@ -408,6 +410,8 @@ class ExpressionsParsingTest extends GroovyParsingTestCase {
void testregex$dollarSlashyUltimate() { doTest() }
void testregex$afterNewLine() { doTest() }
void testrelational$eq1() throws Throwable { doTest() }
void testrelational$inst0() throws Throwable { doTest() }
@@ -0,0 +1,13 @@
a //
a /* */
-----
Groovy script
Reference expression
PsiElement(identifier)('a')
PsiWhiteSpace(' ')
PsiComment(line comment)('//')
PsiElement(new line)('\n')
Reference expression
PsiElement(identifier)('a')
PsiWhiteSpace(' ')
PsiComment(block comment)('/* */')
@@ -0,0 +1,11 @@
a /= b
-----
Groovy script
Assignment expression
Reference expression
PsiElement(identifier)('a')
PsiWhiteSpace(' ')
PsiElement(/=)('/=')
PsiWhiteSpace(' ')
Reference expression
PsiElement(identifier)('b')
@@ -0,0 +1,12 @@
a
/foo/
-----
Groovy script
Reference expression
PsiElement(identifier)('a')
PsiElement(new line)('\n')
Literal
GroovyASTPsiElementImpl(regex literal)
PsiElement(regex begin)('/')
PsiElement(regex content)('foo')
PsiElement(regex end)('/')
@@ -1,30 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="module" module-name="annotations" />
<orderEntry type="module-library">
<library>
<CLASSES>
<root url="jar://$MODULE_DIR$/../lib/aether-1.1.0-all.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</orderEntry>
<orderEntry type="module-library">
<library>
<CLASSES>
<root url="jar://$MODULE_DIR$/../lib/maven-aether-provider-3.3.9-all.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</orderEntry>
</component>
</module>
@@ -1,143 +0,0 @@
package org.jetbrains.idea.maven.aether;
import org.apache.maven.repository.internal.MavenRepositorySystemUtils;
import org.eclipse.aether.DefaultRepositorySystemSession;
import org.eclipse.aether.RepositorySystem;
import org.eclipse.aether.artifact.Artifact;
import org.eclipse.aether.artifact.DefaultArtifact;
import org.eclipse.aether.collection.CollectRequest;
import org.eclipse.aether.connector.basic.BasicRepositoryConnectorFactory;
import org.eclipse.aether.graph.Dependency;
import org.eclipse.aether.impl.DefaultServiceLocator;
import org.eclipse.aether.repository.LocalRepository;
import org.eclipse.aether.repository.RemoteRepository;
import org.eclipse.aether.resolution.ArtifactResult;
import org.eclipse.aether.resolution.DependencyRequest;
import org.eclipse.aether.resolution.DependencyResult;
import org.eclipse.aether.spi.connector.RepositoryConnectorFactory;
import org.eclipse.aether.spi.connector.transport.TransporterFactory;
import org.eclipse.aether.transfer.TransferEvent;
import org.eclipse.aether.transfer.TransferListener;
import org.eclipse.aether.transport.file.FileTransporterFactory;
import org.eclipse.aether.transport.http.HttpTransporterFactory;
import org.eclipse.aether.util.artifact.JavaScopes;
import org.eclipse.aether.util.filter.DependencyFilterUtils;
import org.eclipse.aether.util.version.GenericVersionScheme;
import org.eclipse.aether.version.InvalidVersionSpecificationException;
import org.eclipse.aether.version.Version;
import org.eclipse.aether.version.VersionScheme;
import org.jetbrains.annotations.NotNull;
import java.io.File;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
/**
* @author Eugene Zhuravlev
* Date: 20-Jun-16
*
* Aether-based repository manager and dependency resolver using maven implementation of this functionality.
*
* instance of this component should be managed by the code which requires dependency resolution functionality
* all necessary params like path to local repo should be passed in constructor
*
*/
public class ArtifactRepositoryManager {
private static final String ARTIFACT_EXTENSION = "jar";
private final VersionScheme myVersioning = new GenericVersionScheme();
private final DefaultRepositorySystemSession mySession;
// todo: more remotes? make remote repos configurable?
public static final List<RemoteRepository> REMOTE_REPOSITORIES = Collections.singletonList(
new RemoteRepository.Builder("central", "default", "http://central.maven.org/maven2/").build()
);
private static final RepositorySystem ourSystem;
static {
final DefaultServiceLocator locator = MavenRepositorySystemUtils.newServiceLocator();
locator.addService(RepositoryConnectorFactory.class, BasicRepositoryConnectorFactory.class);
locator.addService(TransporterFactory.class, FileTransporterFactory.class);
locator.addService(TransporterFactory.class, HttpTransporterFactory.class);
locator.setErrorHandler(new DefaultServiceLocator.ErrorHandler() {
public void serviceCreationFailed(Class<?> type, Class<?> impl, Throwable exception) {
if (exception != null) {
throw new RuntimeException(exception);
}
}
});
ourSystem = locator.getService(RepositorySystem.class);
}
public ArtifactRepositoryManager(@NotNull File localRepositoryPath) {
this(localRepositoryPath, ProgressConsumer.DEAF);
}
public ArtifactRepositoryManager(@NotNull File localRepositoryPath, @NotNull final ProgressConsumer progressConsumer) {
final DefaultRepositorySystemSession session = MavenRepositorySystemUtils.newSession();
if (progressConsumer != ProgressConsumer.DEAF) {
session.setTransferListener((TransferListener)Proxy
.newProxyInstance(session.getClass().getClassLoader(), new Class[]{TransferListener.class}, new InvocationHandler() {
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
final Object event = args[0];
if (event instanceof TransferEvent) {
progressConsumer.consume(event.toString());
//if (((TransferEvent)event).getType() != TransferEvent.EventType.PROGRESSED) {
// progressConsumer.consume(event.toString());
//}
}
return null;
}
}));
}
// setup session here
session.setLocalRepositoryManager(ourSystem.newLocalRepositoryManager(session, new LocalRepository(localRepositoryPath)));
session.setReadOnly();
mySession = session;
}
public Collection<File> resolveDependency(String groupId, String artifactId, String version) throws Exception {
final DependencyRequest dependencyRequest = new DependencyRequest(
createCollectRequest(groupId, artifactId, toVersion(version)),
DependencyFilterUtils.classpathFilter(JavaScopes.COMPILE)
);
final DependencyResult result = ourSystem.resolveDependencies(mySession, dependencyRequest);
final List<File> files = new ArrayList<>();
for (ArtifactResult artifactResult : result.getArtifactResults()) {
files.add(artifactResult.getArtifact().getFile());
}
return files;
}
private static CollectRequest createCollectRequest(String groupId, String artifactId, Version version) {
return createCollectRequest(groupId, artifactId, Collections.singleton(version));
}
private static CollectRequest createCollectRequest(String groupId, String artifactId, Collection<Version> versions) {
CollectRequest request = new CollectRequest();
for (Artifact artifact : toArtifacts(groupId, artifactId, versions)) {
request.addDependency(new Dependency(artifact, JavaScopes.COMPILE));
}
return request.setRepositories(REMOTE_REPOSITORIES);
}
private Version toVersion(String version) throws InvalidVersionSpecificationException {
return myVersioning.parseVersion(version);
}
private static List<Artifact> toArtifacts(String groupId, String artifactId, Collection<Version> versions) {
if (versions.isEmpty()) {
return Collections.emptyList();
}
final List<Artifact> result = new ArrayList<>(versions.size());
for (Version version : versions) {
result.add(new DefaultArtifact(groupId, artifactId, ARTIFACT_EXTENSION, version.toString()));
}
return result;
}
}
@@ -1,14 +0,0 @@
package org.jetbrains.idea.maven.aether;
/**
* @author Eugene Zhuravlev
* Date: 12-Aug-16
*/
public interface ProgressConsumer {
ProgressConsumer DEAF = new ProgressConsumer() {
public void consume(String message) {
}
};
void consume(String message);
}
@@ -310,3 +310,6 @@ insert.sam.method.call.fix.family.name=Insert single abstract method call
wrap.with.java.io.file.text=Wrap using 'new File()'
wrap.with.java.io.file.parameter.single.text=Wrap parameter using 'new File()'
wrap.with.java.io.file.parameter.multiple.text=Wrap {0, choice, 1#1st|2#2nd|3#3rd|4#{0,number}th} parameter using ''new File()''
java.9.merge.module.statements.fix.family.name=Merge with other ''{0}'' statement
java.9.merge.module.statements.fix.name=Merge with other ''{0} {1}'' statement