Merge remote-tracking branch 'origin/master'

This commit is contained in:
Konstantin Bulenkov
2012-09-11 16:17:15 +04:00
32 changed files with 488 additions and 252 deletions
@@ -83,6 +83,9 @@ public class AddTypeCastFix extends LocalQuickFixAndIntentionActionOnPsiElement
static PsiExpression createCastExpression(PsiExpression originalExpression, Project project, PsiType type) throws IncorrectOperationException {
// remove nested casts
PsiElement element = PsiUtil.deparenthesizeExpression(originalExpression);
if (element == null){
return null;
}
PsiElementFactory factory = JavaPsiFacade.getInstance(originalExpression.getProject()).getElementFactory();
PsiTypeCastExpression typeCast = (PsiTypeCastExpression)factory.createExpressionFromText("(Type)value", null);
@@ -21,6 +21,7 @@ import com.intellij.lang.Language;
import com.intellij.openapi.vfs.VirtualFile;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.lang.ref.SoftReference;
@@ -31,23 +32,27 @@ public class PsiInvalidElementAccessException extends RuntimeException {
private final SoftReference<PsiElement> myElementReference; // to prevent leaks, since exceptions are stored in IdeaLogger
public PsiInvalidElementAccessException(PsiElement element) {
this(element, null, null);
this(element, (String)null);
}
public PsiInvalidElementAccessException(PsiElement element, String message) {
this(element, message, null);
public PsiInvalidElementAccessException(PsiElement element, @Nullable String message) {
this(element, getMessageWithReason(element, message), null);
}
public PsiInvalidElementAccessException(PsiElement element, Throwable cause) {
this(element, null, cause);
public PsiInvalidElementAccessException(PsiElement element, @Nullable Throwable cause) {
this(element, getMessageWithReason(element, null), cause);
}
public PsiInvalidElementAccessException(PsiElement element, String message, Throwable cause) {
super((element != null ? "Element: " + element.getClass() + " because: " + reason(element) : "Unknown psi element") +
(message == null ? "" : "; " + message), cause);
public PsiInvalidElementAccessException(PsiElement element, @Nullable String message, @Nullable Throwable cause) {
super(message, cause);
myElementReference = new SoftReference<PsiElement>(element);
}
private static String getMessageWithReason(@Nullable PsiElement element, @Nullable String message) {
return (element != null ? "Element: " + element.getClass() + " because: " + reason(element) : "Unknown psi element") +
(message == null ? "" : "; " + message);
}
@NonNls
@NotNull
private static String reason(@NotNull PsiElement root){
@@ -71,6 +76,7 @@ public class PsiInvalidElementAccessException extends RuntimeException {
return "psi is outdated";
}
@Nullable
public PsiElement getPsiElement() {
return myElementReference.get();
}
@@ -144,7 +144,7 @@ public class StubBasedPsiElementBase<T extends StubElement> extends ASTDelegateP
}
PsiFile psi = (PsiFile)stub.getPsi();
if (psi == null) {
throw new PsiInvalidElementAccessException(this);
throw new PsiInvalidElementAccessException(this, "no psi for file stub " + stub, null);
}
return psi;
}
@@ -16,6 +16,7 @@
package com.intellij.codeEditor.printing;
import com.intellij.CommonBundle;
import com.intellij.ide.highlighter.HighlighterFactory;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.actionSystem.LangDataKeys;
@@ -28,12 +29,14 @@ import com.intellij.openapi.editor.highlighter.EditorHighlighter;
import com.intellij.openapi.fileTypes.FileTypes;
import com.intellij.openapi.progress.*;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.Messages;
import com.intellij.psi.PsiDirectory;
import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import java.awt.print.*;
import java.util.ArrayList;
import java.util.Collections;
@@ -151,8 +154,14 @@ class PrintManager {
printerJob.print();
}
catch(PrinterException e) {
LOG.error(e);
catch(final PrinterException e) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
Messages.showErrorDialog(project, e.getMessage(), CommonBundle.getErrorTitle());
}
});
LOG.info(e);
}
catch(ProcessCanceledException e) {
printerJob.cancel();
@@ -25,14 +25,9 @@ import com.intellij.openapi.editor.actionSystem.EditorActionHandler;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiWhiteSpace;
import com.intellij.psi.*;
import com.intellij.util.Processor;
import java.util.List;
public class UnSelectWordHandler extends EditorActionHandler {
private final EditorActionHandler myOriginalHandler;
@@ -59,6 +54,11 @@ public class UnSelectWordHandler extends EditorActionHandler {
private static void doAction(Editor editor, PsiFile file) {
if (file instanceof PsiCompiledFile) {
file = ((PsiCompiledFile)file).getDecompiledPsiFile();
if (file == null) return;
}
if (!editor.getSelectionModel().hasSelection()) {
return;
}
@@ -55,6 +55,7 @@ public final class StructureViewFactoryImpl extends StructureViewFactoryEx imple
@SuppressWarnings({"WeakerAccess"}) public boolean AUTOSCROLL_MODE = true;
@SuppressWarnings({"WeakerAccess"}) public boolean AUTOSCROLL_FROM_SOURCE = false;
@SuppressWarnings({"WeakerAccess"}) public String ACTIVE_ACTIONS = "";
public boolean SHOW_TOOLBAR = false;
}
private final Project myProject;
@@ -85,6 +86,7 @@ public final class StructureViewFactoryImpl extends StructureViewFactoryEx imple
return myStructureViewWrapperImpl;
}
@NotNull
public State getState() {
return myState;
}
@@ -154,6 +154,10 @@ public class StructureViewComponent extends SimpleToolWindowPanel implements Tre
myAutoScrollToSourceHandler = new MyAutoScrollToSourceHandler();
myAutoScrollFromSourceHandler = new MyAutoScrollFromSourceHandler(myProject, this);
if (getSettings().SHOW_TOOLBAR) {
setToolbar(createToolbar());
}
installTree();
myCopyPasteDelegator = new CopyPasteDelegator(myProject, getTree()) {
@@ -164,6 +168,10 @@ public class StructureViewComponent extends SimpleToolWindowPanel implements Tre
};
}
private JComponent createToolbar() {
return ActionManager.getInstance().createActionToolbar(ActionPlaces.STRUCTURE_VIEW_TOOLBAR, createActionGroup(), true).getComponent();
}
private void installTree() {
getTree().getSelectionModel().setSelectionMode(TreeSelectionModel.DISCONTIGUOUS_TREE_SELECTION);
myAutoScrollToSourceHandler.install(getTree());
@@ -367,7 +375,24 @@ public class StructureViewComponent extends SimpleToolWindowPanel implements Tre
}
public ActionGroup getGearActions() {
return createActionGroup(true);
DefaultActionGroup group = createActionGroup(true);
group.addAction(new ToggleAction("Show Toolbar") {
@Override
public boolean isSelected(AnActionEvent e) {
return getSettings().SHOW_TOOLBAR;
}
@Override
public void setSelected(AnActionEvent e, boolean state) {
setToolbar(state ? createToolbar() : null);
getSettings().SHOW_TOOLBAR = state;
}
}).setAsSecondary(true);
return group;
}
private StructureViewFactoryImpl.State getSettings() {
return ((StructureViewFactoryImpl)StructureViewFactory.getInstance(myProject)).getState();
}
public AnAction[] getTitleActions() {
@@ -381,7 +406,7 @@ public class StructureViewComponent extends SimpleToolWindowPanel implements Tre
return createActionGroup(false);
}
protected ActionGroup createActionGroup(boolean togglesOnly) {
protected DefaultActionGroup createActionGroup(boolean togglesOnly) {
DefaultActionGroup result = new DefaultActionGroup();
Sorter[] sorters = myTreeModel.getSorters();
for (final Sorter sorter : sorters) {
@@ -522,9 +547,7 @@ public class StructureViewComponent extends SimpleToolWindowPanel implements Tre
return;
}
StructureViewFactoryImpl structureViewFactory = (StructureViewFactoryImpl)StructureViewFactoryEx.getInstance(myProject);
if (!structureViewFactory.getState().AUTOSCROLL_FROM_SOURCE) {
if (!getSettings().AUTOSCROLL_FROM_SOURCE) {
return;
}
@@ -612,11 +635,11 @@ public class StructureViewComponent extends SimpleToolWindowPanel implements Tre
protected boolean isAutoScrollMode() {
return myShouldAutoScroll && !myProject.isDisposed()
&& ((StructureViewFactoryImpl)StructureViewFactory.getInstance(myProject)).getState().AUTOSCROLL_MODE;
&& getSettings().AUTOSCROLL_MODE;
}
protected void setAutoScrollMode(boolean state) {
((StructureViewFactoryImpl)StructureViewFactory.getInstance(myProject)).getState().AUTOSCROLL_MODE = state;
getSettings().AUTOSCROLL_MODE = state;
}
protected void scrollToSource(Component tree) {
@@ -659,13 +682,11 @@ public class StructureViewComponent extends SimpleToolWindowPanel implements Tre
}
protected boolean isAutoScrollEnabled() {
StructureViewFactoryImpl structureViewFactory = (StructureViewFactoryImpl)StructureViewFactory.getInstance(myProject);
return structureViewFactory.getState().AUTOSCROLL_FROM_SOURCE;
return getSettings().AUTOSCROLL_FROM_SOURCE;
}
protected void setAutoScrollEnabled(boolean state) {
StructureViewFactoryImpl structureViewFactory = (StructureViewFactoryImpl)StructureViewFactory.getInstance(myProject);
structureViewFactory.getState().AUTOSCROLL_FROM_SOURCE = state;
getSettings().AUTOSCROLL_FROM_SOURCE = state;
final FileEditor[] selectedEditors = FileEditorManager.getInstance(myProject).getSelectedEditors();
if (selectedEditors.length > 0 && state) {
scrollToSelectedElement();
@@ -4,7 +4,6 @@ package com.intellij.openapi.paths;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.ElementManipulator;
import com.intellij.psi.ElementManipulators;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiReference;
@@ -21,9 +20,7 @@ public abstract class PathReferenceProviderBase implements PathReferenceProvider
public boolean createReferences(@NotNull final PsiElement psiElement, final @NotNull List<PsiReference> references, final boolean soft) {
final ElementManipulator<PsiElement> manipulator = ElementManipulators.getManipulator(psiElement);
assert manipulator != null;
final TextRange range = manipulator.getRangeInElement(psiElement);
final TextRange range = ElementManipulators.getValueTextRange(psiElement);
int offset = range.getStartOffset();
int endOffset = range.getEndOffset();
final String elementText = psiElement.getText();
@@ -74,13 +74,18 @@ public class SimpleToolWindowPanel extends JPanel implements QuickActionProvider
});
}
public void setToolbar(JComponent c) {
public void setToolbar(@Nullable JComponent c) {
if (c == null) {
remove(myToolbar);
}
myToolbar = c;
if (myVertical) {
add(c, BorderLayout.NORTH);
} else {
add(c, BorderLayout.WEST);
if (c != null) {
if (myVertical) {
add(c, BorderLayout.NORTH);
} else {
add(c, BorderLayout.WEST);
}
}
revalidate();
@@ -754,7 +754,7 @@ public final class TreeUtil {
@NotNull
public static ArrayList<TreeNode> childrenToArray(@NotNull final TreeNode node) {
ApplicationManager.getApplication().assertIsDispatchThread();
//ApplicationManager.getApplication().assertIsDispatchThread();
final ArrayList<TreeNode> result = new ArrayList<TreeNode>();
for(int i = 0; i < node.getChildCount(); i++){
TreeNode child = node.getChildAt(i);
@@ -39,6 +39,7 @@ import com.intellij.openapi.editor.ex.EditorSettingsExternalizable;
import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.fileChooser.FileChooserFactory;
import com.intellij.openapi.fileChooser.FileSaverDescriptor;
import com.intellij.openapi.fileChooser.FileSaverDialog;
import com.intellij.openapi.fileEditor.*;
import com.intellij.openapi.fileEditor.impl.text.TextEditorImpl;
import com.intellij.openapi.fileTypes.BinaryFileTypeDecompilers;
@@ -430,33 +431,42 @@ public class FileDocumentManagerImpl extends FileDocumentManager implements Appl
@Nullable
private static VirtualFile handleExternalDeletion(VirtualFile file) {
String path = file.getPath();
String[] options = {"Restore", "Save under a different name", "Discard changes"};
int result = suggestToRestoreDeletedFile(path, new String[]{"Restore", "Save under a different name", "Discard changes"});
if (result == 0) return createFile(new File(path));
if (result == 1) return saveUnderDifferentName(file);
return null;
}
@Nullable
private static VirtualFile saveUnderDifferentName(VirtualFile file) {
FileSaverDescriptor descriptor = new FileSaverDescriptor("Save File As...", "Save file under a different name");
FileSaverDialog dialog = FileChooserFactory.getInstance().createSaveFileDialog(descriptor, (Project)null);
VirtualFileWrapper wrapper = dialog.save(findValidParent(file), file.getName());
return wrapper == null ? null : createFile(wrapper.getFile());
}
private static int suggestToRestoreDeletedFile(String path, String[] options) {
String message = "File has been deleted on disk: " + FileUtil.toSystemDependentName(path);
int result = Messages.showDialog(message, "File Deleted", options, 0, Messages.getQuestionIcon());
File newFile;
if (result == 0) {
newFile = new File(path);
} else if (result == 1) {
VirtualFile validParent = file;
while (validParent != null && !validParent.isValid()) {
validParent = validParent.getParent();
}
final VirtualFileWrapper wrapper = FileChooserFactory.getInstance().createSaveFileDialog(
new FileSaverDescriptor("Save File As...", "Save file under a different name"), (Project)null).save(validParent, file.getName());
if (wrapper == null) {
return null;
}
newFile = wrapper.getFile();
} else {
return null;
}
return Messages.showDialog(message, "File Deleted", options, 0, Messages.getQuestionIcon());
}
@Nullable
private static VirtualFile createFile(File newFile) {
if (!FileUtil.createIfDoesntExist(newFile)) {
return null;
}
return LocalFileSystem.getInstance().refreshAndFindFileByIoFile(newFile);
}
@Nullable
private static VirtualFile findValidParent(VirtualFile file) {
VirtualFile validParent = file;
while (validParent != null && !validParent.isValid()) {
validParent = validParent.getParent();
}
return validParent;
}
private static void updateModifiedProperty(@NotNull VirtualFile file) {
for (Project project : ProjectManager.getInstance().getOpenProjects()) {
FileEditorManager fileEditorManager = FileEditorManager.getInstance(project);
@@ -440,6 +440,6 @@
<daemon.changeLocalityDetector implementation="com.intellij.xml.XmlChangeLocalityDetector"/>
</extensions>
<extensions defaultExtensionNs="org.jetbrains">
<urlOpener implementation="com.intellij.ide.browsers.impl.UrlOpenerImpl" order="last"/>
<urlOpener implementation="com.intellij.ide.browsers.impl.DefaultUrlOpener" order="last"/>
</extensions>
</idea-plugin>
@@ -0,0 +1 @@
print <spot>String.class</spot>
@@ -0,0 +1,5 @@
<html>
<body>
This intention removes redundant explicit .class reference.
</body>
</html>
+5
View File
@@ -1178,6 +1178,11 @@
<categoryKey>intention.category.groovy/intention.category.groovy.style</categoryKey>
<className>org.jetbrains.plugins.groovy.intentions.style.ConvertToGeeseBracesIntention</className>
</intentionAction>
<intentionAction>
<bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
<categoryKey>intention.category.groovy/intention.category.groovy.style</categoryKey>
<className>org.jetbrains.plugins.groovy.intentions.style.RemoveRedundantClassPropertyIntention</className>
</intentionAction>
<intentionAction>
<bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
<categoryKey>intention.category.groovy/intention.category.groovy.style</categoryKey>
@@ -173,4 +173,6 @@ remove.unnecessary.escape.characters.intention.family.name=Remove unnecessary es
gr.break.string.on.line.breaks.intention.name=Break string on '\\n'
gr.break.string.on.line.breaks.intention.family.name=Break string on '\\n'
gr.create.missing.switch.branches.intention.name=Create missing 'switch' branches
gr.create.missing.switch.branches.intention.family.name=Create missing 'switch' branches
gr.create.missing.switch.branches.intention.family.name=Create missing 'switch' branches
remove.redundant.class.property.intention.name=Remove redundant .class
remove.redundant.class.property.intention.family.name=Remove redundant .class
@@ -0,0 +1,56 @@
/*
* Copyright 2000-2012 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.plugins.groovy.intentions.style;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiElement;
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.plugins.groovy.intentions.base.Intention;
import org.jetbrains.plugins.groovy.intentions.base.PsiElementPredicate;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression;
/**
* @author Max Medvedev
*/
public class RemoveRedundantClassPropertyIntention extends Intention {
@Override
protected void processIntention(@NotNull PsiElement element, Project project, Editor editor) throws IncorrectOperationException {
if (element instanceof GrReferenceExpression) {
((GrReferenceExpression)element).replaceWithExpression(((GrReferenceExpression)element).getQualifier(), true);
}
}
@NotNull
@Override
protected PsiElementPredicate getElementPredicate() {
return new PsiElementPredicate() {
@Override
public boolean satisfiedBy(PsiElement element) {
if (element instanceof GrReferenceExpression && "class".equals(((GrReferenceExpression)element).getReferenceName())) {
GrExpression qualifier = ((GrReferenceExpression)element).getQualifier();
if (qualifier instanceof GrReferenceExpression) {
return ((GrReferenceExpression)qualifier).resolve() instanceof PsiClass;
}
}
return false;
}
};
}
}
@@ -23,18 +23,16 @@ import gnu.trove.TIntObjectProcedure;
import gnu.trove.TIntProcedure;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.groovy.codeInspection.utils.ControlFlowUtils;
import org.jetbrains.plugins.groovy.lang.psi.GrControlFlowOwner;
import org.jetbrains.plugins.groovy.lang.psi.GroovyFileBase;
import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement;
import org.jetbrains.plugins.groovy.lang.psi.GroovyRecursiveElementVisitor;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrClassInitializer;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrField;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrStatement;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariable;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMember;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod;
import org.jetbrains.plugins.groovy.lang.psi.controlFlow.ControlFlowBuilderUtil;
import org.jetbrains.plugins.groovy.lang.psi.controlFlow.Instruction;
import org.jetbrains.plugins.groovy.lang.psi.controlFlow.ReadWriteVariableInstruction;
@@ -55,19 +53,13 @@ public class ReachingDefinitionsCollector {
@NotNull
public static FragmentVariableInfos obtainVariableFlowInformation(final GrStatement first, final GrStatement last) {
GroovyPsiElement context = PsiTreeUtil.getParentOfType(first, GrMethod.class, GrClosableBlock.class, GroovyFileBase.class, GrClassInitializer.class);
GrControlFlowOwner flowOwner;
if (context instanceof GrMethod) flowOwner = ((GrMethod) context).getBlock();
else flowOwner = (GrControlFlowOwner) context;
GrControlFlowOwner flowOwner = ControlFlowUtils.findControlFlowOwner(first);
assert flowOwner != null;
assert PsiTreeUtil.isAncestor(flowOwner, last, true);
final Instruction[] flow = flowOwner.getControlFlow();
final ReachingDefinitionsDfaInstance dfaInstance = new ReachingDefinitionsDfaInstance(flow);
final ReachingDefinitionsSemilattice lattice = new ReachingDefinitionsSemilattice();
final DFAEngine<DefinitionMap> engine = new DFAEngine<DefinitionMap>(flow, dfaInstance, lattice);
final DefinitionMap dfaResult = postprocess(engine.performForceDFA(), flow, dfaInstance);
final DefinitionMap dfaResult = inferDfaResult(flow);
final LinkedHashSet<Integer> fragmentInstructions = getFragmentInstructions(first, last, flow);
final int[] postorder = ControlFlowBuilderUtil.postorder(flow);
@@ -80,7 +72,7 @@ public class ReachingDefinitionsCollector {
final PsiManager manager = first.getManager();
for (final Integer ref : fragmentReads) {
ReadWriteVariableInstruction rwInstruction = (ReadWriteVariableInstruction) flow[ref];
ReadWriteVariableInstruction rwInstruction = (ReadWriteVariableInstruction)flow[ref];
String name = rwInstruction.getVariableName();
final int[] defs = dfaResult.getDefinitions(ref);
if (!allDefsInFragment(defs, fragmentInstructions)) {
@@ -89,22 +81,22 @@ public class ReachingDefinitionsCollector {
}
for (final Integer ref : reachableFromFragmentReads) {
ReadWriteVariableInstruction rwInstruction = (ReadWriteVariableInstruction) flow[ref];
String name = rwInstruction.getVariableName();
final int[] defs = dfaResult.getDefinitions(ref);
if (anyDefInFragment(defs, fragmentInstructions)) {
for (int def : defs) {
if (fragmentInstructions.contains(def)) {
PsiType outputType = getType(flow[def].getElement());
addVariable(name, omap, manager, outputType);
}
}
if (!allProperDefsInFragment(defs, ref, fragmentInstructions, postorder)) {
PsiType inputType = getType(rwInstruction.getElement());
addVariable(name, imap, manager, inputType);
ReadWriteVariableInstruction rwInstruction = (ReadWriteVariableInstruction)flow[ref];
String name = rwInstruction.getVariableName();
final int[] defs = dfaResult.getDefinitions(ref);
if (anyDefInFragment(defs, fragmentInstructions)) {
for (int def : defs) {
if (fragmentInstructions.contains(def)) {
PsiType outputType = getType(flow[def].getElement());
addVariable(name, omap, manager, outputType);
}
}
if (!allProperDefsInFragment(defs, ref, fragmentInstructions, postorder)) {
PsiType inputType = getType(rwInstruction.getElement());
addVariable(name, imap, manager, inputType);
}
}
}
addClosureUsages(imap, omap, first, last, flowOwner);
@@ -123,14 +115,29 @@ public class ReachingDefinitionsCollector {
};
}
private static void addClosureUsages(final Map<String, VariableInfo> imap, final Map<String, VariableInfo> omap, final GrStatement first, final GrStatement last, GrControlFlowOwner flowOwner) {
private static DefinitionMap inferDfaResult(Instruction[] flow) {
final ReachingDefinitionsDfaInstance dfaInstance = new ReachingDefinitionsDfaInstance(flow);
final ReachingDefinitionsSemilattice lattice = new ReachingDefinitionsSemilattice();
final DFAEngine<DefinitionMap> engine = new DFAEngine<DefinitionMap>(flow, dfaInstance, lattice);
return postprocess(engine.performForceDFA(), flow, dfaInstance);
}
private static void addClosureUsages(final Map<String, VariableInfo> imap,
final Map<String, VariableInfo> omap,
final GrStatement first,
final GrStatement last,
GrControlFlowOwner flowOwner) {
flowOwner.accept(new GroovyRecursiveElementVisitor() {
public void visitClosure(GrClosableBlock closure) {
addUsagesInClosure(imap, omap, closure, first, last);
super.visitClosure(closure);
}
private void addUsagesInClosure(final Map<String, VariableInfo> imap, final Map<String, VariableInfo> omap, final GrClosableBlock closure, final GrStatement first, final GrStatement last) {
private void addUsagesInClosure(final Map<String, VariableInfo> imap,
final Map<String, VariableInfo> omap,
final GrClosableBlock closure,
final GrStatement first,
final GrStatement last) {
closure.accept(new GroovyRecursiveElementVisitor() {
public void visitReferenceExpression(GrReferenceExpression refExpr) {
if (refExpr.isQualified()) {
@@ -140,7 +147,7 @@ public class ReachingDefinitionsCollector {
if (!(resolved instanceof GrVariable)) {
return;
}
GrVariable variable = (GrVariable) resolved;
GrVariable variable = (GrVariable)resolved;
if (PsiTreeUtil.isAncestor(closure, variable, true)) {
return;
}
@@ -169,7 +176,7 @@ public class ReachingDefinitionsCollector {
}
private static void addVariable(String name, Map<String, VariableInfo> map, PsiManager manager, PsiType type) {
VariableInfoImpl info = (VariableInfoImpl) map.get(name);
VariableInfoImpl info = (VariableInfoImpl)map.get(name);
if (info == null) {
info = new VariableInfoImpl(name, manager);
map.put(name, info);
@@ -181,7 +188,7 @@ public class ReachingDefinitionsCollector {
final LinkedHashSet<Integer> result = new LinkedHashSet<Integer>();
for (final Integer i : instructions) {
final Instruction instruction = flow[i];
if (instruction instanceof ReadWriteVariableInstruction && !((ReadWriteVariableInstruction) instruction).isWrite()) {
if (isReadInsn(instruction)) {
result.add(i);
}
}
@@ -215,21 +222,27 @@ public class ReachingDefinitionsCollector {
@Nullable
private static PsiType getType(PsiElement element) {
if (element instanceof GrVariable) return ((GrVariable) element).getTypeGroovy();
else if (element instanceof GrReferenceExpression) return ((GrReferenceExpression) element).getType();
if (element instanceof GrVariable) {
return ((GrVariable)element).getTypeGroovy();
}
else if (element instanceof GrReferenceExpression) return ((GrReferenceExpression)element).getType();
return null;
}
private static VariableInfo[] filterNonlocals(Map<String, VariableInfo> infos, GrStatement place) {
List<VariableInfo> result = new ArrayList<VariableInfo>();
for (Iterator<VariableInfo> iterator = infos.values().iterator(); iterator.hasNext();) {
for (Iterator<VariableInfo> iterator = infos.values().iterator(); iterator.hasNext(); ) {
VariableInfo info = iterator.next();
String name = info.getName();
GroovyPsiElement property = ResolveUtil.resolveProperty(place, name);
if (property instanceof GrVariable) iterator.remove();
if (property instanceof GrVariable) {
iterator.remove();
}
else if (property instanceof GrReferenceExpression) {
GrMember member = PsiTreeUtil.getParentOfType(property, GrMember.class);
if (member == null) continue;
if (member == null) {
continue;
}
else if (!member.hasModifierProperty(PsiModifier.STATIC)) {
if (member.getContainingClass() instanceof GroovyScriptClass) {
//binding variable
@@ -277,20 +290,20 @@ public class ReachingDefinitionsCollector {
return true;
}
private static LinkedHashSet<Integer> getReachable(final LinkedHashSet<Integer> fragmentInsns, final Instruction[] flow, DefinitionMap dfaResult, final int[] postorder) {
private static LinkedHashSet<Integer> getReachable(final LinkedHashSet<Integer> fragmentInsns,
final Instruction[] flow,
final DefinitionMap dfaResult,
final int[] postorder) {
final LinkedHashSet<Integer> result = new LinkedHashSet<Integer>();
for (Instruction insn : flow) {
if (insn instanceof ReadWriteVariableInstruction &&
!((ReadWriteVariableInstruction) insn).isWrite()) {
for (final Instruction insn : flow) {
if (isReadInsn(insn)) {
final int ref = insn.num();
for (int def : dfaResult.getDefinitions(ref)) {
if (fragmentInsns.contains(def)) {
if (!fragmentInsns.contains(ref) || postorder[ref] < postorder[def]) {
result.add(ref);
break;
}
for (final int def : dfaResult.getDefinitions(ref)) {
if (fragmentInsns.contains(def) &&
(!fragmentInsns.contains(ref) || postorder[ref] < postorder[def] && checkPathIsOutsideOfFragment(def, ref, flow, fragmentInsns))) {
result.add(ref);
break;
}
}
}
}
@@ -298,6 +311,60 @@ public class ReachingDefinitionsCollector {
return result;
}
private static boolean checkPathIsOutsideOfFragment(int def, int ref, Instruction[] flow, LinkedHashSet<Integer> fragmentInsns) {
Boolean path = findPath(flow[def], ref, fragmentInsns, false, new HashMap<Instruction, Boolean>());
assert path != null : "def=" + def + ", ref=" + ref;
return path.booleanValue();
}
/**
* return true if path is outside of fragment, null if there is no pathand false if path is inside fragment
*/
@Nullable
private static Boolean findPath(Instruction cur,
int destination,
LinkedHashSet<Integer> fragmentInsns,
boolean wasOutside,
HashMap<Instruction, Boolean> visited) {
wasOutside = wasOutside || !fragmentInsns.contains(cur.num());
visited.put(cur, null);
Iterable<? extends Instruction> instructions = cur.allSuccessors();
boolean pathExists = false;
for (Instruction i : instructions) {
if (i.num() == destination) return wasOutside;
Boolean result;
if (visited.containsKey(i)) {
result = visited.get(i);
}
else {
result = findPath(i, destination, fragmentInsns, wasOutside, visited);
visited.put(i, result);
}
if (result != null) {
if (result.booleanValue()) {
visited.put(cur, true);
return true;
}
pathExists = true;
}
}
if (pathExists) {
visited.put(cur, false);
return false;
}
else {
visited.put(cur, null);
return null;
}
}
private static boolean isReadInsn(Instruction insn) {
return insn instanceof ReadWriteVariableInstruction && !((ReadWriteVariableInstruction)insn).isWrite();
}
@SuppressWarnings({"UnusedDeclaration"})
private static String dumpDfaResult(ArrayList<TIntObjectHashMap<TIntHashSet>> dfaResult, ReachingDefinitionsDfaInstance dfa) {
final StringBuffer buffer = new StringBuffer();
@@ -343,18 +410,21 @@ public class ReachingDefinitionsCollector {
@Nullable
public PsiType getType() {
if (myType instanceof PsiIntersectionType) return ((PsiIntersectionType) myType).getConjuncts()[0];
if (myType instanceof PsiIntersectionType) return ((PsiIntersectionType)myType).getConjuncts()[0];
return myType;
}
void addSubtype(PsiType t) {
if (t != null) {
if (myType == null) myType = t;
if (myType == null) {
myType = t;
}
else {
if (!myType.isAssignableFrom(t)) {
if (t.isAssignableFrom(myType)) {
myType = t;
} else {
}
else {
myType = TypesUtil.getLeastUpperBound(myType, t, myManager);
}
}
@@ -365,13 +435,13 @@ public class ReachingDefinitionsCollector {
@NotNull
private static DefinitionMap postprocess(@NotNull final ArrayList<DefinitionMap> dfaResult,
@NotNull Instruction[] flow,
@NotNull ReachingDefinitionsDfaInstance dfaInstance) {
@NotNull Instruction[] flow,
@NotNull ReachingDefinitionsDfaInstance dfaInstance) {
DefinitionMap result = new DefinitionMap();
for (int i = 0; i < flow.length; i++) {
Instruction insn = flow[i];
if (insn instanceof ReadWriteVariableInstruction) {
ReadWriteVariableInstruction rwInsn = (ReadWriteVariableInstruction) insn;
ReadWriteVariableInstruction rwInsn = (ReadWriteVariableInstruction)insn;
if (!rwInsn.isWrite()) {
int idx = dfaInstance.getVarIndex(rwInsn.getVariableName());
result.copyFrom(dfaResult.get(i), idx, i);
@@ -0,0 +1,81 @@
package org.jetbrains.plugins.groovy
import com.intellij.psi.PsiElement
import com.intellij.psi.util.PsiTreeUtil
import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase
import org.jetbrains.annotations.NotNull
import org.jetbrains.plugins.groovy.lang.psi.GrControlFlowOwner
import org.jetbrains.plugins.groovy.lang.psi.GroovyFile
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrStatement
import org.jetbrains.plugins.groovy.lang.psi.dataFlow.reachingDefs.FragmentVariableInfos
import org.jetbrains.plugins.groovy.lang.psi.dataFlow.reachingDefs.ReachingDefinitionsCollector
import org.jetbrains.plugins.groovy.lang.psi.dataFlow.reachingDefs.VariableInfo
import org.jetbrains.plugins.groovy.util.TestUtils
/**
* @auther ven
*/
public class ReachingDefsTest extends LightCodeInsightFixtureTestCase {
String basePath = TestUtils.testDataPath + 'groovy/reachingDefs/'
public void testAssign() { doTest() }
public void testClosure() { doTest() }
public void testClosure1() { doTest() }
public void testEm1() { doTest() }
public void testEm2() { doTest() }
public void testEm3() { doTest() }
public void testIf1() { doTest() }
public void testInner() { doTest() }
public void testLocal1() { doTest() }
public void testLocal2() { doTest() }
public void testSimpl1() { doTest() }
public void testSimpl2() { doTest() }
public void testSimpl3() { doTest() }
public void testWhile1() { doTest() }
public void doTest() {
final List<String> data = TestUtils.readInput(testDataPath + getTestName(true) + ".test")
String text = data.get(0)
myFixture.configureByText(GroovyFileType.GROOVY_FILE_TYPE, text)
int selStart = myFixture.editor.selectionModel.selectionStart
int selEnd = myFixture.editor.selectionModel.selectionEnd
final GroovyFile file = (GroovyFile)myFixture.file
final PsiElement start = file.findElementAt(selStart)
final PsiElement end = file.findElementAt(selEnd - 1)
final GrControlFlowOwner owner = PsiTreeUtil.getParentOfType(PsiTreeUtil.findCommonParent(start, end), GrControlFlowOwner, false)
assert owner != null
GrStatement firstStatement = getStatement(start, owner)
GrStatement lastStatement = getStatement(end, owner)
final FragmentVariableInfos fragmentVariableInfos = ReachingDefinitionsCollector.obtainVariableFlowInformation(firstStatement, lastStatement)
assertEquals(data.get(1), dumpInfo(fragmentVariableInfos).trim())
}
private static String dumpInfo(FragmentVariableInfos fragmentVariableInfos) {
StringBuilder builder = new StringBuilder()
builder.append("input:\n")
for (VariableInfo info : fragmentVariableInfos.inputVariableNames) {
builder.append(info.name).append("\n")
}
builder.append("output:\n")
for (VariableInfo info : fragmentVariableInfos.outputVariableNames) {
builder.append(info.name).append("\n")
}
return builder.toString()
}
private static GrStatement getStatement(@NotNull PsiElement element, PsiElement context) {
while (element.parent != context) {
element = element.parent
assert element != null
}
return (GrStatement) element
}
}
@@ -1,86 +0,0 @@
package org.jetbrains.plugins.groovy;
import com.intellij.psi.PsiElement;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.plugins.groovy.lang.psi.GrControlFlowOwner;
import org.jetbrains.plugins.groovy.lang.psi.GroovyFile;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrStatement;
import org.jetbrains.plugins.groovy.lang.psi.dataFlow.reachingDefs.FragmentVariableInfos;
import org.jetbrains.plugins.groovy.lang.psi.dataFlow.reachingDefs.ReachingDefinitionsCollector;
import org.jetbrains.plugins.groovy.lang.psi.dataFlow.reachingDefs.VariableInfo;
import org.jetbrains.plugins.groovy.util.TestUtils;
import java.util.List;
/**
* @auther ven
*/
public class ReachingDefsTest extends LightCodeInsightFixtureTestCase {
@Override
protected String getBasePath() {
return TestUtils.getTestDataPath() + "groovy/reachingDefs/";
}
public void testAssign() throws Throwable { doTest(); }
public void testClosure() throws Throwable { doTest(); }
public void testClosure1() throws Throwable { doTest(); }
public void testEm1() throws Throwable { doTest(); }
public void testEm2() throws Throwable { doTest(); }
public void testEm3() throws Throwable { doTest(); }
public void testIf1() throws Throwable { doTest(); }
public void testInner() throws Throwable { doTest(); }
public void testLocal1() throws Throwable { doTest(); }
public void testLocal2() throws Throwable { doTest(); }
public void testSimpl1() throws Throwable { doTest(); }
public void testSimpl2() throws Throwable { doTest(); }
public void testSimpl3() throws Throwable { doTest(); }
public void testWhile1() throws Throwable { doTest(); }
public void doTest() throws Exception {
final List<String> data = TestUtils.readInput(getTestDataPath() + getTestName(true) + ".test");
String text = data.get(0);
myFixture.configureByText(GroovyFileType.GROOVY_FILE_TYPE, text);
int selStart = myFixture.getEditor().getSelectionModel().getSelectionStart();
int selEnd = myFixture.getEditor().getSelectionModel().getSelectionEnd();
final GroovyFile file = (GroovyFile) myFixture.getFile();
final PsiElement start = file.findElementAt(selStart);
final PsiElement end = file.findElementAt(selEnd - 1);
final GrControlFlowOwner owner = PsiTreeUtil.getParentOfType(PsiTreeUtil.findCommonParent(start, end), GrControlFlowOwner.class, false);
assert owner != null;
GrStatement firstStatement = getStatement(start, owner);
GrStatement lastStatement = getStatement(end, owner);
final FragmentVariableInfos fragmentVariableInfos = ReachingDefinitionsCollector.obtainVariableFlowInformation(firstStatement, lastStatement);
assertEquals(data.get(1), dumpInfo(fragmentVariableInfos).trim());
}
private static String dumpInfo(FragmentVariableInfos fragmentVariableInfos) {
StringBuilder builder = new StringBuilder();
builder.append("input:\n");
for (VariableInfo info : fragmentVariableInfos.getInputVariableNames()) {
builder.append(info.getName()).append("\n");
}
builder.append("output:\n");
for (VariableInfo info : fragmentVariableInfos.getOutputVariableNames()) {
builder.append(info.getName()).append("\n");
}
return builder.toString();
}
private static GrStatement getStatement(@NotNull PsiElement element, PsiElement context) {
while (element.getParent() != context) {
element = element.getParent();
assert element != null;
}
return (GrStatement) element;
}
}
@@ -28,10 +28,7 @@ import org.jetbrains.plugins.groovy.util.TestUtils
* @author ilyas
*/
public class ExtractMethodTest extends LightGroovyTestCase {
@Override
protected String getBasePath() {
return TestUtils.testDataPath + "groovy/refactoring/extractMethod/";
}
final String basePath = TestUtils.testDataPath + 'groovy/refactoring/extractMethod/'
private void doAntiTest(String errorMessage) {
GroovyExtractMethodHandler handler = configureFromText(readInput().get(0));
@@ -94,7 +91,7 @@ public class ExtractMethodTest extends LightGroovyTestCase {
public void testVen3() throws Throwable { doTest(); }
public void testForIn() throws Throwable { doTest(); }
public void testInCatch() {doTest();}
public void testClosureIt() throws Throwable { doTest(); }
public void testImplicitReturn() {doTest();}
@@ -109,7 +106,7 @@ public class ExtractMethodTest extends LightGroovyTestCase {
public void testLastBlockStatementInterruptsControlFlow() {doTest();}
public void testAOOBE() {doTest();}
public void testWildCardReturnType() {doTest();}
public void testParamChangedInsideExtractedMethod() {doTest();}
@@ -117,4 +114,6 @@ public class ExtractMethodTest extends LightGroovyTestCase {
public void testArgsUsedOnlyInClosure() {doTest()}
public void testArgsUsedOnlyInAnonymousClass() {doTest()}
public void testTwoVars() {doTest()}
}
@@ -0,0 +1,24 @@
def foo() {
<begin>int i = 0
int j = 1
while (condition) {
i = i + 1
j = i
}<end>
return j
}
-----
def foo() {
int j = testMethod()
return j
}
private int testMethod() {
int i = 0
int j = 1
while (condition) {
i = i + 1
j = i
}
return j
}
@@ -1,6 +1,6 @@
protected static def getGeneratedFileNames() {
def foo = 0
while (true) {
while (cond) {
<begin> println(foo)
foo = ""
<end> }
@@ -10,7 +10,7 @@ protected static def getGeneratedFileNames() {
-----
protected static def getGeneratedFileNames() {
def foo = 0
while (true) {
while (cond) {
foo = <caret>testMethod(foo)
}
@@ -1,6 +1,6 @@
protected static def getGeneratedFileNames() {
foo = 0
while (true) {
while (cond) {
<begin> println(foo)
foo = ""
<end> }
@@ -10,7 +10,7 @@ protected static def getGeneratedFileNames() {
-----
protected static def getGeneratedFileNames() {
foo = 0
while (true) {
while (cond) {
foo = <caret>testMethod(foo)
}
@@ -1,20 +1,18 @@
protected static def getGeneratedFileNames() {
foo = 0
def foo = 0
while (true) {
<begin> println(foo)
foo = ""
<end> }
int t = foo
}
-----
protected static def getGeneratedFileNames() {
foo = 0
def foo = 0
while (true) {
foo = <caret>testMethod(foo)
}
int t = foo
}
private static String testMethod(Serializable foo) {
@@ -20,12 +20,15 @@ import com.intellij.compiler.CompilerConfiguration;
import com.intellij.execution.configurations.ConfigurationUtil;
import com.intellij.execution.testframework.SourceScope;
import com.intellij.ide.util.ClassFilter;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Computable;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiManager;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.util.PsiUtilBase;
import com.intellij.psi.util.PsiUtilCore;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
@@ -49,10 +52,14 @@ public class TestClassFilter implements ClassFilter.ClassFilterWithScope {
public Project getProject() { return myProject; }
public boolean isAccepted(final PsiClass aClass) {
return ConfigurationUtil.PUBLIC_INSTANTIATABLE_CLASS.value(aClass) &&
(aClass.isInheritor(myBase, true) || JUnitUtil.isTestClass(aClass))
&& !CompilerConfiguration.getInstance(getProject()).isExcludedFromCompilation(PsiUtilBase.getVirtualFile(aClass))
;
return ApplicationManager.getApplication().runReadAction(new Computable<Boolean>() {
@Override
public Boolean compute() {
return ConfigurationUtil.PUBLIC_INSTANTIATABLE_CLASS.value(aClass) &&
(aClass.isInheritor(myBase, true) || JUnitUtil.isTestClass(aClass))
&& !CompilerConfiguration.getInstance(getProject()).isExcludedFromCompilation(PsiUtilCore.getVirtualFile(aClass));
}
});
}
public TestClassFilter intersectionWith(final GlobalSearchScope scope) {
@@ -78,9 +85,14 @@ public class TestClassFilter implements ClassFilter.ClassFilterWithScope {
}
return new TestClassFilter(testCase, sourceScope.getGlobalSearchScope()){
@Override
public boolean isAccepted(PsiClass aClass) {
public boolean isAccepted(final PsiClass aClass) {
if (super.isAccepted(aClass)) {
final String qualifiedName = aClass.getQualifiedName();
final String qualifiedName = ApplicationManager.getApplication().runReadAction(new Computable<String>() {
@Override
public String compute() {
return aClass.getQualifiedName();
}
});
for (Pattern compilePattern : compilePatterns) {
if (compilePattern.matcher(qualifiedName).matches()) {
return true;
@@ -146,6 +146,7 @@ http
https
impl
inbox
incrementer
indextype
indices
infile
@@ -18,7 +18,9 @@ package com.theoryinpractice.testng.model;
import com.intellij.codeInsight.AnnotationUtil;
import com.intellij.execution.configurations.ConfigurationUtil;
import com.intellij.ide.util.ClassFilter;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Computable;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiMethod;
import com.intellij.psi.search.GlobalSearchScope;
@@ -60,35 +62,40 @@ public class TestClassFilter implements ClassFilter.ClassFilterWithScope
return new TestClassFilter(this.scope.intersectWith(scope), project, includeConfig, checkClassCanBeInstantiated);
}
public boolean isAccepted(PsiClass psiClass) {
if(!ConfigurationUtil.PUBLIC_INSTANTIATABLE_CLASS.value(psiClass)) return false;
//PsiManager manager = PsiManager.getInstance(project);
//if(manager.getEffectiveLanguageLevel().compareTo(LanguageLevel.JDK_1_5) < 0) return true;
boolean hasTest = TestNGUtil.hasTest(psiClass);
if (hasTest) {
if (checkClassCanBeInstantiated) {
final PsiMethod[] constructors = psiClass.getConstructors();
if (constructors.length > 0) {
boolean canBeInstantiated = false;
for (PsiMethod constructor : constructors) {
if (constructor.getParameterList().getParametersCount() == 0) {
canBeInstantiated = true;
break;
}
if (AnnotationUtil.isAnnotated(constructor, Arrays.asList(GUICE_INJECTION, FACTORY_INJECTION), true)) {
canBeInstantiated = true;
break;
public boolean isAccepted(final PsiClass psiClass) {
return ApplicationManager.getApplication().runReadAction(new Computable<Boolean>() {
@Override
public Boolean compute() {
if(!ConfigurationUtil.PUBLIC_INSTANTIATABLE_CLASS.value(psiClass)) return false;
//PsiManager manager = PsiManager.getInstance(project);
//if(manager.getEffectiveLanguageLevel().compareTo(LanguageLevel.JDK_1_5) < 0) return true;
boolean hasTest = TestNGUtil.hasTest(psiClass);
if (hasTest) {
if (checkClassCanBeInstantiated) {
final PsiMethod[] constructors = psiClass.getConstructors();
if (constructors.length > 0) {
boolean canBeInstantiated = false;
for (PsiMethod constructor : constructors) {
if (constructor.getParameterList().getParametersCount() == 0) {
canBeInstantiated = true;
break;
}
if (AnnotationUtil.isAnnotated(constructor, Arrays.asList(GUICE_INJECTION, FACTORY_INJECTION), true)) {
canBeInstantiated = true;
break;
}
}
if (!canBeInstantiated){
return false;
}
}
}
if (!canBeInstantiated){
return false;
}
return true;
}
}
return true;
}
return includeConfig && TestNGUtil.hasConfig(psiClass);
return includeConfig && TestNGUtil.hasConfig(psiClass);
}
});
}
public Project getProject() {
@@ -17,7 +17,9 @@ package com.theoryinpractice.testng.model;
import com.intellij.execution.configurations.ConfigurationUtil;
import com.intellij.ide.util.ClassFilter;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Computable;
import com.intellij.psi.PsiClass;
import com.intellij.psi.search.GlobalSearchScope;
import com.theoryinpractice.testng.util.TestNGUtil;
@@ -35,10 +37,15 @@ public class TestListenerFilter implements ClassFilter.ClassFilterWithScope
this.project = project;
}
public boolean isAccepted(PsiClass psiClass) {
if (!ConfigurationUtil.PUBLIC_INSTANTIATABLE_CLASS.value(psiClass)) return false;
public boolean isAccepted(final PsiClass psiClass) {
return ApplicationManager.getApplication().runReadAction(new Computable<Boolean>() {
@Override
public Boolean compute() {
if (!ConfigurationUtil.PUBLIC_INSTANTIATABLE_CLASS.value(psiClass)) return false;
return TestNGUtil.inheritsITestListener(psiClass);
return TestNGUtil.inheritsITestListener(psiClass);
}
});
}
public Project getProject() {
@@ -19,7 +19,7 @@ import com.intellij.icons.AllIcons;
import com.intellij.ide.BrowserUtil;
import com.intellij.ide.browsers.chrome.ChromeSettings;
import com.intellij.ide.browsers.firefox.FirefoxSettings;
import com.intellij.ide.browsers.impl.UrlOpenerImpl;
import com.intellij.ide.browsers.impl.DefaultUrlOpener;
import com.intellij.openapi.components.*;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.Conditions;
@@ -217,7 +217,7 @@ public class BrowsersConfiguration implements PersistentStateComponent<Element>
@Nullable final String url,
final boolean forceOpenNewInstanceOnMac,
String... parameters) {
UrlOpenerImpl.doLaunchBrowser(family, url, parameters, Conditions.<String>alwaysTrue(), forceOpenNewInstanceOnMac);
DefaultUrlOpener.doLaunchBrowser(family, url, parameters, Conditions.<String>alwaysTrue(), forceOpenNewInstanceOnMac);
}
public static void launchBrowser(final @NotNull BrowserFamily family,
@@ -225,7 +225,7 @@ public class BrowsersConfiguration implements PersistentStateComponent<Element>
final boolean forceOpenNewInstanceOnMac,
final Condition<String> browserSpecificParametersFilter,
String... parameters) {
UrlOpenerImpl.doLaunchBrowser(family, url, parameters, browserSpecificParametersFilter, forceOpenNewInstanceOnMac);
DefaultUrlOpener.doLaunchBrowser(family, url, parameters, browserSpecificParametersFilter, forceOpenNewInstanceOnMac);
}
@Nullable
@@ -38,8 +38,8 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class UrlOpenerImpl extends UrlOpener {
private static final Logger LOG = Logger.getInstance(UrlOpenerImpl.class);
public class DefaultUrlOpener extends UrlOpener {
private static final Logger LOG = Logger.getInstance(DefaultUrlOpener.class);
@Override
public boolean openUrl(BrowsersConfiguration.BrowserFamily family, String url) {