Merge remote-tracking branch 'origin/master'

This commit is contained in:
Dmitry Trofimov
2013-05-29 17:59:08 +02:00
66 changed files with 959 additions and 346 deletions
-1
View File
@@ -19,7 +19,6 @@
<orderEntry type="module" module-name="relaxng" scope="RUNTIME" />
<orderEntry type="module" module-name="spellchecker" scope="RUNTIME" />
<orderEntry type="module" module-name="xdebugger-impl" scope="RUNTIME" />
<orderEntry type="module" module-name="resources" scope="TEST" />
</component>
</module>
@@ -28,6 +28,7 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
@@ -47,8 +48,9 @@ public class PlainModuleTemplatesFactory extends ProjectTemplatesFactory {
return builder.getGroupName();
}
});
groups.add(OTHER_GROUP);
return ArrayUtil.toStringArray(groups);
HashSet<String> set = new HashSet<String>(groups);
set.add(OTHER_GROUP);
return ArrayUtil.toStringArray(set);
}
@NotNull
@@ -16,6 +16,7 @@
package com.intellij.codeInsight.completion;
import com.intellij.codeInsight.ExpectedTypeInfo;
import com.intellij.codeInsight.completion.impl.BetterPrefixMatcher;
import com.intellij.codeInsight.completion.impl.CamelHumpMatcher;
import com.intellij.codeInsight.lookup.AutoCompletionPolicy;
import com.intellij.codeInsight.lookup.LookupElement;
@@ -40,9 +41,9 @@ import static com.intellij.patterns.PsiJavaPatterns.psiElement;
public class JavaNoVariantsDelegator extends CompletionContributor {
@Override
public void fillCompletionVariants(final CompletionParameters parameters, final CompletionResultSet result) {
final boolean empty = containsOnlyPackages(result.runRemainingContributors(parameters, true)) ||
suggestMetaAnnotations(parameters);
public void fillCompletionVariants(final CompletionParameters parameters, CompletionResultSet result) {
LinkedHashSet<CompletionResult> plainResults = result.runRemainingContributors(parameters, true);
final boolean empty = containsOnlyPackages(plainResults) || suggestMetaAnnotations(parameters);
if (!empty && parameters.getInvocationCount() == 0) {
result.restartCompletionWhenNothingMatches();
@@ -50,10 +51,13 @@ public class JavaNoVariantsDelegator extends CompletionContributor {
if (empty) {
delegate(parameters, JavaCompletionSorting.addJavaSorting(parameters, result));
} else if (Registry.is("ide.completion.show.all.classes")) {
} else if (Registry.is("ide.completion.show.all.classes") || Registry.is("ide.completion.show.better.matching.classes")) {
if (parameters.getInvocationCount() <= 1 &&
JavaCompletionContributor.mayStartClassName(result) &&
JavaCompletionContributor.isClassNamePossible(parameters)) {
if (Registry.is("ide.completion.show.better.matching.classes")) {
result = result.withPrefixMatcher(new BetterPrefixMatcher(result.getPrefixMatcher(), BetterPrefixMatcher.getBestMatchingDegree(plainResults)));
}
suggestNonImportedClasses(parameters, result);
}
}
@@ -22,6 +22,11 @@ import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.command.CommandProcessor;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.event.*;
import com.intellij.openapi.editor.event.DocumentAdapter;
import com.intellij.openapi.fileChooser.ex.FileChooserDialogImpl;
import com.intellij.openapi.fileChooser.ex.TextFieldAction;
import com.intellij.openapi.fileTypes.StdFileTypes;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.ContentIterator;
@@ -35,9 +40,10 @@ import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.*;
import com.intellij.ui.ScrollPaneFactory;
import com.intellij.ui.TreeSpeedSearch;
import com.intellij.ui.*;
import com.intellij.ui.components.labels.LinkLabel;
import com.intellij.ui.treeStructure.Tree;
import com.intellij.util.Alarm;
import com.intellij.util.IncorrectOperationException;
import com.intellij.util.PlatformIcons;
import com.intellij.util.containers.Convertor;
@@ -66,6 +72,9 @@ public class PackageChooserDialog extends PackageChooser {
private final Project myProject;
private final String myTitle;
private Module myModule;
private EditorTextField myPathEditor;
private Alarm myAlarm = new Alarm(getDisposable());
public PackageChooserDialog(String title, @NotNull Module module) {
super(module.getProject(), true);
@@ -147,19 +156,69 @@ public class PackageChooserDialog extends PackageChooser {
else {
setTitle(myTitle);
}
updatePathFromTree();
}
});
panel.add(scrollPane, BorderLayout.CENTER);
DefaultActionGroup group = createActionGroup(myTree);
final JPanel northPanel = new JPanel(new BorderLayout());
panel.add(northPanel, BorderLayout.NORTH);
ActionToolbar toolBar = ActionManager.getInstance().createActionToolbar(ActionPlaces.UNKNOWN, group, true);
panel.add(toolBar.getComponent(), BorderLayout.NORTH);
toolBar.getComponent().setAlignmentX(JComponent.LEFT_ALIGNMENT);
northPanel.add(toolBar.getComponent(), BorderLayout.WEST);
setupPathComponent(northPanel);
return panel;
}
private void setupPathComponent(final JPanel northPanel) {
northPanel.add(new TextFieldAction() {
@Override
public void linkSelected(LinkLabel aSource, Object aLinkData) {
toggleShowPathComponent(northPanel, this);
}
}, BorderLayout.EAST);
myPathEditor = new EditorTextField(JavaReferenceEditorUtil.createDocument("", myProject, false), myProject, StdFileTypes.JAVA);
myPathEditor.addDocumentListener(new DocumentAdapter() {
@Override
public void documentChanged(DocumentEvent e) {
myAlarm.cancelAllRequests();
myAlarm.addRequest(new Runnable() {
@Override
public void run() {
updateTreeFromPath();
}
}, 300);
}
});
myPathEditor.setBorder(BorderFactory.createEmptyBorder(0, 0, 2, 0));
northPanel.add(myPathEditor, BorderLayout.SOUTH);
}
private void toggleShowPathComponent(JPanel northPanel, TextFieldAction fieldAction) {
boolean toShowTextField = !isPathShowing();
PropertiesComponent.getInstance().setValue(FileChooserDialogImpl.FILE_CHOOSER_SHOW_PATH_PROPERTY, Boolean.toString(toShowTextField));
myPathEditor.setVisible(toShowTextField);
fieldAction.update();
northPanel.revalidate();
northPanel.repaint();
updatePathFromTree();
}
private static boolean isPathShowing() {
return PropertiesComponent.getInstance().getBoolean(FileChooserDialogImpl.FILE_CHOOSER_SHOW_PATH_PROPERTY, true);
}
private void updatePathFromTree() {
if (!isPathShowing()) return;
final PsiPackage selection = getTreeSelection();
myPathEditor.setText(selection != null ? selection.getQualifiedName() : "");
}
private void updateTreeFromPath() {
selectPackage(myPathEditor.getText().trim());
}
private DefaultActionGroup createActionGroup(JComponent component) {
final DefaultActionGroup group = new DefaultActionGroup();
final DefaultActionGroup temp = new DefaultActionGroup();
@@ -81,8 +81,7 @@ public class ExtractMethodHandler implements RefactoringActionHandler {
editor.getScrollingModel().scrollToCaret(ScrollType.MAKE_VISIBLE);
if (!editor.getSelectionModel().hasSelection()) {
final int offset = editor.getCaretModel().getOffset();
final PsiElement[] statementsInRange = IntroduceVariableBase.findStatementsAtOffset(editor, file, offset);
final List<PsiExpression> expressions = IntroduceVariableBase.collectExpressions(file, editor, offset, statementsInRange);
final List<PsiExpression> expressions = IntroduceVariableBase.collectExpressions(file, editor, offset, true);
if (expressions.isEmpty()) {
editor.getSelectionModel().selectLineAtCaret();
}
@@ -99,7 +99,7 @@ public class ElementToWorkOn {
}
if (!editor.getSelectionModel().hasSelection()){
final List<PsiExpression> expressions = IntroduceVariableBase.collectExpressions(file, editor, offset, statementsInRange);
final List<PsiExpression> expressions = IntroduceVariableBase.collectExpressions(file, editor, offset);
for (Iterator<PsiExpression> iterator = expressions.iterator(); iterator.hasNext(); ) {
PsiExpression expression = iterator.next();
if (!processor.accept(new ElementToWorkOn(null, expression))) {
@@ -125,7 +125,7 @@ public abstract class IntroduceVariableBase extends IntroduceHandlerBase {
}
if (!selectionModel.hasSelection()) {
final List<PsiExpression> expressions = collectExpressions(file, editor, offset, statementsInRange);
final List<PsiExpression> expressions = collectExpressions(file, editor, offset);
if (expressions.isEmpty()) {
selectionModel.selectLineAtCaret();
} else if (expressions.size() == 1) {
@@ -162,7 +162,16 @@ public abstract class IntroduceVariableBase extends IntroduceHandlerBase {
return Boolean.valueOf(PropertiesComponent.getInstance().getOrInit(PREFER_STATEMENTS_OPTION, "false")).booleanValue() || Registry.is(PREFER_STATEMENTS_OPTION, false);
}
public static List<PsiExpression> collectExpressions(final PsiFile file, final Editor editor, final int offset, final PsiElement... statementsInRange) {
public static List<PsiExpression> collectExpressions(final PsiFile file,
final Editor editor,
final int offset) {
return collectExpressions(file, editor, offset, false);
}
public static List<PsiExpression> collectExpressions(final PsiFile file,
final Editor editor,
final int offset,
boolean acceptVoid) {
Document document = editor.getDocument();
CharSequence text = document.getCharsSequence();
int correctedOffset = offset;
@@ -196,7 +205,8 @@ public abstract class IntroduceVariableBase extends IntroduceHandlerBase {
}*/
PsiExpression expression = PsiTreeUtil.getParentOfType(elementAtCaret, PsiExpression.class);
while (expression != null) {
if (!expressions.contains(expression) && !(expression instanceof PsiParenthesizedExpression) && !(expression instanceof PsiSuperExpression) && expression.getType() != PsiType.VOID) {
if (!expressions.contains(expression) && !(expression instanceof PsiParenthesizedExpression) && !(expression instanceof PsiSuperExpression) &&
(acceptVoid || expression.getType() != PsiType.VOID)) {
if (expression instanceof PsiMethodReferenceExpression) {
expressions.add(expression);
}
@@ -23,6 +23,9 @@ import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiMethod;
import com.intellij.psi.PsiParameter;
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
import com.intellij.psi.codeStyle.VariableKind;
import com.intellij.psi.impl.beanProperties.BeanProperty;
import com.intellij.psi.util.PropertyUtil;
import com.intellij.refactoring.RenameRefactoring;
@@ -65,6 +68,15 @@ public abstract class BeanPropertyRenameHandler implements RenameHandler {
if (setter != null) {
final String setterName = PropertyUtil.suggestSetterName(newName);
rename.addElement(setter, setterName);
final PsiParameter[] setterParameters = setter.getParameterList().getParameters();
if (setterParameters.length == 1) {
final JavaCodeStyleManager manager = JavaCodeStyleManager.getInstance(psiElement.getProject());
final String suggestedParameterName = manager.propertyNameToVariableName(property.getName(), VariableKind.PARAMETER);
if (suggestedParameterName.equals(setterParameters[0].getName())) {
rename.addElement(setterParameters[0], manager.propertyNameToVariableName(newName, VariableKind.PARAMETER));
}
}
}
final PsiMethod getter = property.getGetter();
@@ -43,11 +43,21 @@ public class JavaReferenceEditorUtil {
}
@Nullable
public static Document createDocument(final String text, Project project, boolean isClassesAccepted) {
public static Document createDocument(final String text,
Project project,
boolean isClassesAccepted) {
return createDocument(text, project, isClassesAccepted, JavaCodeFragment.VisibilityChecker.EVERYTHING_VISIBLE);
}
@Nullable
public static Document createDocument(final String text,
Project project,
boolean isClassesAccepted,
JavaCodeFragment.VisibilityChecker visibilityChecker) {
final PsiPackage defaultPackage = JavaPsiFacade.getInstance(project).findPackage("");
final JavaCodeFragmentFactory factory = JavaCodeFragmentFactory.getInstance(project);
final JavaCodeFragment fragment = factory.createReferenceCodeFragment(text, defaultPackage, true, isClassesAccepted);
fragment.setVisibilityChecker(JavaCodeFragment.VisibilityChecker.EVERYTHING_VISIBLE);
fragment.setVisibilityChecker(visibilityChecker);
return PsiDocumentManager.getInstance(project).getDocument(fragment);
}
@@ -43,7 +43,7 @@ public class ReferenceEditorComboWithBrowseButton extends ComponentWithBrowseBut
@NotNull final Project project,
boolean toAcceptClasses,
final JavaCodeFragment.VisibilityChecker visibilityChecker, final String recentsKey) {
super(new EditorComboBox(createDocument(StringUtil.isEmpty(text) ? "" : text, project, toAcceptClasses, visibilityChecker), project, StdFileTypes.JAVA),
super(new EditorComboBox(JavaReferenceEditorUtil.createDocument(StringUtil.isEmpty(text) ? "" : text, project, toAcceptClasses, visibilityChecker), project, StdFileTypes.JAVA),
browseActionListener);
final List<String> recentEntries = RecentsManager.getInstance(project).getRecentEntries(recentsKey);
if (recentEntries != null) {
@@ -54,16 +54,6 @@ public class ReferenceEditorComboWithBrowseButton extends ComponentWithBrowseBut
}
}
private static Document createDocument(final String text,
Project project,
boolean isClassesAccepted,
final JavaCodeFragment.VisibilityChecker visibilityChecker) {
PsiPackage defaultPackage = JavaPsiFacade.getInstance(project).findPackage("");
final JavaCodeFragment fragment = JavaCodeFragmentFactory.getInstance(project).createReferenceCodeFragment(text, defaultPackage, true, isClassesAccepted);
fragment.setVisibilityChecker(visibilityChecker);
return PsiDocumentManager.getInstance(project).getDocument(fragment);
}
public String getText(){
return getChildComponent().getText().trim();
}
@@ -405,6 +405,14 @@ public class ControlFlowUtil {
if (parent instanceof PsiClass) {
final PsiClass clss = (PsiClass)parent;
if (PsiTreeUtil.isAncestor(targetClassMember, clss, false)) return false;
PsiClass containingClass = PsiTreeUtil.getParentOfType(ref, PsiClass.class);
while (containingClass != null) {
if (containingClass.isInheritor(clss, true) &&
PsiTreeUtil.isAncestor(targetClassMember, containingClass, false)) {
return false;
}
containingClass = containingClass.getContainingClass();
}
}
}
@@ -0,0 +1,6 @@
class MyClass {
String hc = this.<caret>
@Annotation
public void myAnnotatedMethod() {}
}
@@ -0,0 +1,6 @@
class MyClass {
String hc = this.toString()<caret>
@Annotation
public void myAnnotatedMethod() {}
}
@@ -0,0 +1,13 @@
public class Foo {
public void update() {}
}
class FooBar {
{
Foo tm = new Foo() {
{
<selection>update()</selection>;
}
};
}
}
@@ -0,0 +1,17 @@
public class Foo {
public void update() {}
}
class FooBar {
{
Foo tm = new Foo() {
{
newMethod();
}
private void newMethod() {
update();
}
};
}
}
@@ -14,6 +14,14 @@ public class TabCompletionTest extends LightFixtureCompletionTestCase {
checkResultByFile("MethodLookup3_After.java");
}
public void _testMethodCallBeforeAnnotation() {
String name = getTestName(false);
myFixture.configureByFile(name + ".java");
myFixture.completeBasic();
myFixture.type("tos\t");
checkResultByFile(name + "_After.java");
}
public void testReplaceThisWithSuper() throws Throwable {
configureByFile("ReplaceThisWithSuper.java");
checkResultByFile("ReplaceThisWithSuper_After.java");
@@ -540,4 +540,15 @@ class Foo {
}
}
public void "test expand current live template on no suggestions in lookup"() {
myFixture.configureByText "a.java", "class Foo {{ <caret> }}"
myFixture.completeBasic()
assert myFixture.lookup
myFixture.type("sout")
assert myFixture.lookup
assert myFixture.lookupElementStrings == []
myFixture.type('\t')
myFixture.checkResult "class Foo {{\n System.out.println(<caret>); }}"
}
}
@@ -583,6 +583,10 @@ public class ExtractMethodTest extends LightCodeInsightTestCase {
doDuplicatesTest();
}
public void testTargetAnonymous() throws Exception {
doTest();
}
private void doTestDisabledParam() throws PrepareFailedException {
final CodeStyleSettings settings = CodeStyleSettingsManager.getSettings(getProject());
settings.ELSE_ON_NEW_LINE = true;
@@ -15,8 +15,7 @@
*/
package com.intellij.concurrency;
import com.intellij.util.Consumer;
import org.jetbrains.annotations.NotNull;
import java.util.concurrent.Executor;
import java.util.concurrent.Future;
@@ -25,5 +24,5 @@ import java.util.concurrent.Future;
* Author: dmitrylomov
*/
public interface AsyncFuture<V> extends Future<V> {
void addConsumer(Executor executor, ResultConsumer<V> consumer);
void addConsumer(@NotNull Executor executor, @NotNull ResultConsumer<V> consumer);
}
@@ -15,10 +15,12 @@
*/
package com.intellij.concurrency;
import org.jetbrains.annotations.NotNull;
/**
* Author: dmitrylomov
*/
public interface AsyncFutureResult<V> extends AsyncFuture<V> {
void set(V value);
void setException(Throwable t);
void setException(@NotNull Throwable t);
}
@@ -15,6 +15,8 @@
*/
package com.intellij.concurrency;
import org.jetbrains.annotations.NotNull;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
@@ -22,7 +24,7 @@ import java.util.concurrent.Future;
* Author: dmitrylomov
*/
public class AsyncUtil {
public static <V> V get(Future<V> result) {
public static <V> V get(@NotNull Future<V> result) {
try {
return result.get();
}
@@ -30,11 +32,12 @@ public class AsyncUtil {
throw new Error(e);
}
catch (ExecutionException e) {
if (e.getCause() instanceof RuntimeException)
throw (RuntimeException) e.getCause();
else
if (e.getCause() instanceof RuntimeException) {
throw (RuntimeException)e.getCause();
}
else {
throw new Error(e);
}
}
}
}
@@ -15,18 +15,20 @@
*/
package com.intellij.concurrency;
import org.jetbrains.annotations.NotNull;
import java.util.concurrent.atomic.AtomicBoolean;
/**
* Executes given runnable exactly once.
*
* <p/>
* Author: dmitrylomov
*/
public class DoOnce {
private Runnable myRunnable;
private final AtomicBoolean myAlreadyRun;
public DoOnce(Runnable runnable) {
public DoOnce(@NotNull Runnable runnable) {
myRunnable = runnable;
myAlreadyRun = new AtomicBoolean(false);
}
@@ -35,7 +37,8 @@ public class DoOnce {
if (myAlreadyRun.compareAndSet(false, true)) {
try {
myRunnable.run();
} finally {
}
finally {
myRunnable = null; // do not leak runnable
}
}
@@ -15,6 +15,8 @@
*/
package com.intellij.concurrency;
import org.jetbrains.annotations.NotNull;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executor;
import java.util.concurrent.TimeUnit;
@@ -27,7 +29,7 @@ public class FinallyFuture<V> implements AsyncFuture<V> {
private final DoOnce myFinallyBlock;
private final AsyncFuture<V> myInner;
public FinallyFuture(AsyncFuture<V> inner, Runnable finallyBlock) {
public FinallyFuture(@NotNull AsyncFuture<V> inner, @NotNull Runnable finallyBlock) {
myInner = inner;
myFinallyBlock = new DoOnce(finallyBlock);
}
@@ -35,8 +37,9 @@ public class FinallyFuture<V> implements AsyncFuture<V> {
@Override
public boolean cancel(boolean mayInterruptIfRunning) {
boolean cancel = myInner.cancel(mayInterruptIfRunning);
if (cancel)
if (cancel) {
myFinallyBlock.execute();
}
return cancel;
}
@@ -61,14 +64,15 @@ public class FinallyFuture<V> implements AsyncFuture<V> {
}
@Override
public void addConsumer(Executor executor, final ResultConsumer<V> consumer) {
public void addConsumer(@NotNull Executor executor, @NotNull final ResultConsumer<V> consumer) {
myInner.addConsumer(executor, new ResultConsumer<V>() {
@Override
public void onSuccess(V value) {
try {
myFinallyBlock.execute();
consumer.onSuccess(value);
} catch (Throwable t) {
}
catch (Throwable t) {
consumer.onFailure(t);
}
}
@@ -77,7 +81,8 @@ public class FinallyFuture<V> implements AsyncFuture<V> {
public void onFailure(Throwable t) {
try {
myFinallyBlock.execute();
} catch (Throwable t1) {
}
catch (Throwable t1) {
t = t1;
}
consumer.onFailure(t);
@@ -86,7 +91,7 @@ public class FinallyFuture<V> implements AsyncFuture<V> {
}
@Override
public V get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException {
public V get(long timeout, @NotNull TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException {
boolean timeoutOccurred = false;
try {
try {
@@ -96,10 +101,11 @@ public class FinallyFuture<V> implements AsyncFuture<V> {
timeoutOccurred = true;
throw t;
}
} finally {
if (!timeoutOccurred)
myFinallyBlock.execute();
}
finally {
if (!timeoutOccurred) {
myFinallyBlock.execute();
}
}
}
}
@@ -96,6 +96,7 @@ public abstract class AbstractQuery<Result> implements Query<Result> {
protected abstract boolean processResults(@NotNull Processor<Result> consumer);
@NotNull
protected AsyncFuture<Boolean> processResultsAsync(@NotNull Processor<Result> consumer) {
final AsyncFutureResult<Boolean> result = AsyncFutureFactory.getInstance().createAsyncFutureResult();
try {
@@ -44,4 +44,5 @@ run.configuration.description={0} build
run.configuration.settings.label.project={0} project:
run.configuration.settings.label.tasks=Tasks:
run.configuration.settings.label.vmoptions=VM options:
run.configuration.settings.caption.vmoptions=VM options:
run.configuration.settings.caption.vmoptions=VM options:
run.text.starting=Executing external tasks ''{0}''...
@@ -71,8 +71,7 @@ public class ExternalSystemTaskExecutionSettings implements Cloneable {
}
public void setTaskNames(List<String> taskNames) {
myTaskNames.clear();
myTaskNames.addAll(taskNames);
myTaskNames = taskNames;
}
@Override
@@ -18,11 +18,13 @@ import com.intellij.openapi.externalSystem.model.serialization.ExternalTaskPojo;
import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskId;
import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskNotificationListenerAdapter;
import com.intellij.openapi.externalSystem.service.internal.ExternalSystemExecuteTaskTask;
import com.intellij.openapi.externalSystem.util.ExternalSystemBundle;
import com.intellij.openapi.options.SettingsEditor;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.InvalidDataException;
import com.intellij.openapi.util.JDOMExternalizable;
import com.intellij.openapi.util.WriteExternalException;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.containers.ContainerUtilRt;
import com.intellij.util.xmlb.XmlSerializer;
import org.jdom.Element;
@@ -103,7 +105,7 @@ public class ExternalSystemRunConfiguration extends RunConfigurationBase {
ConsoleView console = new TextConsoleBuilderImpl(getProject()).getConsole();
final MyProcessHandler processHandler = new MyProcessHandler();
console.attachToProcess(processHandler);
List<ExternalTaskPojo> tasks = ContainerUtilRt.newArrayList();
final List<ExternalTaskPojo> tasks = ContainerUtilRt.newArrayList();
for (String taskName : mySettings.getTaskNames()) {
tasks.add(new ExternalTaskPojo(taskName, mySettings.getExternalProjectPath(), null));
}
@@ -114,9 +116,18 @@ public class ExternalSystemRunConfiguration extends RunConfigurationBase {
ApplicationManager.getApplication().executeOnPooledThread(new Runnable() {
@Override
public void run() {
String greeting = ExternalSystemBundle.message("run.text.starting", StringUtil.join(mySettings.getTaskNames(), " "));
processHandler.notifyTextAvailable(greeting, ProcessOutputTypes.SYSTEM);
task.execute(new ExternalSystemTaskNotificationListenerAdapter() {
private boolean myResetGreeting = true;
@Override
public void onTaskOutput(@NotNull ExternalSystemTaskId id, @NotNull String text, boolean stdOut) {
if (myResetGreeting) {
processHandler.notifyTextAvailable("\r", ProcessOutputTypes.SYSTEM);
myResetGreeting = false;
}
processHandler.notifyTextAvailable(text, stdOut ? ProcessOutputTypes.STDOUT : ProcessOutputTypes.STDERR);
}
@@ -15,7 +15,6 @@
*/
package com.intellij.openapi.externalSystem.service.execution;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.externalSystem.ExternalSystemManager;
import com.intellij.openapi.externalSystem.ExternalSystemUiAware;
import com.intellij.openapi.externalSystem.model.ProjectSystemId;
@@ -30,11 +29,10 @@ import com.intellij.openapi.util.text.StringUtil;
import com.intellij.ui.RawCommandLineEditor;
import com.intellij.ui.components.JBLabel;
import com.intellij.ui.components.JBTextField;
import com.intellij.util.Consumer;
import com.intellij.util.ui.GridBag;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.awt.*;
import static com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil.normalizePath;
@@ -94,52 +92,15 @@ public class ExternalSystemTaskSettingsControl implements ExternalSystemSettings
myTasksLabel = new JBLabel(ExternalSystemBundle.message("run.configuration.settings.label.tasks"));
myTasksTextField = new JBTextField(ExternalSystemConstants.TEXT_FIELD_WIDTH_IN_COLUMNS);
canvas.add(myTasksLabel, ExternalSystemUiUtil.getLabelConstraints(0));
canvas.add(myTasksTextField, ExternalSystemUiUtil.getFillLineConstraints(0));
GridBag c = ExternalSystemUiUtil.getFillLineConstraints(0);
c.insets.right = myProjectPathField.getButton().getPreferredSize().width + 8 /* street magic, sorry */;
canvas.add(myTasksTextField, c);
myVmOptionsLabel = new JBLabel(ExternalSystemBundle.message("run.configuration.settings.label.vmoptions"));
myVmOptionsEditor = new RawCommandLineEditor();
myVmOptionsEditor.setDialogCaption(ExternalSystemBundle.message("run.configuration.settings.caption.vmoptions"));
canvas.add(myVmOptionsLabel, ExternalSystemUiUtil.getLabelConstraints(0));
canvas.add(myVmOptionsEditor, ExternalSystemUiUtil.getFillLineConstraints(0));
canvas.setPaintCallback(new Consumer<Graphics>() {
@Nullable private Dimension myDimension;
@Nullable private Dimension myBounds;
private boolean myBorderReset;
@Override
public void consume(Graphics graphics) {
if (!myBorderReset) {
Editor editor = myProjectPathField.getChildComponent().getEditor();
if (editor != null) {
myBorderReset = true;
editor.setBorder(null);
}
}
Dimension size = myVmOptionsEditor.getTextField().getPreferredSize();
Rectangle bounds = myVmOptionsEditor.getTextField().getBounds();
if (!size.equals(myDimension)) {
myDimension = size;
}
if (myBounds == null || myBounds.width != bounds.width || myBounds.height == bounds.height) {
myBounds = bounds.getSize();
}
applyDimension(myProjectPathField.getChildComponent(), false);
applyDimension(myTasksTextField, true);
}
private void applyDimension(@NotNull JComponent component, boolean processBounds) {
Rectangle bounds = component.getBounds();
if (bounds != null && myBounds != null && (bounds.width != myBounds.width || bounds.height != myBounds.height)) {
component.setPreferredSize(myDimension);
if (processBounds) {
component.setBounds(bounds.x, bounds.y, myBounds.width, myBounds.height);
}
}
}
});
}
@Override
@@ -16,17 +16,26 @@
package com.intellij.openapi.externalSystem.service.ui;
import com.intellij.codeInsight.completion.CompletionResultSet;
import com.intellij.ide.util.PropertiesComponent;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.FoldRegion;
import com.intellij.openapi.editor.FoldingModel;
import com.intellij.openapi.externalSystem.ExternalSystemManager;
import com.intellij.openapi.externalSystem.ExternalSystemUiAware;
import com.intellij.openapi.externalSystem.model.ProjectSystemId;
import com.intellij.openapi.externalSystem.model.serialization.ExternalProjectPojo;
import com.intellij.openapi.externalSystem.settings.AbstractExternalSystemLocalSettings;
import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil;
import com.intellij.openapi.fileChooser.FileChooser;
import com.intellij.openapi.fileChooser.FileChooserDescriptor;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.ComponentWithBrowseButton;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.ui.EditorTextField;
import com.intellij.ui.TextAccessor;
import com.intellij.util.Consumer;
import com.intellij.util.TextFieldCompletionProvider;
import com.intellij.util.TextFieldCompletionProviderDumbAware;
import com.intellij.util.ui.UIUtil;
@@ -43,17 +52,31 @@ import java.util.Map;
*/
public class ExternalProjectPathField extends ComponentWithBrowseButton<EditorTextField> implements TextAccessor {
@NotNull private static final String PROJECT_FILE_TO_START_WITH_KEY = "external.system.task.project.file.to.start";
@NotNull private final Project myProject;
@NotNull private final ProjectSystemId myExternalSystemId;
public ExternalProjectPathField(@NotNull Project project,
@NotNull ProjectSystemId externalSystemId,
@NotNull FileChooserDescriptor descriptor,
@NotNull String fileChooserTitle)
{
super(createTextField(project, externalSystemId), createBrowseListener(descriptor, fileChooserTitle));
super(createTextField(project, externalSystemId), new MyBrowseListener(descriptor, fileChooserTitle, project));
ActionListener[] listeners = getButton().getActionListeners();
for (ActionListener listener : listeners) {
if (listener instanceof MyBrowseListener) {
((MyBrowseListener)listener).setPathField(getChildComponent());
break;
}
}
myProject = project;
myExternalSystemId = externalSystemId;
}
@NotNull
private static EditorTextField createTextField(@NotNull Project project, @NotNull ProjectSystemId externalSystemId) {
ExternalSystemManager<?,?,?,?,?> manager = ExternalSystemApiUtil.getManager(externalSystemId);
private static EditorTextField createTextField(@NotNull final Project project, @NotNull final ProjectSystemId externalSystemId) {
ExternalSystemManager<?, ?, ?, ?, ?> manager = ExternalSystemApiUtil.getManager(externalSystemId);
assert manager != null;
final AbstractExternalSystemLocalSettings settings = manager.getLocalSettingsProvider().fun(project);
final ExternalSystemUiAware uiAware;
@@ -84,38 +107,117 @@ public class ExternalProjectPathField extends ComponentWithBrowseButton<EditorTe
result.stopHere();
}
};
EditorTextField result = provider.createEditor(project, false);
EditorTextField result = provider.createEditor(project, false, new Consumer<Editor>() {
@Override
public void consume(Editor editor) {
collapseIfPossible(editor, externalSystemId, project);
}
});
result.setBorder(UIUtil.getTextFieldBorder());
result.setOneLineMode(true);
result.setOpaque(true);
result.setBackground(UIUtil.getTextFieldBackground());
return result;
}
@Override
public void setText(final String text) {
getChildComponent().setText(text);
@NotNull
private static ActionListener createBrowseListener(@NotNull final FileChooserDescriptor descriptor,
final @NotNull String fileChooserTitle)
{
return new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
descriptor.setTitle(fileChooserTitle);
// TODO den implement
//VirtualFile file = FileChooser.chooseFile(descriptor, get, null);
//if (file != null) {
// setWorkingDirectory(file.getPresentableUrl());
//}
}
};
Editor editor = getChildComponent().getEditor();
if (editor != null) {
collapseIfPossible(editor, myExternalSystemId, myProject);
}
}
@Override
public void setText(String text) {
getChildComponent().setText(text);
private static void collapseIfPossible(@NotNull final Editor editor,
@NotNull ProjectSystemId externalSystemId,
@NotNull Project project)
{
ExternalSystemManager<?,?,?,?,?> manager = ExternalSystemApiUtil.getManager(externalSystemId);
assert manager != null;
final AbstractExternalSystemLocalSettings settings = manager.getLocalSettingsProvider().fun(project);
final ExternalSystemUiAware uiAware;
if (manager instanceof ExternalSystemUiAware) {
uiAware = (ExternalSystemUiAware)manager;
}
else {
uiAware = DefaultExternalSystemUiAware.INSTANCE;
}
String rawText = editor.getDocument().getText();
for (Map.Entry<ExternalProjectPojo, Collection<ExternalProjectPojo>> entry : settings.getAvailableProjects().entrySet()) {
if (entry.getKey().getPath().equals(rawText)) {
collapse(editor, uiAware.getProjectRepresentationName(entry.getKey().getPath(), null));
return;
}
for (ExternalProjectPojo pojo : entry.getValue()) {
if (pojo.getPath().equals(rawText)) {
collapse(editor, uiAware.getProjectRepresentationName(pojo.getPath(), entry.getKey().getPath()));
return;
}
}
}
}
private static void collapse(@NotNull final Editor editor, @NotNull final String placeholder) {
final FoldingModel foldingModel = editor.getFoldingModel();
foldingModel.runBatchFoldingOperation(new Runnable() {
@Override
public void run() {
FoldRegion region = foldingModel.addFoldRegion(0, editor.getDocument().getTextLength(), placeholder);
if (region != null) {
region.setExpanded(false);
}
}
});
}
@Override
public String getText() {
return getChildComponent().getText();
}
private static class MyBrowseListener implements ActionListener {
@NotNull private final FileChooserDescriptor myDescriptor;
@NotNull private final Project myProject;
private EditorTextField myPathField;
MyBrowseListener(@NotNull final FileChooserDescriptor descriptor,
@NotNull final String fileChooserTitle,
@NotNull final Project project)
{
descriptor.setTitle(fileChooserTitle);
myDescriptor = descriptor;
myProject = project;
}
private void setPathField(@NotNull EditorTextField pathField) {
myPathField = pathField;
}
@Override
public void actionPerformed(ActionEvent e) {
if (myPathField == null) {
assert false;
return;
}
PropertiesComponent component = PropertiesComponent.getInstance(myProject);
String pathToStart = myPathField.getText();
if (StringUtil.isEmpty(pathToStart)) {
pathToStart = component.getValue(PROJECT_FILE_TO_START_WITH_KEY);
}
VirtualFile fileToStart = null;
if (!StringUtil.isEmpty(pathToStart)) {
fileToStart = LocalFileSystem.getInstance().findFileByPath(pathToStart);
}
VirtualFile file = FileChooser.chooseFile(myDescriptor, myProject, fileToStart);
if (file != null) {
String path = ExternalSystemApiUtil.getLocalFileSystemPath(file);
myPathField.setText(path);
component.setValue(PROJECT_FILE_TO_START_WITH_KEY, path);
}
}
}
}
@@ -49,12 +49,24 @@ public class ExternalProjectPathLookupElement extends LookupElement {
@Override
public void handleInsert(InsertionContext context) {
Editor editor = context.getEditor();
final FoldingModel foldingModel = editor.getFoldingModel();
foldingModel.runBatchFoldingOperation(new Runnable() {
@Override
public void run() {
FoldRegion[] regions = foldingModel.getAllFoldRegions();
for (FoldRegion region : regions) {
foldingModel.removeFoldRegion(region);
}
}
});
final Document document = editor.getDocument();
final int startOffset = context.getStartOffset();
document.replaceString(startOffset, context.getTailOffset(), myProjectPath);
document.replaceString(startOffset, document.getTextLength(), myProjectPath);
final Project project = context.getProject();
PsiDocumentManager.getInstance(project).commitDocument(document);
final FoldingModel foldingModel = editor.getFoldingModel();
foldingModel.runBatchFoldingOperationDoNotCollapseCaret(new Runnable() {
@Override
public void run() {
@@ -14,11 +14,12 @@ public class SearchRequestQuery extends AbstractQuery<PsiReference> {
private final Project myProject;
private final SearchRequestCollector myRequests;
public SearchRequestQuery(Project project, SearchRequestCollector requests) {
public SearchRequestQuery(@NotNull Project project, @NotNull SearchRequestCollector requests) {
myProject = project;
myRequests = requests;
}
@NotNull
@Override
protected AsyncFuture<Boolean> processResultsAsync(@NotNull Processor<PsiReference> consumer) {
return PsiSearchHelper.SERVICE.getInstance(myProject).processRequestsAsync(myRequests, consumer);
@@ -221,81 +221,82 @@ public class PsiSearchHelperImpl implements PsiSearchHelper {
@NotNull final Processor<PsiElement> psiRootProcessor,
final ProgressIndicator progress) {
myManager.startBatchFilesProcessingMode();
final AtomicInteger counter = new AtomicInteger(0);
final AtomicBoolean canceled = new AtomicBoolean(false);
final AtomicBoolean pceThrown = new AtomicBoolean(false);
final AtomicInteger counter = new AtomicInteger(0);
final AtomicBoolean canceled = new AtomicBoolean(false);
final AtomicBoolean pceThrown = new AtomicBoolean(false);
final int size = files.size();
AsyncFuture<Boolean>
completed = JobLauncher.getInstance().invokeConcurrentlyUnderProgressAsync(files, progress, false, new Processor<VirtualFile>() {
@Override
public boolean process(final VirtualFile vfile) {
final PsiFile file = ApplicationManager.getApplication().runReadAction(new Computable<PsiFile>() {
final int size = files.size();
AsyncFuture<Boolean>
completed = JobLauncher.getInstance().invokeConcurrentlyUnderProgressAsync(files, progress, false, new Processor<VirtualFile>() {
@Override
public boolean process(final VirtualFile vfile) {
final PsiFile file = ApplicationManager.getApplication().runReadAction(new Computable<PsiFile>() {
@Override
public PsiFile compute() {
return vfile.isValid() ? myManager.findFile(vfile) : null;
}
});
if (file != null && !(file instanceof PsiBinaryFile)) {
file.getViewProvider().getContents(); // load contents outside readaction
ApplicationManager.getApplication().runReadAction(new Runnable() {
@Override
public PsiFile compute() {
return vfile.isValid() ? myManager.findFile(vfile) : null;
public void run() {
try {
if (myManager.getProject().isDisposed()) throw new ProcessCanceledException();
List<PsiFile> psiRoots = file.getViewProvider().getAllFiles();
Set<PsiElement> processed = new THashSet<PsiElement>(psiRoots.size() * 2, (float)0.5);
for (PsiElement psiRoot : psiRoots) {
if (progress != null) progress.checkCanceled();
assert psiRoot != null : "One of the roots of file " + file + " is null. All roots: " + psiRoots +
"; ViewProvider: " + file.getViewProvider() + "; Virtual file: " + file.getViewProvider().getVirtualFile();
if (!processed.add(psiRoot)) continue;
if (!psiRoot.isValid()) continue;
if (!psiRootProcessor.process(psiRoot)) {
canceled.set(true);
return;
}
}
myManager.dropResolveCaches();
}
catch (ProcessCanceledException e) {
canceled.set(true);
pceThrown.set(true);
}
}
});
if (file != null && !(file instanceof PsiBinaryFile)) {
file.getViewProvider().getContents(); // load contents outside readaction
ApplicationManager.getApplication().runReadAction(new Runnable() {
@Override
public void run() {
try {
if (myManager.getProject().isDisposed()) throw new ProcessCanceledException();
List<PsiFile> psiRoots = file.getViewProvider().getAllFiles();
Set<PsiElement> processed = new THashSet<PsiElement>(psiRoots.size() * 2, (float)0.5);
for (PsiElement psiRoot : psiRoots) {
if (progress != null) progress.checkCanceled();
assert psiRoot != null : "One of the roots of file " + file + " is null. All roots: " + psiRoots +
"; ViewProvider: " + file.getViewProvider() + "; Virtual file: " + file.getViewProvider().getVirtualFile();
if (!processed.add(psiRoot)) continue;
if (!psiRoot.isValid()) continue;
if (!psiRootProcessor.process(psiRoot)) {
canceled.set(true);
return;
}
}
myManager.dropResolveCaches();
}
catch (ProcessCanceledException e) {
canceled.set(true);
pceThrown.set(true);
}
}
});
}
if (progress != null && progress.isRunning()) {
double fraction = (double)counter.incrementAndGet() / size;
progress.setFraction(fraction);
}
return !canceled.get();
}
});
final AsyncFutureResult<Boolean> ourResult = AsyncFutureFactory.getInstance().createAsyncFutureResult();
completed.addConsumer(SameThreadExecutor.INSTANCE, new DefaultResultConsumer<Boolean>(ourResult) {
@Override
public void onSuccess(Boolean value) {
if (pceThrown.get())
ourResult.setException(new ProcessCanceledException());
else
ourResult.set(value);
if (progress != null && progress.isRunning()) {
double fraction = (double)counter.incrementAndGet() / size;
progress.setFraction(fraction);
}
return !canceled.get();
}
});
@Override
public void onFailure(Throwable t) {
ourResult.setException(t);
final AsyncFutureResult<Boolean> ourResult = AsyncFutureFactory.getInstance().createAsyncFutureResult();
completed.addConsumer(SameThreadExecutor.INSTANCE, new DefaultResultConsumer<Boolean>(ourResult) {
@Override
public void onSuccess(Boolean value) {
if (pceThrown.get()) {
ourResult.setException(new ProcessCanceledException());
}
});
return new FinallyFuture<Boolean>(ourResult, new Runnable() {
@Override
public void run() {
myManager.finishBatchFilesProcessingMode();
else {
ourResult.set(value);
}
});
}
@Override
public void onFailure(Throwable t) {
ourResult.setException(t);
}
});
return new FinallyFuture<Boolean>(ourResult, new Runnable() {
@Override
public void run() {
myManager.finishBatchFilesProcessingMode();
}
});
}
@NotNull
@@ -597,7 +598,7 @@ public class PsiSearchHelperImpl implements PsiSearchHelper {
@NotNull
private AsyncFuture<Boolean> processGlobalRequestsOptimizedAsync(@NotNull MultiMap<Set<IdIndexEntry>, RequestWithProcessor> singles,
final ProgressIndicator progress) {
final ProgressIndicator progress) {
if (singles.isEmpty()) {
return AsyncFutureFactory.wrap(true);
}
@@ -0,0 +1,142 @@
package com.intellij.application.options;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.options.ConfigurationException;
import com.intellij.openapi.options.SearchableConfigurable;
import com.intellij.openapi.options.UnnamedConfigurable;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.Splitter;
import com.intellij.platform.ModuleAttachProcessor;
import com.intellij.ui.CollectionListModel;
import com.intellij.ui.components.JBList;
import com.intellij.ui.components.JBScrollPane;
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import java.awt.*;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @author yole
*/
public abstract class ModuleAwareProjectConfigurable<T extends UnnamedConfigurable> implements SearchableConfigurable {
private final Project myProject;
private final String myDisplayName;
private final String myHelpTopic;
private final Map<Module, T> myModuleConfigurables = new HashMap<Module, T>();
public ModuleAwareProjectConfigurable(Project project, String displayName, String helpTopic) {
myProject = project;
myDisplayName = displayName;
myHelpTopic = helpTopic;
}
@Nls
@Override
public String getDisplayName() {
return myDisplayName;
}
@Override
public String getHelpTopic() {
return myHelpTopic;
}
@Override
public JComponent createComponent() {
if (myProject.isDefault()) {
T configurable = createDefaultProjectConfigurable();
if (configurable != null) {
myModuleConfigurables.put(null, configurable);
return configurable.createComponent();
}
}
final List<Module> modules = ModuleAttachProcessor.getSortedModules(myProject);
if (modules.size() == 1) {
Module module = modules.get(0);
final T configurable = createModuleConfigurable(module);
myModuleConfigurables.put(module, configurable);
return configurable.createComponent();
}
final Splitter splitter = new Splitter(false, 0.25f);
final JBList moduleList = new JBList(new CollectionListModel<Module>(modules));
moduleList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
moduleList.setCellRenderer(new ModuleListCellRenderer());
splitter.setFirstComponent(new JBScrollPane(moduleList));
final CardLayout layout = new CardLayout();
final JPanel cardPanel = new JPanel(layout);
splitter.setSecondComponent(cardPanel);
for (Module module : modules) {
final T configurable = createModuleConfigurable(module);
myModuleConfigurables.put(module, configurable);
final JComponent component = configurable.createComponent();
cardPanel.add(component, module.getName());
}
moduleList.addListSelectionListener(new ListSelectionListener() {
@Override
public void valueChanged(ListSelectionEvent e) {
final Module value = (Module)moduleList.getSelectedValue();
layout.show(cardPanel, value.getName());
}
});
if (modules.size() > 0) {
moduleList.setSelectedIndex(0);
layout.show(cardPanel, modules.get(0).getName());
}
return splitter;
}
@Nullable
protected T createDefaultProjectConfigurable() {
return null;
}
protected abstract T createModuleConfigurable(Module module);
@Override
public boolean isModified() {
for (T configurable : myModuleConfigurables.values()) {
if (configurable.isModified()) return true;
}
return false;
}
@Override
public void apply() throws ConfigurationException {
for (T configurable : myModuleConfigurables.values()) {
configurable.apply();
}
}
@Override
public void reset() {
for (T configurable : myModuleConfigurables.values()) {
configurable.reset();
}
}
@Override
public void disposeUIResources() {
for (T configurable : myModuleConfigurables.values()) {
configurable.disposeUIResources();
}
myModuleConfigurables.clear();
}
@NotNull
@Override
public String getId() {
return getClass().getName();
}
@Override
public Runnable enableSearch(String option) {
return null;
}
}
@@ -0,0 +1,23 @@
package com.intellij.application.options;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleType;
import com.intellij.ui.ListCellRendererWrapper;
import javax.swing.*;
/**
* @author yole
*/
public class ModuleListCellRenderer extends ListCellRendererWrapper<Module> {
@Override
public void customize(JList list, Module module, int index, boolean selected, boolean hasFocus) {
if (module == null) {
setText("[none]");
}
else {
setIcon(ModuleType.get(module).getIcon());
setText(module.getName());
}
}
}
@@ -31,6 +31,8 @@ import com.intellij.openapi.command.CommandProcessor;
import com.intellij.openapi.editor.*;
import com.intellij.openapi.editor.actionSystem.TypedAction;
import com.intellij.openapi.editor.event.*;
import com.intellij.openapi.editor.ex.EditorEx;
import com.intellij.openapi.editor.ex.FocusChangeListener;
import com.intellij.openapi.fileEditor.FileEditorManagerAdapter;
import com.intellij.openapi.fileEditor.FileEditorManagerEvent;
import com.intellij.openapi.fileEditor.FileEditorManagerListener;
@@ -177,6 +179,19 @@ public abstract class CompletionPhase implements Disposable {
}
}
}, this);
if (indicator.isAutopopupCompletion()) {
// lookup is not visible, we have to check ourselves if editor retains focus
((EditorEx)indicator.getEditor()).addFocusListener(new FocusChangeListener() {
@Override
public void focusGained(Editor editor) {
}
@Override
public void focusLost(Editor editor) {
indicator.closeAndFinish(true);
}
}, this);
}
}
@Override
@@ -0,0 +1,59 @@
/*
* 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.
*/
package com.intellij.codeInsight.completion.impl;
import com.intellij.codeInsight.completion.CompletionResult;
import com.intellij.codeInsight.completion.PrefixMatcher;
import org.jetbrains.annotations.NotNull;
import java.util.LinkedHashSet;
/**
* @author peter
*/
public class BetterPrefixMatcher extends PrefixMatcher {
private final PrefixMatcher myOriginal;
private final int myMinMatchingDegree;
public BetterPrefixMatcher(PrefixMatcher original, int minMatchingDegree) {
super(original.getPrefix());
myOriginal = original;
myMinMatchingDegree = minMatchingDegree;
}
public static int getBestMatchingDegree(LinkedHashSet<CompletionResult> plainResults) {
int bestMatchingDegree = Integer.MIN_VALUE;
for (CompletionResult cr : plainResults) {
bestMatchingDegree = Math.max(bestMatchingDegree, RealPrefixMatchingWeigher
.getBestMatchingDegree(cr.getLookupElement(), cr.getPrefixMatcher()));
}
return bestMatchingDegree;
}
@Override
public boolean prefixMatches(@NotNull String name) {
if (!myOriginal.prefixMatches(name) || !myOriginal.isStartMatch(name)) {
return false;
}
return myOriginal.matchingDegree(name) >= myMinMatchingDegree;
}
@NotNull
@Override
public PrefixMatcher cloneWithPrefix(@NotNull String prefix) {
return new BetterPrefixMatcher(myOriginal.cloneWithPrefix(prefix), myMinMatchingDegree);
}
}
@@ -19,13 +19,14 @@ public class RealPrefixMatchingWeigher extends LookupElementWeigher {
@Override
public Comparable weigh(@NotNull LookupElement element) {
final PrefixMatcher matcher = CompletionServiceImpl.getItemMatcher(element, myLocation.getCompletionParameters().getLookup());
return getBestMatchingDegree(element, CompletionServiceImpl.getItemMatcher(element, myLocation.getCompletionParameters().getLookup()));
}
public static int getBestMatchingDegree(LookupElement element, PrefixMatcher matcher) {
int max = Integer.MIN_VALUE;
for (String lookupString : element.getAllLookupStrings()) {
max = Math.max(max, matcher.matchingDegree(lookupString));
}
return -max;
}
}
@@ -84,9 +84,6 @@ public abstract class ChooseItemAction extends EditorAction {
return false;
}
if (finishingChar == Lookup.REPLACE_SELECT_CHAR) {
if (lookup.isFocused()) {
return true;
}
return !lookup.getItems().isEmpty();
}
@@ -21,6 +21,7 @@ import com.intellij.ide.CutProvider;
import com.intellij.ide.DeleteProvider;
import com.intellij.ide.PasteProvider;
import com.intellij.ide.highlighter.HighlighterFactory;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.editor.*;
@@ -628,6 +629,11 @@ public class EditorWindow extends UserDataHolderBase implements EditorEx {
myDelegate.addFocusListener(listener);
}
@Override
public void addFocusListener(@NotNull FocusChangeListener listener, Disposable parentDisposable) {
myDelegate.addFocusListener(listener, parentDisposable);
}
@Override
public Project getProject() {
return myDelegate.getProject();
@@ -13,6 +13,7 @@ import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiFileFactory;
import com.intellij.ui.EditorTextField;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* @author sergey.evdokimov
@@ -68,11 +69,21 @@ public abstract class TextFieldCompletionProvider {
protected abstract void addCompletionVariants(@NotNull String text, int offset, @NotNull String prefix, @NotNull CompletionResultSet result);
@NotNull
public EditorTextField createEditor(Project project) {
return createEditor(project, true);
}
@NotNull
public EditorTextField createEditor(Project project, final boolean shouldHaveBorder) {
return createEditor(project, shouldHaveBorder, null);
}
@NotNull
public EditorTextField createEditor(Project project,
final boolean shouldHaveBorder,
@Nullable final Consumer<Editor> editorConstructionCallback)
{
return new EditorTextField(createDocument(project, ""), project, PlainTextLanguage.INSTANCE.getAssociatedFileType()) {
@Override
protected boolean shouldHaveBorder() {
@@ -88,6 +99,15 @@ public abstract class TextFieldCompletionProvider {
editor.setBorder(null);
}
}
@Override
protected EditorEx createEditor() {
EditorEx result = super.createEditor();
if (editorConstructionCallback != null) {
editorConstructionCallback.consume(result);
}
return result;
}
};
}
}
@@ -24,18 +24,20 @@ import com.intellij.ui.SimpleTextAttributes;
import com.intellij.util.PlatformIcons;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.TestOnly;
import javax.swing.*;
import java.awt.*;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
// todo: move to lang-impl ?
public class CompositeAppearance implements ModifiableCellAppearanceEx {
private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.roots.ui.util.CompositeAppearance");
private Icon myIcon;
private final ArrayList<TextSection> mySections = new ArrayList<TextSection>();
private final List<TextSection> mySections = new ArrayList<TextSection>();
private int myInsertionIndex = 0;
public void customize(@NotNull SimpleColoredComponent component) {
@@ -148,6 +150,7 @@ public class CompositeAppearance implements ModifiableCellAppearanceEx {
return appearance;
}
@TestOnly
public Iterator<TextSection> getSectionsIterator() {
return mySections.iterator();
}
@@ -155,8 +158,8 @@ public class CompositeAppearance implements ModifiableCellAppearanceEx {
public static class TextSection {
private static final TextAttributes DEFAULT_TEXT_ATTRIBUTES = new TextAttributes(null, null, null, null, Font.PLAIN);
private static final String DEFAULT_TEXT = "";
private String TEXT;
private TextAttributes ATTRIBUTES;
private final String TEXT;
private final TextAttributes ATTRIBUTES;
public TextSection(String text, TextAttributes attributes) {
ATTRIBUTES = attributes == null ? DEFAULT_TEXT_ATTRIBUTES : attributes;
@@ -198,7 +201,7 @@ public class CompositeAppearance implements ModifiableCellAppearanceEx {
}
public void addSurrounded(String text, String prefix, String suffix, SimpleTextAttributes textAttributes) {
if (text != null && text.trim().length() > 0) {
if (text != null && !text.trim().isEmpty()) {
addText(prefix + text + suffix, textAttributes);
}
}
@@ -16,6 +16,7 @@
package com.intellij.concurrency;
import com.google.common.util.concurrent.SettableFuture;
import org.jetbrains.annotations.NotNull;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executor;
@@ -33,16 +34,18 @@ public class AsyncFutureResultImpl<V> implements AsyncFutureResult<V> {
}
@Override
public void addConsumer(Executor executor, final ResultConsumer<V> consumer) {
public void addConsumer(@NotNull Executor executor, @NotNull final ResultConsumer<V> consumer) {
myFuture.addListener(new Runnable() {
@Override
public void run() {
try {
final V result = myFuture.get();
consumer.onSuccess(result);
} catch (ExecutionException e) {
}
catch (ExecutionException e) {
consumer.onFailure(e.getCause());
} catch (Throwable throwable) {
}
catch (Throwable throwable) {
consumer.onFailure(throwable);
}
}
@@ -70,7 +73,7 @@ public class AsyncFutureResultImpl<V> implements AsyncFutureResult<V> {
}
@Override
public V get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException {
public V get(long timeout, @NotNull TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException {
return myFuture.get(timeout, unit);
}
@@ -80,7 +83,7 @@ public class AsyncFutureResultImpl<V> implements AsyncFutureResult<V> {
}
@Override
public void setException(Throwable t) {
public void setException(@NotNull Throwable t) {
myFuture.setException(t);
}
}
@@ -130,7 +130,8 @@ public class JobLauncherImpl extends JobLauncher {
try {
final boolean result = invokeConcurrentlyUnderProgress(things, progress, failFastOnAcquireReadAction, thingProcessor);
asyncFutureResult.set(result);
} catch (Throwable t) {
}
catch (Throwable t) {
asyncFutureResult.setException(t);
}
return asyncFutureResult;
@@ -57,7 +57,9 @@ public class ProductivityFeaturesRegistryImpl extends ProductivityFeaturesRegist
readFromXml("file:///ProductivityFeaturesRegistry.xml");
}
catch (Exception e) {
LOG.error(e);
if (!ApplicationManager.getApplication().isUnitTestMode()) {
LOG.error(e);
}
}
try {
@@ -15,6 +15,8 @@
*/
package com.intellij.ide.plugins;
import com.google.common.hash.Hashing;
import com.google.common.io.Files;
import com.intellij.ide.IdeBundle;
import com.intellij.openapi.application.ApplicationInfo;
import com.intellij.openapi.application.PathManager;
@@ -50,6 +52,11 @@ public class RepositoryHelper {
indicator.setText2(IdeBundle.message("progress.connecting.to.plugin.manager", appInfo.getPluginManagerUrl()));
}
File pluginListFile = new File(PathManager.getPluginsPath(), PLUGIN_LIST_FILE);
if (pluginListFile.length() > 0) {
url = url + "&crc32=" + Files.hash(pluginListFile, Hashing.crc32()).toString();
}
HttpURLConnection connection = HttpConfigurable.getInstance().openHttpConnection(url);
connection.setRequestProperty("Accept-Encoding", "gzip");
@@ -63,6 +70,10 @@ public class RepositoryHelper {
indicator.checkCanceled();
}
if (connection.getResponseCode() == 304) {
return loadPluginList(pluginListFile);
}
String encoding = connection.getContentEncoding();
InputStream is = connection.getInputStream();
try {
@@ -103,9 +114,13 @@ public class RepositoryHelper {
os.close();
}
return loadPluginList(temp);
}
private static List<IdeaPluginDescriptor> loadPluginList(File file) throws Exception {
SAXParser parser = SAXParserFactory.newInstance().newSAXParser();
RepositoryContentHandler handler = new RepositoryContentHandler();
parser.parse(temp, handler);
parser.parse(file, handler);
return handler.getPluginsList();
}
@@ -23,7 +23,6 @@ import com.intellij.internal.statistic.beans.PatchedUsage;
import com.intellij.internal.statistic.beans.UsageDescriptor;
import com.intellij.internal.statistic.persistence.SentUsagesPersistence;
import com.intellij.internal.statistic.persistence.UsageStatisticsPersistenceComponent;
import com.intellij.openapi.application.ex.ApplicationManagerEx;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.project.Project;
@@ -176,12 +175,12 @@ public class StatisticsUploadAssistant {
private static Map<GroupDescriptor, Set<PatchedUsage>> mapToPatchedUsagesMap(Map<GroupDescriptor, Set<UsageDescriptor>> allUsages) {
Map<GroupDescriptor, Set<PatchedUsage>> patchedUsages = new LinkedHashMap<GroupDescriptor, Set<PatchedUsage>>();
for (Map.Entry<GroupDescriptor, Set<UsageDescriptor>> entry : allUsages.entrySet()) {
patchedUsages.put(entry.getKey(), ContainerUtil.map2Set(entry.getValue(), new Function<UsageDescriptor, PatchedUsage>() {
patchedUsages.put(entry.getKey(), new HashSet<PatchedUsage>(ContainerUtil.map2Set(entry.getValue(), new Function<UsageDescriptor, PatchedUsage>() {
@Override
public PatchedUsage fun(UsageDescriptor usageDescriptor) {
return new PatchedUsage(usageDescriptor);
}
}));
})));
}
return patchedUsages;
}
@@ -19,6 +19,7 @@ import com.intellij.ide.CopyProvider;
import com.intellij.ide.CutProvider;
import com.intellij.ide.DeleteProvider;
import com.intellij.ide.PasteProvider;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.LogicalPosition;
@@ -105,6 +106,8 @@ public interface EditorEx extends Editor {
boolean setCaretEnabled(boolean enabled);
void addFocusListener(@NotNull FocusChangeListener listener);
void addFocusListener(@NotNull FocusChangeListener listener, Disposable parentDisposable);
void setOneLineMode(boolean b);
@@ -2199,7 +2199,7 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
if (hEnd >= lEnd) {
FoldRegion collapsedFolderAt = myFoldingModel.getCollapsedRegionAtOffset(start);
if (collapsedFolderAt == null) {
if (collapsedFolderAt == null || collapsedFolderAt.getEndOffset() == lEnd) {
position.x = drawSoftWrapAwareBackground(g, backColor, text, start, lEnd - lIterator.getSeparatorLength(), position, fontType,
defaultBackground, clip, softWrapsToSkip, caretRowPainted);
@@ -4268,6 +4268,11 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
myFocusListeners.add(listener);
}
@Override
public void addFocusListener(@NotNull FocusChangeListener listener, Disposable parentDisposable) {
ContainerUtil.add(listener, myFocusListeners, parentDisposable);
}
@Override
@Nullable
public Project getProject() {
@@ -16,12 +16,10 @@
package com.intellij.openapi.fileChooser.ex;
import com.intellij.icons.AllIcons;
import com.intellij.ide.IdeBundle;
import com.intellij.ide.IdeEventQueue;
import com.intellij.ide.SaveAndSyncHandlerImpl;
import com.intellij.ide.util.PropertiesComponent;
import com.intellij.ide.util.treeView.NodeRenderer;
import com.intellij.idea.ActionsBundle;
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.application.ApplicationActivationListener;
import com.intellij.openapi.application.ApplicationManager;
@@ -44,7 +42,6 @@ import com.intellij.openapi.wm.IdeFrame;
import com.intellij.ui.*;
import com.intellij.ui.components.JBList;
import com.intellij.ui.components.labels.LinkLabel;
import com.intellij.ui.components.labels.LinkListener;
import com.intellij.util.ArrayUtil;
import com.intellij.util.Consumer;
import com.intellij.util.IconUtil;
@@ -75,6 +72,7 @@ import java.util.List;
import java.util.Map;
public class FileChooserDialogImpl extends DialogWrapper implements FileChooserDialog, PathChooserDialog, FileLookup {
@NonNls public static final String FILE_CHOOSER_SHOW_PATH_PROPERTY = "FileChooser.ShowPath";
public static final String RECENT_FILES_KEY = "file.chooser.recent.files";
private final FileChooserDescriptor myChooserDescriptor;
protected FileSystemTreeImpl myFileSystemTree;
@@ -292,7 +290,11 @@ public class FileChooserDialogImpl extends DialogWrapper implements FileChooserD
final JPanel toolbarPanel = new JPanel(new BorderLayout());
toolbarPanel.add(toolBar.getComponent(), BorderLayout.CENTER);
myTextFieldAction = new TextFieldAction();
myTextFieldAction = new TextFieldAction() {
public void linkSelected(final LinkLabel aSource, final Object aLinkData) {
toggleShowTextField();
}
};
toolbarPanel.add(myTextFieldAction, BorderLayout.EAST);
myPathTextFieldWrapper = new JPanel(new BorderLayout());
@@ -474,11 +476,11 @@ public class FileChooserDialogImpl extends DialogWrapper implements FileChooserD
private final Map<String, LocalFileSystem.WatchRequest> myRequests = new HashMap<String, LocalFileSystem.WatchRequest>();
private static boolean isToShowTextField() {
return PropertiesComponent.getInstance().getBoolean("FileChooser.ShowPath", true);
return PropertiesComponent.getInstance().getBoolean(FILE_CHOOSER_SHOW_PATH_PROPERTY, true);
}
private static void setToShowTextField(boolean toShowTextField) {
PropertiesComponent.getInstance().setValue("FileChooser.ShowPath", Boolean.toString(toShowTextField));
PropertiesComponent.getInstance().setValue(FILE_CHOOSER_SHOW_PATH_PROPERTY, Boolean.toString(toShowTextField));
}
private final class FileTreeExpansionListener implements TreeExpansionListener {
@@ -577,34 +579,6 @@ public class FileChooserDialogImpl extends DialogWrapper implements FileChooserD
}
private class TextFieldAction extends LinkLabel implements LinkListener {
public TextFieldAction() {
super("", null);
setListener(this, null);
update();
}
protected void onSetActive(final boolean active) {
final String tooltip = AnAction
.createTooltipText(ActionsBundle.message("action.FileChooser.TogglePathShowing.text"),
ActionManager.getInstance().getAction("FileChooser.TogglePathShowing"));
setToolTipText(tooltip);
}
protected String getStatusBarText() {
return ActionsBundle.message("action.FileChooser.TogglePathShowing.text");
}
public void update() {
setVisible(true);
setText(isToShowTextField() ? IdeBundle.message("file.chooser.hide.path") : IdeBundle.message("file.chooser.show.path"));
}
public void linkSelected(final LinkLabel aSource, final Object aLinkData) {
toggleShowTextField();
}
}
private void updatePathFromTree(final List<VirtualFile> selection, boolean now) {
if (!isToShowTextField() || myTreeIsUpdating) return;
@@ -0,0 +1,54 @@
/*
* 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.
*/
package com.intellij.openapi.fileChooser.ex;
import com.intellij.ide.IdeBundle;
import com.intellij.ide.util.PropertiesComponent;
import com.intellij.idea.ActionsBundle;
import com.intellij.openapi.actionSystem.ActionManager;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.ui.components.labels.LinkLabel;
import com.intellij.ui.components.labels.LinkListener;
/**
* User: anna
*/
public abstract class TextFieldAction extends LinkLabel implements LinkListener {
public TextFieldAction() {
super("", null);
setListener(this, null);
update();
}
protected void onSetActive(final boolean active) {
final String tooltip = AnAction
.createTooltipText(ActionsBundle.message("action.FileChooser.TogglePathShowing.text"),
ActionManager.getInstance().getAction("FileChooser.TogglePathShowing"));
setToolTipText(tooltip);
}
protected String getStatusBarText() {
return ActionsBundle.message("action.FileChooser.TogglePathShowing.text");
}
public void update() {
setVisible(true);
setText(PropertiesComponent.getInstance().getBoolean(FileChooserDialogImpl.FILE_CHOOSER_SHOW_PATH_PROPERTY, true) ? IdeBundle.message("file.chooser.hide.path") : IdeBundle.message("file.chooser.show.path"));
}
}
@@ -131,7 +131,7 @@ ide.mac.hide.cursor.when.typing=true
ide.mac.show.native.help=true
ide.mac.useNativeClipboard=false
ide.mac.boldEditorTabs=false
ide.mac.modalDialogsOnFullscreen=true
ide.mac.modalDialogsOnFullscreen=false
# suppress inspection "UnusedProperty"
ide.mac.modalDialogsOnFullscreen.description=New modality approach. All dialogs are DOCUMENT_MODAL expect ide-wide dialogs
@@ -215,6 +215,7 @@ documentation.component.editor.font=false
find.usage.expand.all=false
ide.completion.show.all.classes=false
ide.completion.show.better.matching.classes=false
ide.completion.middle.matching=true
# suppress inspection "UnusedProperty"
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2012 JetBrains s.r.o.
* 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.
@@ -67,7 +67,7 @@ public class FileDocumentManagerImplTest extends PlatformLiteFixture {
MockEditorFactory editorFactory = new MockEditorFactory();
getApplication().registerService(EditorFactory.class, editorFactory);
final LanguageFileType[] fileType = {null};
getApplication().addComponent(FileTypeManager.class, new FileTypeManagerImpl(null, new MockSchemesManagerFactory()){
getApplication().addComponent(FileTypeManager.class, new FileTypeManagerImpl(null, new MockSchemesManagerFactory()) {
@NotNull
@Override
public FileType getFileTypeByFileName(@NotNull String fileName) {
@@ -174,8 +174,8 @@ public class FileDocumentManagerImplTest extends PlatformLiteFixture {
final Document[] unsavedDocuments = myDocumentManager.getUnsavedDocuments();
assertEquals(1, unsavedDocuments.length);
assertSame(document, unsavedDocuments[0]);
assertTrue(Arrays.equals("test".getBytes(), file.contentsToByteArray()));
assertSame(document, unsavedDocuments[0]);
assertTrue(Arrays.equals("test".getBytes("UTF-8"), file.contentsToByteArray()));
}
public void testGetUnsavedDocuments_afterSaveAllDocuments() throws Exception {
@@ -200,10 +200,6 @@ public class FileDocumentManagerImplTest extends PlatformLiteFixture {
assertEquals(0, unsavedDocuments.length);
}
private static MockVirtualFile newTextFile() {
return new MockVirtualFile("test.txt", "test");
}
public void testGetUnsavedDocuments_afterSaveDocumentWithProblems() throws Exception {
final VirtualFile file = new MockVirtualFile("test.txt", "test") {
@Override
@@ -223,8 +219,8 @@ public class FileDocumentManagerImplTest extends PlatformLiteFixture {
final Document[] unsavedDocuments = myDocumentManager.getUnsavedDocuments();
assertEquals(1, unsavedDocuments.length);
assertSame(document, unsavedDocuments[0]);
assertTrue(Arrays.equals("test".getBytes(), file.contentsToByteArray()));
assertSame(document, unsavedDocuments[0]);
assertTrue(Arrays.equals("test".getBytes("UTF-8"), file.contentsToByteArray()));
}
public void testUnsavedDocument_DoNotGC() throws Exception {
@@ -275,12 +271,12 @@ public class FileDocumentManagerImplTest extends PlatformLiteFixture {
final long stamp = file.getModificationStamp();
Document document = myDocumentManager.getDocument(file);
assertNotNull(file.toString(), document);
document.insertString(0, "xxx");
document.insertString(0, "xxx ");
myDocumentManager.saveDocument(document);
assertTrue(stamp != file.getModificationStamp());
assertEquals(document.getModificationStamp(), file.getModificationStamp());
assertTrue(Arrays.equals("xxxtest".getBytes(), file.contentsToByteArray()));
assertTrue(Arrays.equals("xxx test".getBytes("UTF-8"), file.contentsToByteArray()));
}
public void testSaveAllDocuments_DocumentWasChanged() throws Exception {
@@ -288,11 +284,11 @@ public class FileDocumentManagerImplTest extends PlatformLiteFixture {
final long stamp = file.getModificationStamp();
Document document = myDocumentManager.getDocument(file);
assertNotNull(file.toString(), document);
document.insertString(0, "xxx");
document.insertString(0, "xxx ");
myDocumentManager.saveAllDocuments();
assertTrue(stamp != file.getModificationStamp());
assertTrue(Arrays.equals("xxxtest".getBytes(), file.contentsToByteArray()));
assertTrue(Arrays.equals("xxx test".getBytes("UTF-8"), file.contentsToByteArray()));
}
public void testGetFile() throws Exception {
@@ -313,9 +309,9 @@ public class FileDocumentManagerImplTest extends PlatformLiteFixture {
final VirtualFile file = new MockVirtualFile("test.txt", "test\rtest");
Document document = myDocumentManager.getDocument(file);
assertNotNull(file.toString(), document);
document.insertString(0, "xxx");
document.insertString(0, "xxx ");
myDocumentManager.saveAllDocuments();
assertTrue(Arrays.equals("xxxtest\rtest".getBytes(), file.contentsToByteArray()));
assertTrue(Arrays.equals("xxx test\rtest".getBytes("UTF-8"), file.contentsToByteArray()));
}
public void testContentChanged_noDocument() throws Exception {
@@ -391,12 +387,12 @@ public class FileDocumentManagerImplTest extends PlatformLiteFixture {
}
}
public void testContentChanged_dontreloadChangedDocument() throws Exception {
public void testContentChanged_DoNotReloadChangedDocument() throws Exception {
final MockVirtualFile file = newTextFile();
file.setListener(myDocumentManager);
Document document = myDocumentManager.getDocument(file);
assertNotNull(file.toString(), document);
document.insertString(0, "zzz");
document.insertString(0, "old ");
myDocumentManager.myReloadFromDisk = Boolean.FALSE;
try {
@@ -404,7 +400,7 @@ public class FileDocumentManagerImplTest extends PlatformLiteFixture {
file.setContent(null, "xxx", true);
assertEquals("zzztest", document.getText());
assertEquals("old test", document.getText());
assertEquals(oldDocumentStamp, document.getModificationStamp());
}
finally {
@@ -412,7 +408,7 @@ public class FileDocumentManagerImplTest extends PlatformLiteFixture {
}
}
public void testSaveDocument_dontSaveIfModStampEqualsToFile() throws Exception {
public void testSaveDocument_DoNotSaveIfModStampEqualsToFile() throws Exception {
final VirtualFile file = new MockVirtualFile("test.txt", "test") {
@NotNull
@Override
@@ -475,16 +471,16 @@ public class FileDocumentManagerImplTest extends PlatformLiteFixture {
try {
Document document = myDocumentManager.getDocument(file);
assertNotNull(file.toString(), document);
document.insertString(0, "zzz");
document.insertString(0, "old ");
long documentStamp = document.getModificationStamp();
file.setContent(null, "xxx", false);
myDocumentManager.saveAllDocuments();
assertEquals("zzztest", document.getText());
assertEquals("old test", document.getText());
assertEquals(file.getModificationStamp(), document.getModificationStamp());
assertTrue(Arrays.equals("zzztest".getBytes(), file.contentsToByteArray()));
assertTrue(Arrays.equals("old test".getBytes("UTF-8"), file.contentsToByteArray()));
assertEquals(documentStamp, document.getModificationStamp());
}
finally {
@@ -524,10 +520,8 @@ public class FileDocumentManagerImplTest extends PlatformLiteFixture {
}
}
public void testExternalReplaceWithTheSameText() throws Exception{
public void testExternalReplaceWithTheSameText() throws Exception {
final long[] modificationStamp = new long[1];
modificationStamp[0] = 1;
final VirtualFile file = new MockVirtualFile("test.txt", "test") {
@@ -546,20 +540,20 @@ public class FileDocumentManagerImplTest extends PlatformLiteFixture {
@Override
public void refresh(boolean asynchronous, boolean recursive, Runnable postRunnable) {
myDocumentManager.contentsChanged(new VirtualFileEvent(null, this, null, 1, 2));
}
};
DocumentEx document = (DocumentEx)myDocumentManager.getDocument(file);
modificationStamp[0] = 2;
file.refresh(false, false);
assertNotNull(file.toString(), document);
assertEquals(2, document.getModificationStamp());
}
private static MockVirtualFile newTextFile() {
return new MockVirtualFile("test.txt", "test");
}
private static class MyMockFileDocumentManager extends FileDocumentManagerImpl {
private static final FileDocumentManagerListener[] LISTENERS = new FileDocumentManagerListener[0];
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2012 JetBrains s.r.o.
* 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.
@@ -63,7 +63,8 @@ public abstract class SymlinkTestCase extends LightPlatformLangTestCase {
}
protected void refresh(boolean recursive) {
final VirtualFile tempDir = myFileSystem.findFileByIoFile(myTempDir);
assertTrue(myTempDir.getPath(), myTempDir.isDirectory() || myTempDir.mkdirs());
VirtualFile tempDir = myFileSystem.refreshAndFindFileByIoFile(myTempDir);
assertNotNull(myTempDir.getPath(), tempDir);
tempDir.getChildren();
tempDir.refresh(false, true);
@@ -94,6 +94,7 @@ public class URLUtil {
final ZipEntry zipEntry = zipFile.getEntry(resource);
if (zipEntry == null) throw new FileNotFoundException("Entry " + resource + " not found in " + file);
return new FilterInputStream(zipFile.getInputStream(zipEntry)) {
@Override
public void close() throws IOException {
super.close();
zipFile.close();
@@ -32,6 +32,7 @@ public class AttributeBinding implements Binding {
myAttribute = attribute;
}
@Override
public Object serialize(Object o, Object context, SerializationFilter filter) {
final Object v = myAccessor.read(o);
final Object node = myBinding.serialize(v, context, filter);
@@ -39,6 +40,7 @@ public class AttributeBinding implements Binding {
return new org.jdom.Attribute(myAttribute.value(), ((Content)node).getValue());
}
@Override
@Nullable
public Object deserialize(Object context, @NotNull Object... nodes) {
assert nodes.length == 1;
@@ -52,14 +54,17 @@ public class AttributeBinding implements Binding {
return context;
}
@Override
public boolean isBoundTo(Object node) {
return node instanceof org.jdom.Attribute && ((org.jdom.Attribute)node).getName().equals(myAttribute.value());
}
@Override
public Class getBoundNodeType() {
return org.jdom.Attribute.class;
}
@Override
public void init() {
myBinding = XmlSerializerImpl.getBinding(myAccessor);
if (!Text.class.isAssignableFrom(myBinding.getBoundNodeType())) {
@@ -414,6 +414,7 @@ public class GradleProjectResolver implements ExternalSystemProjectResolver<Grad
final Collection<TaskData> rootProjectTasks = ContainerUtilRt.newArrayList();
final DomainObjectSet<? extends IdeaModule> modules = project.getModules();
for (IdeaModule module : modules) {
String moduleConfigPath = GradleUtil.getConfigPath(module.getGradleProject(), rootProjectPath);
for (GradleTask task : module.getGradleProject().getTasks()) {
String name = task.getName();
if (name == null || name.trim().isEmpty()) {
@@ -425,7 +426,6 @@ public class GradleProjectResolver implements ExternalSystemProjectResolver<Grad
continue;
}
String moduleConfigPath = GradleUtil.getConfigPath(module.getGradleProject(), rootProjectPath);
TaskData taskData = new TaskData(GradleConstants.SYSTEM_ID, name, moduleConfigPath, task.getDescription());
if (rootProjectPath.equals(moduleConfigPath)) {
@@ -16,6 +16,7 @@
package org.jetbrains.plugins.groovy.lang.completion;
import com.intellij.codeInsight.completion.*;
import com.intellij.codeInsight.completion.impl.BetterPrefixMatcher;
import com.intellij.codeInsight.completion.impl.CamelHumpMatcher;
import com.intellij.codeInsight.lookup.AutoCompletionPolicy;
import com.intellij.codeInsight.lookup.LookupElement;
@@ -48,9 +49,9 @@ public class GroovyNoVariantsDelegator extends CompletionContributor {
}
@Override
public void fillCompletionVariants(final CompletionParameters parameters, final CompletionResultSet result) {
final boolean empty = JavaNoVariantsDelegator.containsOnlyPackages(result.runRemainingContributors(parameters, true)) ||
suggestMetaAnnotations(parameters);
public void fillCompletionVariants(final CompletionParameters parameters, CompletionResultSet result) {
LinkedHashSet<CompletionResult> plainResults = result.runRemainingContributors(parameters, true);
final boolean empty = JavaNoVariantsDelegator.containsOnlyPackages(plainResults) || suggestMetaAnnotations(parameters);
if (!empty && parameters.getInvocationCount() == 0) {
result.restartCompletionWhenNothingMatches();
@@ -58,11 +59,15 @@ public class GroovyNoVariantsDelegator extends CompletionContributor {
if (empty) {
delegate(parameters, result);
} else if (Registry.is("ide.completion.show.all.classes")) {
} else if (Registry.is("ide.completion.show.all.classes") || Registry.is("ide.completion.show.better.matching.classes")) {
if (parameters.getInvocationCount() <= 1 &&
JavaCompletionContributor.mayStartClassName(result) &&
GroovyCompletionContributor.isClassNamePossible(parameters.getPosition()) &&
!MapArgumentCompletionProvider.isMapKeyCompletion(parameters)) {
if (Registry.is("ide.completion.show.better.matching.classes")) {
result = result.withPrefixMatcher(new BetterPrefixMatcher(result.getPrefixMatcher(), BetterPrefixMatcher.getBestMatchingDegree(plainResults)));
}
suggestNonImportedClasses(parameters, result);
}
}
@@ -29,7 +29,6 @@ import org.jetbrains.idea.maven.dom.intentions.ChooseFileIntentionAction;
import org.jetbrains.idea.maven.dom.model.MavenDomDependency;
import org.jetbrains.idea.maven.dom.model.MavenDomProjectModel;
import java.io.File;
import java.util.Arrays;
import java.util.List;
@@ -668,7 +667,7 @@ public class MavenDependencyCompletionAndResolutionTest extends MavenDomWithIndi
" </dependency>" +
"</dependencies>");
assertCompletionVariants(myProjectPom, "jar", "test-jar", "pom", "ear", "ejb", "ejb-client", "war", "bundle", "jboss-har", "jboss-sar");
assertCompletionVariants(myProjectPom, "jar", "test-jar", "pom", "ear", "ejb", "ejb-client", "war", "bundle", "jboss-har", "jboss-sar", "maven-plugin");
}
public void testDoNotHighlightUnknownType() throws Throwable {
@@ -58,29 +58,29 @@ public class LoadContextAction extends BaseTaskAction {
DefaultActionGroup group = new DefaultActionGroup();
final WorkingContextManager manager = WorkingContextManager.getInstance(project);
List<ContextInfo> history = manager.getContextHistory();
List<ContextHolder> infos = ContainerUtil.map2List(history, new Function<ContextInfo, ContextHolder>() {
List<ContextHolder> infos = new ArrayList<ContextHolder>(ContainerUtil.map2List(history, new Function<ContextInfo, ContextHolder>() {
public ContextHolder fun(final ContextInfo info) {
return new ContextHolder() {
@Override
void load(final boolean clear) {
LoadContextUndoableAction undoableAction = LoadContextUndoableAction.createAction(manager, clear, info.name);
UndoableCommand.execute(project, undoableAction, "Load context " + info.comment, "Context");
}
@Override
void load(final boolean clear) {
LoadContextUndoableAction undoableAction = LoadContextUndoableAction.createAction(manager, clear, info.name);
UndoableCommand.execute(project, undoableAction, "Load context " + info.comment, "Context");
}
@Override
void remove() {
manager.removeContext(info.name);
}
@Override
void remove() {
manager.removeContext(info.name);
}
@Override
Date getDate() {
return new Date(info.date);
}
@Override
Date getDate() {
return new Date(info.date);
}
@Override
String getComment() {
return info.comment;
}
@Override
String getComment() {
return info.comment;
}
@Override
Icon getIcon() {
@@ -88,7 +88,7 @@ public class LoadContextAction extends BaseTaskAction {
}
};
}
});
}));
final TaskManager taskManager = TaskManager.getManager(project);
List<LocalTask> tasks = taskManager.getLocalTasks();
infos.addAll(ContainerUtil.mapNotNull(tasks, new NullableFunction<LocalTask, ContextHolder>() {
@@ -131,7 +131,7 @@ public class LoadContextAction extends BaseTaskAction {
return o2.getDate().compareTo(o1.getDate());
}
});
final Ref<Boolean> shiftPressed = Ref.create(false);
boolean today = true;
Calendar now = Calendar.getInstance();
@@ -166,7 +166,7 @@ public class LoadContextAction extends BaseTaskAction {
});
popup.registerAction("invoke", KeyStroke.getKeyStroke("shift ENTER"), new AbstractAction() {
public void actionPerformed(ActionEvent e) {
popup.handleSelect(true);
popup.handleSelect(true);
}
});
popup.addPopupListener(new JBPopupAdapter() {
@@ -215,12 +215,12 @@ public class MantisRepository extends BaseRepositoryImpl {
final MantisConnectPortType soap = createSoap();
myProjects = new ArrayList<MantisProject>();
ProjectData[] projectDatas = soap.mc_projects_get_user_accessible(getUsername(), getPassword());
List<MantisProject> projects = ContainerUtil.map(projectDatas, new Function<ProjectData, MantisProject>() {
List<MantisProject> projects = new ArrayList<MantisProject>(ContainerUtil.map(projectDatas, new Function<ProjectData, MantisProject>() {
@Override
public MantisProject fun(final ProjectData data) {
return new MantisProject(data.getId().intValue(), data.getName());
}
});
}));
if (allProjectsAvailable(soap)){
projects.add(0, MantisProject.ALL_PROJECTS);
}
@@ -3,12 +3,14 @@ aggregator
ajax
alloc
anyschema
aopalliance
appender
archivelog
args
arial
arity
asensitive
aspectj
attr
attlist
auth
@@ -50,6 +52,7 @@ capath
captcha
ccflags
cdata
cglib
changelist
charset
checkbox
@@ -133,6 +136,7 @@ foreach
formatter
freelist
freelists
freemarker
freepools
frontend
ftlvariable
@@ -140,6 +144,7 @@ fulltext
func
fxml
gdata
gemfire
geocode
geometrycollection
getters
@@ -247,6 +252,7 @@ minvalue
miny
mixin
mlslabel
mongodb
monospaced
multi
multilinestring
@@ -356,6 +362,7 @@ rebase
rebased
rebasing
rect
redis
redistributions
refactor
refactored
@@ -401,6 +408,7 @@ serializers
servererror
servlet
servlets
sftp
shader
significand
significands
@@ -457,6 +465,7 @@ tokenize
tokenizer
tooltip
tooltips
toplink
trebuchet
twitter
typedef
@@ -95,11 +95,12 @@ public class ComboControl extends BaseModifiableControl<JComboBox, String> {
};
final ResolvingConverter resolvingConverter = (ResolvingConverter)converter;
final Collection<Object> variants = resolvingConverter.getVariants(context);
final List<Pair<String, Icon>> all = ContainerUtil.map(variants, new Function<Object, Pair<String, Icon>>() {
public Pair<String, Icon> fun(final Object s) {
return Pair.create(ElementPresentationManager.getElementName(s), ElementPresentationManager.getIcon(s));
}
});
final List<Pair<String, Icon>> all =
new ArrayList<Pair<String, Icon>>(ContainerUtil.map(variants, new Function<Object, Pair<String, Icon>>() {
public Pair<String, Icon> fun(final Object s) {
return Pair.create(ElementPresentationManager.getElementName(s), ElementPresentationManager.getIcon(s));
}
}));
all.addAll(ContainerUtil.map(resolvingConverter.getAdditionalVariants(context), new Function() {
public Object fun(final Object s) {
return new Pair(s, null);
@@ -58,8 +58,7 @@ public class WebBrowserServiceImpl extends WebBrowserService {
WebBrowserUrlProvider provider = getProvider(psiElement);
if (provider != null) {
try {
// I (develar) don't want to change API right now, so, just wrap result
return Urls.newFromIdea(provider.getUrl(psiElement, psiFile, virtualFile));
return provider.getUrl(psiElement, psiFile, virtualFile);
}
catch (WebBrowserUrlProvider.BrowserException e) {
if (!HtmlUtil.isHtmlFile(psiFile)) {
@@ -71,29 +70,30 @@ public class WebBrowserServiceImpl extends WebBrowserService {
return Urls.newFromVirtualFile(virtualFile);
}
@Override
@Nullable
public Url getUrlToOpen(@NotNull PsiElement psiElement) {
try {
return getUrlToOpen(psiElement, false);
}
catch (WebBrowserUrlProvider.BrowserException e) {
catch (WebBrowserUrlProvider.BrowserException ignored) {
return null;
}
}
@Nullable
public static WebBrowserUrlProvider getProvider(@Nullable PsiElement element) {
if (element == null) {
PsiFile psiFile = element == null ? null : element.getContainingFile();
if (psiFile == null) {
return null;
}
final List<WebBrowserUrlProvider> allProviders = Arrays.asList(WebBrowserUrlProvider.EP_NAME.getExtensions());
List<WebBrowserUrlProvider> allProviders = Arrays.asList(WebBrowserUrlProvider.EP_NAME.getExtensions());
for (WebBrowserUrlProvider urlProvider : DumbService.getInstance(element.getProject()).filterByDumbAwareness(allProviders)) {
if (urlProvider.canHandleElement(element)) {
if (urlProvider.canHandleElement(element, psiFile)) {
return urlProvider;
}
}
return null;
}
}
@@ -249,10 +249,12 @@ public class HtmlUtil {
if (customName.length() == 0) continue;
descriptors[index++] = new XmlAttributeDescriptorImpl() {
@Override
public String getName(PsiElement context) {
return customName;
}
@Override
public String getName() {
return customName;
}
@@ -275,14 +277,17 @@ public class HtmlUtil {
if (tagName.length() == 0) continue;
descriptors[index++] = new XmlElementDescriptorImpl(context instanceof XmlTag ? (XmlTag)context : null) {
@Override
public String getName(PsiElement context) {
return tagName;
}
@Override
public String getDefaultName() {
return tagName;
}
@Override
public boolean allowElementsFromNamespace(final String namespace, final XmlTag context) {
return true;
}
@@ -340,10 +345,12 @@ public class HtmlUtil {
descriptors = ArrayUtil.append(
descriptors,
new XmlAttributeDescriptorImpl() {
@Override
public String getName(PsiElement context) {
return JSFC;
}
@Override
public String getName() {
return JSFC;
}
@@ -454,6 +461,7 @@ public class HtmlUtil {
public static void processInjectedContent(final XmlTag element,
@NotNull final Processor<XmlTag> tagProcessor) {
final PsiLanguageInjectionHost.InjectedPsiVisitor injectedPsiVisitor = new PsiLanguageInjectionHost.InjectedPsiVisitor() {
@Override
public void visit(@NotNull PsiFile injectedPsi, @NotNull List<PsiLanguageInjectionHost.Shred> places) {
if (injectedPsi instanceof XmlFile) {
final XmlDocument injectedDocument = ((XmlFile)injectedPsi).getDocument();
@@ -508,12 +516,14 @@ public class HtmlUtil {
@NonNls final Set<String> inTag = new THashSet<String>();
boolean metHttpEquiv = false;
@Override
public void doctype(@Nullable final CharSequence publicId,
@Nullable final CharSequence systemId,
final int startOffset,
final int endOffset) {
}
@Override
public ProcessingOrder startTag(final CharSequence localName, final String namespace, final int startoffset, final int endoffset,
final int headerEndOffset) {
@NonNls String name = localName.toString().toLowerCase();
@@ -526,6 +536,7 @@ public class HtmlUtil {
throw TerminateException.INSTANCE;
}
@Override
public void endTag(final CharSequence localName, final String namespace, final int startoffset, final int endoffset) {
@NonNls final String name = localName.toString().toLowerCase();
if ("meta".equals(name) && metHttpEquiv && contentAttributeValue != null) {
@@ -548,6 +559,7 @@ public class HtmlUtil {
private String contentAttributeValue;
@Override
public void attribute(final CharSequence localName, final CharSequence v, final int startoffset, final int endoffset) {
@NonNls final String name = localName.toString().toLowerCase();
if (inTag.contains("meta")) {
@@ -561,20 +573,23 @@ public class HtmlUtil {
}
}
@Override
public void textElement(final CharSequence display, final CharSequence physical, final int startoffset, final int endoffset) {
}
@Override
public void entityRef(final CharSequence ref, final int startOffset, final int endOffset) {
}
@Override
public void error(String message, int startOffset, int endOffset) {
}
});
}
catch (TerminateException e) {
catch (TerminateException ignored) {
//ignore
}
catch (Exception e) {
catch (Exception ignored) {
// some weird things can happen, like unbalanaced tree
}
@@ -22,7 +22,6 @@ import com.intellij.codeInsight.lookup.LookupElement;
import com.intellij.codeInsight.lookup.LookupElementBuilder;
import com.intellij.codeInsight.lookup.LookupElementDecorator;
import com.intellij.codeInsight.lookup.LookupValueWithPriority;
import com.intellij.openapi.actionSystem.LangDataKeys;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.wm.WindowManager;
import com.intellij.psi.PsiElement;
@@ -30,7 +29,10 @@ import com.intellij.psi.xml.XmlToken;
import com.intellij.ui.ColorChooser;
import com.intellij.ui.ColorPickerListener;
import com.intellij.ui.ColorPickerListenerFactory;
import com.intellij.ui.ColorUtil;
import com.intellij.util.Function;
import com.intellij.xml.XmlBundle;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.awt.*;
@@ -40,18 +42,28 @@ import java.awt.*;
*/
public class UserColorLookup extends LookupElementDecorator<LookupElement> {
private static final String COLOR_STRING = XmlBundle.message("choose.color.in.color.lookup");
private static final Function<Color,String> COLOR_TO_STRING_CONVERTER = new Function<Color, String>() {
@Override
public String fun(Color color) {
return '#' + ColorUtil.toHex(color);
}
};
public UserColorLookup() {
this(COLOR_TO_STRING_CONVERTER);
}
public UserColorLookup(final Function<Color, String> colorToStringConverter) {
super(PrioritizedLookupElement.withPriority(LookupElementBuilder.create(COLOR_STRING).withInsertHandler(
new InsertHandler<LookupElement>() {
@Override
public void handleInsert(InsertionContext context, LookupElement item) {
handleUserSelection(context);
handleUserSelection(context, colorToStringConverter);
}
}), LookupValueWithPriority.HIGH));
}
private static void handleUserSelection(InsertionContext context) {
private static void handleUserSelection(InsertionContext context, @NotNull Function<Color, String> colorToStringConverter) {
Color myColorAtCaret = null;
Editor selectedTextEditor = context.getEditor();
@@ -68,16 +80,8 @@ public class UserColorLookup extends LookupElementDecorator<LookupElement> {
XmlBundle.message("choose.color.dialog.title"), myColorAtCaret, true, listeners, true);
if (color != null) {
String s = Integer.toHexString(color.getRGB() & 0xFFFFFF);
if (s.length() != 6) {
StringBuilder buf = new StringBuilder(s);
for (int i = 6 - buf.length(); i > 0; --i) {
buf.insert(0, '0');
}
s = buf.toString();
}
s = "#" + s;
context.getDocument().insertString(context.getStartOffset(), s);
String colorString = colorToStringConverter.fun(color);
context.getDocument().insertString(context.getStartOffset(), colorString);
context.getEditor().getCaretModel().moveToOffset(context.getTailOffset());
}
}
@@ -33,17 +33,13 @@ public abstract class WebBrowserUrlProvider {
super(message);
}
}
@NotNull
/**
* URL must not be encoded (space as is)
*/
public abstract String getUrl(@NotNull PsiElement element, @NotNull PsiFile psiFile, @NotNull VirtualFile virtualFile) throws BrowserException;
/**
* Invariant: element has not null containing psi file with not null virtual file
*/
public abstract boolean canHandleElement(@NotNull final PsiElement element);
public abstract boolean canHandleElement(@NotNull PsiElement element, @NotNull PsiFile psiFile);
@NotNull
public abstract Url getUrl(@NotNull PsiElement element, @NotNull PsiFile psiFile, @NotNull VirtualFile virtualFile) throws BrowserException;
@Nullable
public String getOpenInBrowserActionText(@NotNull PsiFile file) {