Merge branch 'master' of git.labs.intellij.net:idea/community

This commit is contained in:
unknown
2010-07-20 18:34:28 +04:00
94 changed files with 642 additions and 335 deletions
-1
View File
@@ -28,7 +28,6 @@
<root url="jar://$PROJECT_DIR$/lib/ant/lib/ant-swing.jar!/" />
<root url="jar://$PROJECT_DIR$/lib/ant/lib/ant-javamail.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES>
<root url="jar://$PROJECT_DIR$/lib/ant/src/bundled_ant_src.zip!/bundled_ant_src/main" />
</SOURCES>
-1
View File
@@ -3,7 +3,6 @@
<CLASSES>
<root url="jar://$PROJECT_DIR$/lib/cglib-nodep-2.1_3.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES>
<root url="jar://$PROJECT_DIR$/lib/src/cglib-src-2.1_3.jar!/src/proxy" />
</SOURCES>
-2
View File
@@ -3,7 +3,5 @@
<CLASSES>
<root url="jar://$PROJECT_DIR$/lib/dtdparser113.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>
-2
View File
@@ -4,7 +4,5 @@
<root url="jar://$PROJECT_DIR$/lib/dev/easymockclassextension.jar!/" />
<root url="jar://$PROJECT_DIR$/lib/dev/easymock.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>
-1
View File
@@ -3,7 +3,6 @@
<CLASSES>
<root url="jar://$PROJECT_DIR$/lib/org.eclipse.jdt.core_3.5.2.v_981_R35x.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES>
<root url="jar://$PROJECT_DIR$/lib/src/org.eclipse.jdt.core.source_3.5.2.v_981_R35x.jar!/" />
</SOURCES>
-1
View File
@@ -3,7 +3,6 @@
<CLASSES>
<root url="file://$PROJECT_DIR$/build/lib/gant/lib" />
</CLASSES>
<JAVADOC />
<SOURCES>
<root url="jar://$PROJECT_DIR$/build/lib/gant/src.zip!/groovy" />
<root url="jar://$PROJECT_DIR$/build/lib/gant/jps-sources.zip!/" />
-1
View File
@@ -3,7 +3,6 @@
<CLASSES>
<root url="jar://$PROJECT_DIR$/lib/groovy-all-1.7.3.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES>
<root url="jar://$PROJECT_DIR$/lib/src/groovy-src-1.7.3.zip!/" />
</SOURCES>
-1
View File
@@ -3,7 +3,6 @@
<CLASSES>
<root url="jar://$PROJECT_DIR$/lib/jdom.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES>
<root url="jar://$PROJECT_DIR$/lib/src/jdom.zip!/" />
</SOURCES>
-2
View File
@@ -4,7 +4,5 @@
<root url="jar://$PROJECT_DIR$/lib/dev/jmock-1.0.1.jar!/" />
<root url="jar://$PROJECT_DIR$/lib/dev/jmock-cglib-1.0.1.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>
-2
View File
@@ -3,7 +3,5 @@
<CLASSES>
<root url="jar://$PROJECT_DIR$/lib/junit.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>
-1
View File
@@ -3,7 +3,6 @@
<CLASSES>
<root url="jar://$PROJECT_DIR$/lib/junit-4.7.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES>
<root url="jar://$PROJECT_DIR$/lib/src/junit-4.7-src.jar!/" />
</SOURCES>
-1
View File
@@ -3,7 +3,6 @@
<CLASSES>
<root url="jar://$PROJECT_DIR$/lib/jh.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES>
<root url="jar://$PROJECT_DIR$/lib/src/jhsrc.jar!/src" />
</SOURCES>
-2
View File
@@ -3,7 +3,5 @@
<CLASSES>
<root url="jar://$PROJECT_DIR$/lib/jaxen-1.1.1.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>
-1
View File
@@ -3,7 +3,6 @@
<CLASSES>
<root url="jar://$PROJECT_DIR$/lib/log4j.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES>
<root url="jar://$PROJECT_DIR$/lib/src/log4j.zip!/" />
</SOURCES>
-1
View File
@@ -4,7 +4,6 @@
<root url="jar://$PROJECT_DIR$/build/conf/mac/lib/quaqua.jar!/" />
<root url="jar://$PROJECT_DIR$/lib/eawtstub.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES>
<root url="jar://$PROJECT_DIR$/lib/src/eawtstub_src.zip!/src" />
</SOURCES>
-2
View File
@@ -12,7 +12,5 @@
<root url="jar://$PROJECT_DIR$/lib/dev/hamcrest-library-1.0.jar!/" />
<root url="jar://$PROJECT_DIR$/lib/dev/hamcrest-api-1.0.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>
-1
View File
@@ -3,7 +3,6 @@
<CLASSES>
<root url="jar://$PROJECT_DIR$/lib/nanoxml-2.2.3.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES>
<root url="jar://$PROJECT_DIR$/lib/src/nanoxml.zip!/" />
</SOURCES>
-2
View File
@@ -3,7 +3,5 @@
<CLASSES>
<root url="jar://$PROJECT_DIR$/lib/oromatcher.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>
-2
View File
@@ -3,7 +3,5 @@
<CLASSES>
<root url="jar://$PROJECT_DIR$/plugins/testng/lib/testng-jdk15.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>
-1
View File
@@ -3,7 +3,6 @@
<CLASSES>
<root url="jar://$PROJECT_DIR$/lib/trove4j.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES>
<root url="jar://$PROJECT_DIR$/lib/src/trove4j_src.jar!/util/src" />
<root url="jar://$PROJECT_DIR$/lib/src/trove4j_src.jar!/src" />
-1
View File
@@ -4,7 +4,6 @@
<root url="jar://$PROJECT_DIR$/lib/velocity.jar!/" />
<root url="jar://$PROJECT_DIR$/lib/commons-lang-2.4.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES>
<root url="jar://$PROJECT_DIR$/lib/src/velocity-1.5-src.zip!/java" />
</SOURCES>
-2
View File
@@ -3,7 +3,5 @@
<CLASSES>
<root url="jar://$PROJECT_DIR$/lib/xstream.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>
-1
View File
@@ -3,7 +3,6 @@
<CLASSES>
<root url="jar://$PROJECT_DIR$/lib/xerces.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES>
<root url="jar://$PROJECT_DIR$/lib/src/Xerces-J-src.2.8.1.zip!/xerces-2_8_1/src" />
</SOURCES>
-2
View File
@@ -5,7 +5,5 @@
<root url="jar://$PROJECT_DIR$/lib/xbean.jar!/" />
<root url="jar://$PROJECT_DIR$/lib/resolver.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>
-1
View File
@@ -3,7 +3,6 @@
<CLASSES>
<root url="jar://$PROJECT_DIR$/lib/xmlrpc-2.0.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES>
<root url="jar://$PROJECT_DIR$/lib/src/xmlrpc2.src.zip!/" />
</SOURCES>
-1
View File
@@ -4,7 +4,6 @@
<root url="jar://$PROJECT_DIR$/lib/asm.jar!/" />
<root url="jar://$PROJECT_DIR$/lib/asm-commons.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES>
<root url="jar://$PROJECT_DIR$/lib/src/asm-src.zip!/" />
</SOURCES>
-2
View File
@@ -3,7 +3,5 @@
<CLASSES>
<root url="jar://$PROJECT_DIR$/lib/commons-codec-1.3.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>
-1
View File
@@ -3,7 +3,6 @@
<CLASSES>
<root url="jar://$PROJECT_DIR$/lib/commons-collections.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES>
<root url="jar://$PROJECT_DIR$/lib/src/commons-collections-3.1-src.zip!/commons-collections-3.1/src/java" />
</SOURCES>
-2
View File
@@ -3,7 +3,5 @@
<CLASSES>
<root url="jar://$PROJECT_DIR$/lib/commons-lang-2.4.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>
-1
View File
@@ -3,7 +3,6 @@
<CLASSES>
<root url="jar://$PROJECT_DIR$/lib/commons-net-2.0-patched.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES>
<root url="jar://$PROJECT_DIR$/lib/src/commons-net-2.0-patched-src.zip!/commons-net-2.0-src/src/main/java" />
</SOURCES>
-2
View File
@@ -3,7 +3,5 @@
<CLASSES>
<root url="jar://$PROJECT_DIR$/lib/jcip-annotations.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>
-1
View File
@@ -3,7 +3,6 @@
<CLASSES>
<root url="jar://$PROJECT_DIR$/lib/jgoodies-forms.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES>
<root url="jar://$PROJECT_DIR$/lib/src/jgoodies-forms-src.zip!/" />
</SOURCES>
-2
View File
@@ -4,7 +4,5 @@
<root url="jar://$PROJECT_DIR$/lib/jna-utils.jar!/" />
<root url="jar://$PROJECT_DIR$/lib/jna.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>
-2
View File
@@ -4,7 +4,5 @@
<root url="jar://$PROJECT_DIR$/lib/microba.jar!/" />
<root url="jar://$PROJECT_DIR$/lib/src/microba-src.zip!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>
-1
View File
@@ -3,7 +3,6 @@
<CLASSES>
<root url="jar://$PROJECT_DIR$/lib/picocontainer.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES>
<root url="jar://$PROJECT_DIR$/lib/src/picocontainer-src.zip!/picocontainer-1_2/container/src/java" />
</SOURCES>
-1
View File
@@ -3,7 +3,6 @@
<CLASSES>
<root url="jar://$PROJECT_DIR$/lib/serviceMessages.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES>
<root url="jar://$PROJECT_DIR$/lib/src/serviceMessages_201292_src.zip!/src" />
</SOURCES>
@@ -23,6 +23,7 @@ package com.intellij.ide.util.newProjectWizard;
import com.intellij.ide.util.projectWizard.ModuleWizardStep;
import com.intellij.openapi.module.ModuleType;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.*;
@@ -41,7 +42,7 @@ public class StepSequence {
myParentSequence = stepSequence;
}
public void addCommonStep(ModuleWizardStep step){
public void addCommonStep(@NotNull ModuleWizardStep step){
myCommonSteps.add(step);
}
@@ -65,9 +65,13 @@ public class IntroduceFieldHandler extends BaseExpressionToFieldHandler {
protected Settings showRefactoringDialog(Project project, Editor editor, PsiClass parentClass, PsiExpression expr,
PsiType type,
PsiExpression[] occurences, PsiElement anchorElement, PsiElement anchorElementIfAll) {
final PsiMethod containingMethod = PsiTreeUtil.getParentOfType(expr, PsiMethod.class);
PsiElement element = expr.getUserData(ElementToWorkOn.PARENT);
if (element == null) element = expr;
final PsiMethod containingMethod = PsiTreeUtil.getParentOfType(expr != null ? expr : anchorElement, PsiMethod.class);
PsiElement element = null;
if (expr != null) {
element = expr.getUserData(ElementToWorkOn.PARENT);
if (element == null) element = expr;
}
if (element == null) element = anchorElement;
final PsiModifierListOwner staticParentElement = PsiUtil.getEnclosingStaticElement(element, parentClass);
boolean declareStatic = staticParentElement != null;
@@ -156,19 +156,21 @@ public class MoveMembersProcessor extends BaseRefactoringProcessor {
protected void performRefactoring(final UsageInfo[] usages) {
try {
// correct references to moved members from the outside
LanguageExtension<MoveMemberHandler> extension=new LanguageExtension<MoveMemberHandler>("com.intellij.refactoring.moveMemberHandler");
PsiClass targetClass = JavaPsiFacade.getInstance(myProject)
.findClass(myOptions.getTargetClassName(), GlobalSearchScope.projectScope(myProject));
if (targetClass == null) return;
final Map<PsiMember, PsiElement> anchors = new HashMap<PsiMember, PsiElement>();
for (PsiMember member : myMembersToMove) {
anchors.put(member, extension.forLanguage(member.getLanguage()).getAnchor(member, targetClass));
final MoveMemberHandler handler = MoveMemberHandler.EP_NAME.forLanguage(member.getLanguage());
if (handler != null) {
anchors.put(member, handler.getAnchor(member, targetClass));
}
}
ArrayList<MoveMembersUsageInfo> otherUsages = new ArrayList<MoveMembersUsageInfo>();
for (UsageInfo usageInfo : usages) {
MoveMembersUsageInfo usage = (MoveMembersUsageInfo)usageInfo;
if (!usage.reference.isValid()) continue;
final MoveMemberHandler handler = extension.forLanguage(usageInfo.getElement().getLanguage());
final MoveMemberHandler handler = MoveMemberHandler.EP_NAME.forLanguage(usageInfo.getElement().getLanguage());
if (handler!=null) {
if (handler.changeExternalUsage(myOptions, usage)) continue;
}
@@ -189,13 +191,15 @@ public class MoveMembersProcessor extends BaseRefactoringProcessor {
}
}
final RefactoringElementListener elementListener = getTransaction().getElementListener(member);
final MoveMemberHandler handler = extension.forLanguage(member.getLanguage());
PsiMember newMember=handler.doMove(myOptions, member, anchors.get(member), targetClass);
elementListener.elementMoved(newMember);
final MoveMemberHandler handler = MoveMemberHandler.EP_NAME.forLanguage(member.getLanguage());
if (handler != null) {
PsiMember newMember=handler.doMove(myOptions, member, anchors.get(member), targetClass);
elementListener.elementMoved(newMember);
fixModifierList(newMember, usages);
for (PsiReference reference : refsToBeRebind) {
reference.bindToElement(newMember);
fixModifierList(newMember, usages);
for (PsiReference reference : refsToBeRebind) {
reference.bindToElement(newMember);
}
}
}
@@ -29,9 +29,9 @@ import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.ui.ScrollPaneFactory;
import com.intellij.ui.TableUtil;
import com.intellij.ui.UIBundle;
import com.intellij.ui.table.JBTable;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.ui.ItemRemovable;
import com.intellij.util.ui.Table;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -66,7 +66,7 @@ public class ClassFilterEditor extends JPanel {
myAddClassButton = new JButton(getAddButtonText());
myAddPatternButton = new JButton(getAddPatternButtonText());
myRemoveButton = new JButton(UIBundle.message("button.remove"));
myTable = new Table();
myTable = new JBTable();
JScrollPane scrollPane = ScrollPaneFactory.createScrollPane(myTable);
add(scrollPane, new GridBagConstraints(0, GridBagConstraints.RELATIVE, 1, 3, 1.0, 1.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(4, 4, 4, 6), 0, 0));
@@ -347,4 +347,8 @@ public class ClassFilterEditor extends JPanel {
TableUtil.removeSelectedItems(myTable);
}
}
public void setAddPatternButtonVisible(boolean visible) {
myAddPatternButton.setVisible(visible);
}
}
@@ -38,6 +38,10 @@ public abstract class InlineActionHandler {
return canInlineElement(element);
}
public boolean isEnabledOnElement(PsiElement element, Editor editor) {
return isEnabledOnElement(element);
}
public abstract boolean isEnabledForLanguage(Language l);
public abstract boolean canInlineElement(PsiElement element);
@@ -431,6 +431,14 @@ public class PsiUtilBase {
return narrowLanguage(lang, file.getLanguage());
}
@Nullable
public static PsiElement getElementAtCaret(Editor editor) {
Project project = editor.getProject();
if (project == null) return null;
PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument());
return file == null ? null : file.findElementAt(editor.getCaretModel().getOffset());
}
public static Language getDialect(@NotNull PsiElement element) {
return narrowLanguage(element.getLanguage(), element.getContainingFile().getLanguage());
}
@@ -572,7 +572,7 @@ public class InspectionResultsView extends JPanel implements Disposable, Occuren
if (myTree == null) return null;
TreePath[] paths = myTree.getSelectionPaths();
if (paths == null) return null;
if (paths == null || paths.length == 0) return null;
if (paths.length > 1) {
if (LangDataKeys.PSI_ELEMENT_ARRAY.is(dataId)) {
@@ -555,6 +555,10 @@ public class NavBarPanel extends OpaquePanel.List implements DataProvider, Popup
}
});
if (!isValid()) {
validate();
}
myNodePopup.showUnderneathOf(item);
}
}
@@ -569,15 +569,7 @@ public class PsiBuilderImpl extends UserDataHolderBase implements PsiBuilder {
@SuppressWarnings({"SuspiciousMethodCalls"})
public void doneBefore(Marker marker, Marker before) {
// TODO: there could be not done markers after 'marker' and that's normal
if (((StartMarker)marker).myDoneMarker != null) {
LOG.error("Marker already done.");
}
int idx = myProduction.lastIndexOf(marker);
if (idx < 0) {
LOG.error("Marker never been added.");
}
doValidityChecks(marker, before);
int beforeIndex = myProduction.lastIndexOf(before);
@@ -599,7 +591,7 @@ public class PsiBuilderImpl extends UserDataHolderBase implements PsiBuilder {
}
public void error(Marker marker, String message) {
doValidityChecks(marker);
doValidityChecks(marker, null);
DoneWithErrorMarker doneMarker = new DoneWithErrorMarker((StartMarker)marker, myCurrentLexeme, message);
((StartMarker)marker).myDoneMarker = doneMarker;
@@ -608,27 +600,18 @@ public class PsiBuilderImpl extends UserDataHolderBase implements PsiBuilder {
@SuppressWarnings({"SuspiciousMethodCalls"})
public void errorBefore(Marker marker, String message, Marker before) {
// TODO: there could be not done markers after 'marker' and that's normal
if (((StartMarker)marker).myDoneMarker != null) {
LOG.error("Marker already done.");
}
int idx = myProduction.lastIndexOf(marker);
if (idx < 0) {
LOG.error("Marker has never been added.");
}
doValidityChecks(marker, before);
int beforeIndex = myProduction.lastIndexOf(before);
DoneWithErrorMarker doneMarker = new DoneWithErrorMarker((StartMarker)marker, myCurrentLexeme, message);
doneMarker.myLexemeIndex = ((StartMarker)before).myLexemeIndex;
((StartMarker)marker).myDoneMarker = doneMarker;
myProduction.add(beforeIndex, doneMarker);
}
public void done(final Marker marker) {
doValidityChecks(marker);
doValidityChecks(marker, null);
DoneMarker doneMarker = DONE_MARKERS.alloc();
doneMarker.myStart = (StartMarker)marker;
@@ -644,30 +627,41 @@ public class PsiBuilderImpl extends UserDataHolderBase implements PsiBuilder {
}
@SuppressWarnings({"UseOfSystemOutOrSystemErr", "SuspiciousMethodCalls"})
private void doValidityChecks(final Marker marker) {
if (myDebugMode) {
final DoneMarker doneMarker = ((StartMarker)marker).myDoneMarker;
if (doneMarker != null) {
LOG.error("Marker already done.");
}
int idx = myProduction.lastIndexOf(marker);
if (idx < 0) {
LOG.error("Marker never been added.");
}
private void doValidityChecks(final Marker marker, @Nullable final Marker before) {
if (!myDebugMode) return;
for (int i = myProduction.size() - 1; i > idx; i--) {
Object item = myProduction.get(i);
if (item instanceof StartMarker) {
StartMarker otherMarker = (StartMarker)item;
if (otherMarker.myDoneMarker == null) {
final Throwable debugAllocOther = otherMarker.myDebugAllocationPosition;
final Throwable debugAllocThis = ((StartMarker)marker).myDebugAllocationPosition;
if (debugAllocOther != null) {
debugAllocThis.printStackTrace(System.err);
debugAllocOther.printStackTrace(System.err);
}
LOG.error("Another not done marker added after this one. Must be done before this.");
final DoneMarker doneMarker = ((StartMarker)marker).myDoneMarker;
if (doneMarker != null) {
LOG.error("Marker already done.");
}
int idx = myProduction.lastIndexOf(marker);
if (idx < 0) {
LOG.error("Marker has never been added.");
}
int endIdx = myProduction.size();
if (before != null) {
endIdx = myProduction.lastIndexOf(before);
if (endIdx < 0) {
LOG.error("'Before' marker has never been added.");
}
if (idx > endIdx) {
LOG.error("'Before' marker precedes this one.");
}
}
for (int i = endIdx - 1; i > idx; i--) {
Object item = myProduction.get(i);
if (item instanceof StartMarker) {
StartMarker otherMarker = (StartMarker)item;
if (otherMarker.myDoneMarker == null) {
final Throwable debugAllocOther = otherMarker.myDebugAllocationPosition;
final Throwable debugAllocThis = ((StartMarker)marker).myDebugAllocationPosition;
if (debugAllocOther != null) {
debugAllocThis.printStackTrace(System.err);
debugAllocOther.printStackTrace(System.err);
}
LOG.error("Another not done marker added after this one. Must be done before this.");
}
}
}
@@ -17,6 +17,7 @@
package com.intellij.psi.impl.include;
import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.vfs.JarFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.util.containers.FactoryMap;
@@ -68,14 +69,14 @@ public class FileIncludeIndex extends FileBasedIndexExtension<FileIncludeIndex.K
return INDEX_ID;
}
public DataIndexer<FileIncludeIndex.Key, List<FileIncludeInfoImpl>, FileContent> getIndexer() {
return new DataIndexer<FileIncludeIndex.Key, List<FileIncludeInfoImpl>, FileContent>() {
public DataIndexer<Key, List<FileIncludeInfoImpl>, FileContent> getIndexer() {
return new DataIndexer<Key, List<FileIncludeInfoImpl>, FileContent>() {
@NotNull
public Map<FileIncludeIndex.Key, List<FileIncludeInfoImpl>> map(FileContent inputData) {
public Map<Key, List<FileIncludeInfoImpl>> map(FileContent inputData) {
Map<FileIncludeIndex.Key, List<FileIncludeInfoImpl>> map = new FactoryMap<FileIncludeIndex.Key, List<FileIncludeInfoImpl>>() {
Map<Key, List<FileIncludeInfoImpl>> map = new FactoryMap<Key, List<FileIncludeInfoImpl>>() {
@Override
protected List<FileIncludeInfoImpl> create(FileIncludeIndex.Key key) {
protected List<FileIncludeInfoImpl> create(Key key) {
return new ArrayList<FileIncludeInfoImpl>();
}
};
@@ -144,6 +145,9 @@ public class FileIncludeIndex extends FileBasedIndexExtension<FileIncludeIndex.K
public FileBasedIndex.InputFilter getInputFilter() {
return new FileBasedIndex.InputFilter() {
public boolean acceptInput(VirtualFile file) {
if (file.getFileSystem() == JarFileSystem.getInstance()) {
return false;
}
for (FileIncludeProvider provider : myProviders) {
if (provider.acceptFile(file)) {
return true;
@@ -83,12 +83,8 @@ public abstract class BaseRefactoringAction extends AnAction {
presentation.setEnabled(true);
DataContext dataContext = e.getDataContext();
Project project = e.getData(PlatformDataKeys.PROJECT);
if (project == null) {
disableAction(e);
return;
}
if (isHidden()) {
e.getPresentation().setVisible(false);
if (project == null || isHidden()) {
hideAction(e);
return;
}
@@ -103,7 +99,7 @@ public abstract class BaseRefactoringAction extends AnAction {
if (editor == null) {
if (isAvailableInEditorOnly()) {
disableAction(e);
hideAction(e);
return;
}
final PsiElement[] elements = getPsiElementArray(dataContext);
@@ -116,21 +112,30 @@ public abstract class BaseRefactoringAction extends AnAction {
PsiElement element = e.getData(LangDataKeys.PSI_ELEMENT);
if (element == null || !isAvailableForLanguage(element.getLanguage())) {
if (file == null) {
disableAction(e);
hideAction(e);
return;
}
element = getElementAtCaret(editor, file);
}
final boolean isEnabled = element != null &&
!(element instanceof SyntheticElement) &&
isAvailableForLanguage(PsiUtilBase.getLanguageInEditor(editor, project)) &&
isAvailableOnElementInEditor(element, editor);
if (!isEnabled) {
disableAction(e);
boolean isVisible = element != null &&
!(element instanceof SyntheticElement) &&
isAvailableForLanguage(PsiUtilBase.getLanguageInEditor(editor, project));
if (isVisible) {
boolean isEnabled = isAvailableOnElementInEditor(element, editor);
if (!isEnabled) {
disableAction(e);
}
}
else {
hideAction(e);
}
}
}
private static void hideAction(AnActionEvent e) {
e.getPresentation().setVisible(false);
}
protected boolean isHidden() {
return false;
}
@@ -162,7 +167,7 @@ public abstract class BaseRefactoringAction extends AnAction {
private static void disableAction(final AnActionEvent e) {
e.getPresentation().setEnabled(false);
if (ActionPlaces.isPopupPlace(e.getPlace())) {
e.getPresentation().setVisible(false);
hideAction(e);
}
}
@@ -45,16 +45,16 @@ public class InlineAction extends BasePlatformRefactoringAction {
@Override
protected boolean isAvailableOnElementInEditor(PsiElement element, Editor editor) {
return hasInlineActionHandler(element, PsiUtilBase.getLanguageInEditor(editor, element.getProject()));
return hasInlineActionHandler(element, PsiUtilBase.getLanguageInEditor(editor, element.getProject()), editor);
}
public boolean isEnabledOnElements(PsiElement[] elements) {
return elements.length == 1 && hasInlineActionHandler(elements [0], null);
return elements.length == 1 && hasInlineActionHandler(elements [0], null, null);
}
private static boolean hasInlineActionHandler(PsiElement element, @Nullable Language editorLanguage) {
private static boolean hasInlineActionHandler(PsiElement element, @Nullable Language editorLanguage, Editor editor) {
for(InlineActionHandler handler: Extensions.getExtensions(InlineActionHandler.EP_NAME)) {
if (handler.isEnabledOnElement(element)) {
if (handler.isEnabledOnElement(element, editor)) {
return true;
}
}
@@ -134,7 +134,7 @@ public class RenameDialog extends RefactoringDialog {
}
public String[] getSuggestedNames() {
Set<String> result = new HashSet<String>();
LinkedHashSet<String> result = new LinkedHashSet<String>();
final NameSuggestionProvider[] providers = Extensions.getExtensions(NameSuggestionProvider.EP_NAME);
for(NameSuggestionProvider provider: providers) {
SuggestedNameInfo info = provider.getSuggestedNames(myPsiElement, myNameSuggestionContext, result);
@@ -23,6 +23,7 @@ import com.intellij.concurrency.Job;
import com.intellij.concurrency.JobUtil;
import com.intellij.openapi.progress.ProcessCanceledException;
import com.intellij.openapi.project.IndexNotReadyException;
import com.intellij.openapi.util.Ref;
import com.intellij.util.Alarm;
import com.intellij.util.Function;
import com.intellij.util.ui.EmptyIcon;
@@ -66,29 +67,37 @@ public class DeferredIconImpl<T> implements DeferredIcon {
if (!myIsScheduled) {
myIsScheduled = true;
final Component target;
final Ref<Component> target = new Ref<Component>(null);
final Ref<Component> paintingParent = new Ref<Component>(null);
final Ref<Rectangle> paintingParentRec = new Ref<Rectangle>(null);
final Container list = SwingUtilities.getAncestorOfClass(JList.class, c);
if (list != null) {
target = list;
target.set(list);
}
else {
final Container tree = SwingUtilities.getAncestorOfClass(JTree.class, c);
if (tree != null) {
target = tree;
target.set(tree);
}
else {
final Container table = SwingUtilities.getAncestorOfClass(JTable.class, c);
if (table != null) {
target = table;
target.set(table);
}
else {
target = c;
target.set(c);
}
}
}
myLastTarget = new WeakReference<Component>(target);
Container pp = SwingUtilities.getAncestorOfClass(PaintingParent.class, c);
paintingParent.set(pp);
if (paintingParent.get() != null) {
paintingParentRec.set(((PaintingParent)pp).getChildRec(c));
}
myLastTarget = new WeakReference<Component>(target.get());
JobUtil.submitToJobThread(new Runnable() {
public void run() {
@@ -100,10 +109,23 @@ public class DeferredIconImpl<T> implements DeferredIcon {
//noinspection SSBasedInspection
SwingUtilities.invokeLater(new Runnable() {
public void run() {
Component actualTarget = target.get();
if (SwingUtilities.getWindowAncestor(actualTarget) == null) {
actualTarget = paintingParent.get();
if (actualTarget == null || SwingUtilities.getWindowAncestor(actualTarget) == null) {
actualTarget = null;
myLastTarget = null;
}
}
if (actualTarget == null) return;
myLastTarget = new WeakReference<Component>(actualTarget);
if (shouldRevalidate) {
// revalidate will not work: jtree caches size of nodes
if (target instanceof JTree) {
final TreeUI ui = ((JTree)target).getUI();
if (actualTarget instanceof JTree) {
final TreeUI ui = ((JTree)actualTarget).getUI();
if (ui instanceof BasicTreeUI) {
// this call is "fake" and only need to reset tree layout cache
((BasicTreeUI)ui).setLeftChildIndent(((Integer)UIManager.get("Tree.leftChildIndent")).intValue());
@@ -111,11 +133,16 @@ public class DeferredIconImpl<T> implements DeferredIcon {
}
}
if (c == target) {
if (c == actualTarget) {
c.repaint(x, y, getIconWidth(), getIconHeight());
}
else {
ourRepaintScheduler.pushDirtyComponent(target);
Rectangle rec = null;
if (paintingParentRec.get() != null) {
rec = paintingParentRec.get();
}
ourRepaintScheduler.pushDirtyComponent(actualTarget, rec);
}
}
});
@@ -191,20 +218,44 @@ public class DeferredIconImpl<T> implements DeferredIcon {
private static class RepaintScheduler {
private final Alarm myAlarm = new Alarm();
private final Set<Component> myQueue = new LinkedHashSet<Component>();
private final Set<RepaintRequest> myQueue = new LinkedHashSet<RepaintRequest>();
public void pushDirtyComponent(Component c) {
public void pushDirtyComponent(final Component c, final Rectangle rec) {
myAlarm.cancelAllRequests();
myAlarm.addRequest(new Runnable() {
public void run() {
for (Component component : myQueue) {
component.repaint();
for (RepaintRequest each : myQueue) {
Rectangle r = each.getRectangle();
if (r != null) {
each.getComponent().repaint(r.x, r.y, r.width, r.height);
} else {
each.getComponent().repaint();
}
}
myQueue.clear();
}
}, 50);
myQueue.add(c);
myQueue.add(new RepaintRequest(c, rec));
}
}
private static class RepaintRequest {
private Component myComponent;
private Rectangle myRectangle;
private RepaintRequest(Component component, Rectangle rectangle) {
myComponent = component;
myRectangle = rectangle;
}
public Component getComponent() {
return myComponent;
}
public Rectangle getRectangle() {
return myRectangle;
}
}
}
@@ -20,9 +20,13 @@ import com.intellij.lexer.LexerBase;
import com.intellij.psi.impl.DebugUtil;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.tree.TokenSet;
import com.sun.tools.internal.xjc.util.NullStream;
import org.junit.Test;
import java.io.PrintStream;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
public class LightPsiBuilderTest {
@@ -140,6 +144,45 @@ public class LightPsiBuilderTest {
" PsiElement(DIGIT)('1')\n");
}
@Test
public void testValidityChecksOnDone() throws Exception {
doFailTest("a",
new Parser() {
public void parse(PsiBuilder builder) {
final PsiBuilder.Marker first = builder.mark();
builder.advanceLexer();
builder.mark();
first.done(LETTER);
}
});
}
@Test
public void testValidityChecksOnDoneBefore1() throws Exception {
doFailTest("a",
new Parser() {
public void parse(PsiBuilder builder) {
final PsiBuilder.Marker first = builder.mark();
builder.advanceLexer();
final PsiBuilder.Marker second = builder.mark();
second.precede();
first.doneBefore(LETTER, second);
}
});
}
@Test
public void testValidityChecksOnDoneBefore2() throws Exception {
doFailTest("a",
new Parser() {
public void parse(PsiBuilder builder) {
final PsiBuilder.Marker first = builder.mark();
builder.advanceLexer();
final PsiBuilder.Marker second = builder.mark();
second.doneBefore(LETTER, first);
}
});
}
private interface Parser {
void parse(PsiBuilder builder);
@@ -154,6 +197,27 @@ public class LightPsiBuilderTest {
assertEquals(expected, DebugUtil.nodeTreeToString(root, true));
}
private static void doFailTest(final String text, final Parser parser) {
final PrintStream std = System.err;
//noinspection IOResourceOpenedButNotSafelyClosed
System.setErr(new PrintStream(new NullStream()));
try {
try {
final PsiBuilder builder = new PsiBuilderImpl(new MyTestLexer(), TokenSet.EMPTY, TokenSet.EMPTY, text);
builder.setDebugMode(true);
parser.parse(builder);
fail("should fail");
}
catch (AssertionError e) {
//System.out.println("caught: " + e);
if ("should fail".equals(e.getMessage())) throw e;
}
}
finally {
System.setErr(std);
}
}
private static class MyTestLexer extends LexerBase {
private CharSequence myBuffer = "";
private int myIndex = 0;
@@ -25,6 +25,7 @@ import com.intellij.openapi.ui.Messages;
import com.intellij.ui.CommandButtonGroup;
import com.intellij.ui.components.panels.OpaquePanel;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
@@ -221,7 +222,7 @@ public abstract class AbstractWizard<T extends Step> extends DialogWrapper {
return mySteps.get(myCurrentStep);
}
public void addStep(final T step) {
public void addStep(@NotNull final T step) {
mySteps.add(step);
if (step instanceof StepAdapter) {
@@ -0,0 +1,39 @@
/*
* Copyright 2000-2010 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.ui;
import org.jetbrains.annotations.Nullable;
import java.awt.*;
/**
* Used for deferred re-painting (i.e. for deferred icons). As a paint() method is invoked through the normal AWT painting cycle, deferred painting
* of children may be queued. It means that actual data used for painting is pushed for calculation and, as it gets ready, there is need for repaint.
* The target component for further repaint() is either the component that was originally exposed to painting or, if it's no longer showing (in case of a flyweight
* renderer) -- the first component up in the hierarchy that implements PaintingParent.
*
*/
public interface PaintingParent {
/**
* Returns rectangle of a child component for further repainting
* @param c
* @return a rectange, if null -- the whole component will be repainted
*/
@Nullable
Rectangle getChildRec(Component c);
}
@@ -440,7 +440,7 @@ public class WelcomeScreen {
final boolean e2 = ((IdeaPluginDescriptorImpl)o2).isEnabled();
if (e1 && !e2) return -1;
if (!e1 && e2) return 1;
return o1.getName().compareTo(o2.getName());
return o1.getName().toLowerCase().compareTo(o2.getName().toLowerCase());
}
};
Collections.sort(installedPlugins, pluginsComparator);
@@ -452,11 +452,10 @@ instances.upcasted.to.object=Instances upcasted to Object
instances.upcasted.to.java.lang.object.found=Instances upcasted to java.lang.Object found
replace.inheritance.with.delegation.command=Replacing inheritance with delegation in {0}
replace.inheritance.with.delegation.elements.header=Replace inheritance with delegation
# Inline included file
inline.included.file.title=Inline included file
the.caret.should.be.positioned.on.the.include.directive.to.inline=The caret should be positioned on the include directive to inline
cannot.determine.the.structure.of.included.file=Cannot determine the structure of included file.
included.file.uses.another.syntax=Included file uses another syntax.
cannot.resolve.included.file=Cannot resolve included file
the.caret.should.be.positioned.on.the.included.file.to.inline=The caret should be positioned on the included file reference to inline
inline.the.contents.include.prompt=Inline the contents of ''{0}''?
remove.include.prompt=Included file is no longer used. Remove it?
delete.include.command=Delete {0}
@@ -23,7 +23,7 @@ public class TextChunk {
private final AttributesFlyweight myAttributes;
private final String myText;
public TextChunk(TextAttributes attributesKey, @NotNull String text) {
public TextChunk(@NotNull TextAttributes attributesKey, @NotNull String text) {
myAttributes = attributesKey.getFlyweight();
myText = text;
}
@@ -24,6 +24,7 @@ import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.RangeMarker;
import com.intellij.openapi.editor.markup.TextAttributes;
import com.intellij.openapi.fileEditor.*;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.project.Project;
@@ -91,7 +92,7 @@ public class UsageInfo2UsageAdapter implements UsageInModule, UsageInLibrary, Us
initChunks();
} else { // element over light virtual file
myTextChunks = new TextChunk[] {
new TextChunk(null, element.getText())
new TextChunk(new TextAttributes(), element.getText())
};
myOffset = element.getTextOffset();
}
@@ -0,0 +1 @@
def objects = <spot>[foo, bar]</spot>
@@ -0,0 +1 @@
def objects = <spot>new Object[] {foo, bar}</spot>
@@ -0,0 +1,7 @@
<html>
<body>
<font face="verdana" size="-1">
This intention converts java-style array creation to groovy syntax.
</font>
</body>
</html>
+5
View File
@@ -375,6 +375,11 @@
-->
<!-- conversions -->
<intentionAction>
<bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
<categoryKey>intention.category.groovy/intention.category.conversions</categoryKey>
<className>org.jetbrains.plugins.groovy.intentions.conversions.ConvertJavaStyleArrayCreationIntention</className>
</intentionAction>
<intentionAction>
<bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
<categoryKey>intention.category.groovy/intention.category.conversions</categoryKey>
@@ -283,6 +283,7 @@ public class GroovyAnnotator extends GroovyElementVisitor implements Annotator {
if (body != null) checkDuplicateMethod(body.getGroovyMethods(), myHolder);
checkImplementedMethodsOfClass(myHolder, typeDefinition);
checkConstructors(myHolder, typeDefinition);
highligtClassReference(myHolder, typeDefinition.getNameIdentifierGroovy());
}
private static void checkConstructors(AnnotationHolder holder, GrTypeDefinition typeDefinition) {
@@ -1296,6 +1297,9 @@ public class GroovyAnnotator extends GroovyElementVisitor implements Annotator {
if (member instanceof PsiMethod) {
annotation.setTextAttributes(!isStatic ? DefaultHighlighter.METHOD_CALL : DefaultHighlighter.STATIC_METHOD_ACCESS);
}
if (member instanceof PsiClass) {
highligtClassReference(holder, refExpr);
}
}
@@ -1536,16 +1540,24 @@ public class GroovyAnnotator extends GroovyElementVisitor implements Annotator {
private static void highlightAnnotation(AnnotationHolder holder, PsiElement refElement, GroovyResolveResult result) {
PsiElement element = result.getElement();
PsiElement parent = refElement.getParent();
if (element instanceof PsiClass && ((PsiClass)element).isAnnotationType() && !(parent instanceof GrImportStatement)) {
Annotation annotation = holder.createInfoAnnotation(parent, null);
annotation.setTextAttributes(DefaultHighlighter.ANNOTATION);
GroovyPsiElement context = result.getCurrentFileResolveContext();
if (context instanceof GrImportStatement) {
annotation = holder.createInfoAnnotation(((GrImportStatement)context).getImportReference(), null);
if (element instanceof PsiClass) {
if (((PsiClass)element).isAnnotationType() && !(parent instanceof GrImportStatement)) {
Annotation annotation = holder.createInfoAnnotation(parent, null);
annotation.setTextAttributes(DefaultHighlighter.ANNOTATION);
GroovyPsiElement context = result.getCurrentFileResolveContext();
if (context instanceof GrImportStatement) {
annotation = holder.createInfoAnnotation(((GrImportStatement)context).getImportReference(), null);
annotation.setTextAttributes(DefaultHighlighter.ANNOTATION);
}
} else {
highligtClassReference(holder, refElement);
}
}
}
private static void highligtClassReference(AnnotationHolder holder, PsiElement classReference) {
final Annotation annotation = holder.createInfoAnnotation(classReference, null);
annotation.setTextAttributes(DefaultHighlighter.CLASS_REFERENCE);
}
@@ -70,6 +70,8 @@ public class DefaultHighlighter {
static final String METHOD_CALL_ID = "Method call";
@NonNls
static final String STATIC_METHOD_ACCESS_ID = "Static method access";
@NonNls
static final String CLASS_REFERENCE_ID = "Class";
@NonNls
@@ -103,6 +105,9 @@ public class DefaultHighlighter {
public static TextAttributesKey DOC_COMMENT_TAG = TextAttributesKey.createTextAttributesKey(DOC_COMMENT_TAG_ID,
SyntaxHighlighterColors.DOC_COMMENT_TAG.getDefaultAttributes());
public static TextAttributesKey CLASS_REFERENCE =
TextAttributesKey.createTextAttributesKey(CLASS_REFERENCE_ID, HighlighterColors.TEXT.getDefaultAttributes().clone());
public static final TextAttributes KEYWORD_ATTRIBUTES = SyntaxHighlighterColors.KEYWORD.getDefaultAttributes().clone();
static{
@@ -67,7 +67,7 @@ public class GroovyColorsAndFontsPage implements ColorSettingsPage {
new AttributesDescriptor(DefaultHighlighter.ANNOTATION_ID, DefaultHighlighter.ANNOTATION),
new AttributesDescriptor(DefaultHighlighter.STATIC_FIELD_ID, DefaultHighlighter.STATIC_FIELD),
new AttributesDescriptor(DefaultHighlighter.STATIC_FIELD_ID, DefaultHighlighter.INSTANCE_FIELD),
new AttributesDescriptor(DefaultHighlighter.STATIC_METHOD_ACCESS_ID, DefaultHighlighter.STATIC_METHOD_ACCESS),
new AttributesDescriptor(DefaultHighlighter.CLASS_REFERENCE_ID, DefaultHighlighter.CLASS_REFERENCE),
};
@NotNull
@@ -83,23 +83,23 @@ public class GroovyColorsAndFontsPage implements ColorSettingsPage {
@NonNls
@NotNull
public String getDemoText() {
return "import javax.swing.JPanel\n" +
return "import <classref>javax.swing.JPanel</classref>\n" +
" ### \n" +
"<gdoc>/**\n" +
" * This is Groovydoc comment\n" +
" * <doctag>@see</doctag> java.lang.String#equals\n" +
" * <doctag>@see</doctag> <classref>java.lang.String</classref>#equals\n" +
" */</gdoc>\n" +
"<annotation>@SpecialBean</annotation> \n" +
"class Demo {\n" +
"class <classref>Demo</classref> {\n" +
" def <instfield>property</instfield>\n" +
"//This is a line comment\n" +
"/* This is a block comment */\n" +
" static def foo(int i) { return [i, i, <instfield>property</instfield>] }\n" +
" static def <statfield>panel</statfield> = new JPanel()\n" +
" static def <statfield>panel</statfield> = new <classref>JPanel</classref>()\n" +
"}\n" +
"\n" +
"Demo.<statfield>panel</statfield>.size = " +
"Demo.<statmet>foo</statmet>(\"123${456}789\".toInteger()) \n" +
"<classref>Demo</classref>.<statfield>panel</statfield>.size = " +
"<classref>Demo</classref>.<statmet>foo</statmet>(\"123${456}789\".toInteger()) \n" +
"'JetBrains'.matches(/Jw+Bw+/) \n" +
"def x=1 + <unresolved>unresolved</unresolved>"
;
@@ -115,6 +115,7 @@ public class GroovyColorsAndFontsPage implements ColorSettingsPage {
map.put("gdoc", DefaultHighlighter.DOC_COMMENT_CONTENT);
map.put("doctag", DefaultHighlighter.DOC_COMMENT_TAG);
map.put("unresolved", DefaultHighlighter.UNRESOLVED_ACCESS);
map.put("classref", DefaultHighlighter.CLASS_REFERENCE);
return map;
}
@@ -82,4 +82,7 @@ do.not.create.first.new=Use &existing first parameter as map for named arguments
convert.cannot.itself=Refactoring is not available for map parameter itself
perform.refactoring=Performing refactoring
map.param.name=Map parameter &name:
convert.param.to.map.entry=Convert parameter to map entry
convert.param.to.map.entry=Convert parameter to map entry
convert.java.style.array.creation.intention.name=Convert java-style array creation
convert.java.style.array.creation.intention.family.name=Convert Java-Style Array Creation to Groovy Syntax
@@ -0,0 +1,65 @@
/*
* Copyright 2000-2010 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.conversions;
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.GroovyPsiElementFactory;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrNewExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrMethodCallExpression;
/**
* @author Maxim.Medvedev
*/
public class ConvertJavaStyleArrayCreationIntention extends Intention {
@Override
protected void processIntention(@NotNull PsiElement element) throws IncorrectOperationException {
final GrClosableBlock block = ((GrMethodCallExpression)element).getClosureArguments()[0];
final String text = block.getText();
int start = block.getLBrace().getStartOffsetInParent() + 1;
int finish = block.getRBrace().getStartOffsetInParent();
String newText = "[" + text.substring(start, finish) + "]";
final GrExpression newExpr = GroovyPsiElementFactory.getInstance(element.getProject()).createExpressionFromText(newText);
((GrMethodCallExpression)element).replaceWithStatement(newExpr);
}
@NotNull
@Override
protected PsiElementPredicate getElementPredicate() {
return new PsiElementPredicate() {
@Override
public boolean satisfiedBy(PsiElement element) {
if (!(element instanceof GrMethodCallExpression)) return false;
final GrExpression expression = ((GrMethodCallExpression)element).getInvokedExpression();
if (!(expression instanceof GrNewExpression)) return false;
if (((GrNewExpression)expression).getArrayCount() == 0) return false;
if (((GrMethodCallExpression)element).getArgumentList().getText().trim().length() > 0) return false;
final GrClosableBlock[] closureArguments = ((GrMethodCallExpression)element).getClosureArguments();
if (closureArguments.length != 1) return false;
final GrClosableBlock block = closureArguments[0];
if (block.getLBrace() == null || block.getRBrace() == null) return false;
return true;
}
};
}
}
@@ -185,42 +185,53 @@ public class ConvertParameterToMapEntryIntention extends Intention {
//final List<GrCall> calls = getCallOccurrences(occurrences);
try {
for (PsiElement occurrence : occurrences) {
if (occurrence instanceof GrReferenceExpression && occurrence.getParent() instanceof GrCall) {
final GrReferenceExpression refExpr = (GrReferenceExpression)occurrence;
final GrClosureSignature signature = generateSignature(owner, refExpr);
if (signature == null) continue;
final GrCall call = (GrCall)refExpr.getParent();
final GrArgumentList argumentList = call.getArgumentList();
final GrClosableBlock[] closureArguments =
call instanceof GrCallExpression ? ((GrCallExpression)call).getClosureArguments() : GrClosableBlock.EMPTY_ARRAY;
final GrClosureSignatureUtil.ArgInfo<PsiElement>[] argInfos =
GrClosureSignatureUtil.mapParametersToArguments(signature, argumentList, closureArguments, owner.getResolveScope());
if (argInfos == null) continue;
final GrClosureSignatureUtil.ArgInfo<PsiElement> argInfo = argInfos[index];
final GrNamedArgument namedArg;
if (argInfo.isMultiArg) {
if (argInfo.args.size() == 0) continue;
String arg = "[" + StringUtil.join(ContainerUtil.map(argInfo.args, new Function<PsiElement, String>() {
public String fun(PsiElement element) {
return element.getText();
}
}), ", ") + "]";
for (PsiElement psiElement : argInfo.args) {
psiElement.delete();
GrReferenceExpression refExpr = null;
if (occurrence instanceof GrReferenceExpression) {
final PsiElement parent = occurrence.getParent();
if (parent instanceof GrCall) {
refExpr = (GrReferenceExpression)occurrence;
}
else if (parent instanceof GrReferenceExpression) {
final PsiElement resolved = ((GrReferenceExpression)parent).resolve();
if (resolved instanceof PsiMethod && "call".equals(((PsiMethod)resolved).getName())) {
refExpr = (GrReferenceExpression)parent;
}
namedArg = factory.createNamedArgument(paramName, factory.createExpressionFromText(arg));
}
else {
if (argInfo.args.size() == 0) continue;
final PsiElement argument = argInfo.args.iterator().next();
assert argument instanceof GrExpression;
namedArg = factory.createNamedArgument(paramName, (GrExpression)argument);
argument.delete();
}
((GrCall)refExpr.getParent()).addNamedArgument(namedArg);
}
if (refExpr == null) continue;
final GrClosureSignature signature = generateSignature(owner, refExpr);
if (signature == null) continue;
final GrCall call = (GrCall)refExpr.getParent();
final GrArgumentList argumentList = call.getArgumentList();
final GrClosableBlock[] closureArguments =
call instanceof GrCallExpression ? ((GrCallExpression)call).getClosureArguments() : GrClosableBlock.EMPTY_ARRAY;
final GrClosureSignatureUtil.ArgInfo<PsiElement>[] argInfos =
GrClosureSignatureUtil.mapParametersToArguments(signature, argumentList, closureArguments, owner.getResolveScope());
if (argInfos == null) continue;
final GrClosureSignatureUtil.ArgInfo<PsiElement> argInfo = argInfos[index];
final GrNamedArgument namedArg;
if (argInfo.isMultiArg) {
if (argInfo.args.size() == 0) continue;
String arg = "[" + StringUtil.join(ContainerUtil.map(argInfo.args, new Function<PsiElement, String>() {
public String fun(PsiElement element) {
return element.getText();
}
}), ", ") + "]";
for (PsiElement psiElement : argInfo.args) {
psiElement.delete();
}
namedArg = factory.createNamedArgument(paramName, factory.createExpressionFromText(arg));
}
else {
if (argInfo.args.size() == 0) continue;
final PsiElement argument = argInfo.args.iterator().next();
assert argument instanceof GrExpression;
namedArg = factory.createNamedArgument(paramName, (GrExpression)argument);
argument.delete();
}
((GrCall)refExpr.getParent()).addNamedArgument(namedArg);
}
}
catch (IncorrectOperationException e) {
@@ -369,10 +380,8 @@ public class ConvertParameterToMapEntryIntention extends Intention {
final PsiElement namedElem = getReferencedElement(owner);
if (namedElem == null) return true;
final Ref<Boolean> result = new Ref<Boolean>(true);
final Task task = new Task.Modal(project, GroovyIntentionsBundle.message("find.method.ro.closure.usages.0",
owner instanceof GrClosableBlock
? CLOSURE_CAPTION
: METHOD_CAPTION), true) {
final Task task = new Task.Modal(project, GroovyIntentionsBundle
.message("find.method.ro.closure.usages.0", owner instanceof GrClosableBlock ? CLOSURE_CAPTION : METHOD_CAPTION), true) {
public void run(@NotNull final ProgressIndicator indicator) {
final GlobalSearchScope projectScope = GlobalSearchScope.projectScope(getProject());
final Query<PsiReference> query = ReferencesSearch.search(namedElem, projectScope);
@@ -227,38 +227,11 @@ public class PsiImplUtil {
}
public static void setName(String name, PsiElement nameElement) {
ASTNode node = nameElement.getNode();
ASTNode newNameNode = GroovyPsiElementFactory.getInstance(nameElement.getProject()).createReferenceNameFromText(name).getNode();
assert newNameNode != null && node != null;
node.getTreeParent().replaceChild(node, newNameNode);
final PsiElement newNameElement = GroovyPsiElementFactory.getInstance(nameElement.getProject()).createReferenceNameFromText(name);
nameElement.replace(newNameElement);
}
public static boolean isExtendsSignature(MethodSignature superSignatureCandidate, MethodSignature subSignature) {
/*final String name1 = superSignatureCandidate.getName();
final String name2 = subSignature.getName();
if (!name1.equals(name2)) return false;
final PsiType[] superTypes = superSignatureCandidate.getParameterTypes();
final PsiType[] subTypes = subSignature.getParameterTypes();
if (subTypes.length != superTypes.length) return false;
for (int i = 0; i < subTypes.length - 1; i++) {
PsiType superType = TypeConversionUtil.erasure(superTypes[i]);
PsiType subType = subTypes[i];
if (!superType.isAssignableFrom(subType)) return false;
}
if (superTypes.length > 0) {
final PsiType lastSuperType = TypeConversionUtil.erasure(superTypes[superTypes.length - 1]);
final PsiType lastSubType = subTypes[superTypes.length - 1];
if (lastSuperType instanceof PsiArrayType && !(lastSubType instanceof PsiArrayType)) {
final PsiType componentType = ((PsiArrayType) lastSuperType).getComponentType();
if (!lastSubType.isConvertibleFrom(componentType)) return false;
} else {
if (!lastSuperType.isAssignableFrom(lastSubType)) return false;
}
}
return true;*/
return MethodSignatureUtil.isSubsignature(superSignatureCandidate, subSignature);
}
@@ -138,6 +138,7 @@ public abstract class GrTypeDefinitionImpl extends GroovyBaseElementImpl<GrTypeD
public ItemPresentation getPresentation() {
return new ItemPresentation() {
@Nullable
public String getPresentableText() {
return getName();
}
@@ -524,7 +525,14 @@ public abstract class GrTypeDefinitionImpl extends GroovyBaseElementImpl<GrTypeD
if (renameFile) {
final GroovyFileBase file = (GroovyFileBase)getContainingFile();
file.setName(name + "." + GroovyFileType.GROOVY_FILE_TYPE.getDefaultExtension());
final VirtualFile virtualFile = file.getVirtualFile();
final String ext;
if (virtualFile != null) {
ext = virtualFile.getExtension();
} else {
ext = GroovyFileType.GROOVY_FILE_TYPE.getDefaultExtension();
}
file.setName(name + "." + ext);
}
return this;
@@ -596,12 +604,12 @@ public abstract class GrTypeDefinitionImpl extends GroovyBaseElementImpl<GrTypeD
if (!(file instanceof GroovyFile)) return false;
final GroovyFile groovyFile = (GroovyFile)file;
if (groovyFile.isScript()) return false;
final GrTypeDefinition[] typeDefinitions = groovyFile.getTypeDefinitions();
final String name = getName();
final VirtualFile vFile = groovyFile.getVirtualFile();
return vFile != null && name != null && name.equals(vFile.getNameWithoutExtension());
}
@Nullable
public PsiElement getOriginalElement() {
return PsiImplUtil.getOriginalElement(this, getContainingFile());
}
@@ -0,0 +1,32 @@
/*
* Copyright 2000-2010 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;
import org.jetbrains.plugins.groovy.util.TestUtils;
/**
* @author Maxim.Medvedev
*/
public class ConvertJavaStyleArrayCreationTest extends GrIntentionTestCase{
@Override
protected String getBasePath() {
return TestUtils.getTestDataPath() + "intentions/convertJavaStyleArrayCreation/";
}
public void testConversion() {
doTest(GroovyIntentionsBundle.message("convert.java.style.array.creation.intention.name"), true);
}
}
@@ -56,39 +56,43 @@ public class ParameterToMapEntryTest extends GroovyFormatterTestCase {
}
*/
public void testParam1() throws Throwable {
public void testParam1() {
doTestImpl("A.groovy");
}
public void testFormatter() throws Throwable {
public void testFormatter() {
doTestImpl("A.groovy");
}
public void testClosureAtEnd() throws Throwable {
public void testClosureAtEnd() {
doTestImpl("A.groovy");
}
public void testClosure1() throws Throwable {
public void testClosure1() {
doTestImpl("A.groovy");
}
public void testNewMap() throws Throwable {
public void testNewMap() {
doTestImpl("A.groovy");
}
public void testTestError() throws Throwable {
public void testTestError() {
doTestImpl("A.groovy");
}
public void testSecondClosure() throws Throwable {
public void testSecondClosure() {
doTestImpl("A.groovy");
}
public void testVarArgs() throws Throwable {
public void testVarArgs() {
doTestImpl("A.groovy");
}
private void doTestImpl(String filePath) throws Throwable {
public void testCallMethod() {
doTestImpl("A.groovy");
}
private void doTestImpl(String filePath) {
myFixture.configureByFile(filePath);
int offset = myFixture.getEditor().getCaretModel().getOffset();
final PsiFile file = myFixture.getFile();
@@ -327,6 +327,12 @@ foo = 4"""
doInplaceRenameTest();
}
public void testExtensionOnClassRename() {
myFixture.configureByText "Foo.gpp", "class Foo {}"
myFixture.renameElement myFixture.findClass("Foo"), "Bar"
assert "gpp", myFixture.file.virtualFile.extension
}
private def doInplaceRenameTest() {
String prefix = TestUtils.getTestDataPath() + "groovy/refactoring/rename/" + getTestName(false)
myFixture.configureByFile prefix + ".groovy";
@@ -0,0 +1 @@
def foo = new Ob<caret>ject[] {1, 2, 3}
@@ -0,0 +1 @@
def foo = [1, 2, 3]
@@ -0,0 +1,3 @@
def clos = { int <caret>i -> println(i) }
clos(1)
clos.call(1)
+3
View File
@@ -0,0 +1,3 @@
def clos = { Map attrs -> println(attrs.i) }
clos(i: 1)
clos.call(i: 1)
@@ -10,7 +10,7 @@
// 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.zmlx.hg4idea;
package org.zmlx.hg4idea.test;
import com.intellij.execution.process.ProcessOutput;
import com.intellij.openapi.application.PluginPathManager;
@@ -24,7 +24,8 @@ import com.intellij.testFramework.fixtures.IdeaTestFixtureFactory;
import com.intellij.testFramework.fixtures.TempDirTestFixture;
import com.intellij.vcsUtil.VcsUtil;
import org.testng.annotations.BeforeMethod;
import org.zmlx.hg4idea.org.zmlx.hg4idea.test.TestChangeListManager;
import org.zmlx.hg4idea.HgFile;
import org.zmlx.hg4idea.HgVcs;
import java.io.*;
@@ -33,7 +34,7 @@ import static org.testng.Assert.assertTrue;
/**
* The ancestor of all hg4idea test cases.
*/
public abstract class AbstractHgTestCase extends AbstractVcsTestCase {
public abstract class HgAbstractTestCase extends AbstractVcsTestCase {
public static final String HG_EXECUTABLE_PATH = "IDEA_TEST_HG_EXECUTABLE_PATH";
@@ -10,7 +10,7 @@
// 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.zmlx.hg4idea;
package org.zmlx.hg4idea.test;
import com.intellij.openapi.vfs.VirtualFile;
import org.testng.annotations.Test;
@@ -18,7 +18,7 @@ import org.testng.annotations.Test;
/**
* Tests adding files to the Mercurial repository.
*/
public class HgAddTestCase extends AbstractHgTestCase {
public class HgAddTestCase extends HgAbstractTestCase {
/**
* 1. Create a file in the file system.
@@ -10,14 +10,14 @@
// 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.zmlx.hg4idea;
package org.zmlx.hg4idea.test;
import com.intellij.openapi.vfs.VirtualFile;
import org.testng.annotations.Test;
import java.io.File;
public class HgCopyTestCase extends AbstractHgTestCase {
public class HgCopyTestCase extends HgAbstractTestCase {
@Test
public void testCopyUnmodifiedFile() throws Exception {
@@ -10,7 +10,7 @@
// 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.zmlx.hg4idea;
package org.zmlx.hg4idea.test;
import com.intellij.openapi.vfs.VirtualFile;
import org.testng.Assert;
@@ -18,7 +18,7 @@ import org.testng.annotations.Test;
import java.io.File;
public class HgDeleteTestCase extends AbstractHgTestCase {
public class HgDeleteTestCase extends HgAbstractTestCase {
@Test
public void testDeleteUnmodifiedFile() throws Exception {
@@ -10,7 +10,7 @@
// 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.zmlx.hg4idea;
package org.zmlx.hg4idea.test;
import com.intellij.openapi.vcs.VcsConfiguration;
import com.intellij.openapi.vfs.VirtualFile;
@@ -19,12 +19,13 @@ import com.intellij.testFramework.fixtures.TempDirTestFixture;
import com.intellij.vcsUtil.VcsUtil;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.zmlx.hg4idea.HgVcs;
import java.io.File;
import static org.testng.Assert.assertTrue;
public class HgFromClonedTestCase extends AbstractHgTestCase {
public class HgFromClonedTestCase extends HgAbstractTestCase {
protected File remoteRepo;
protected File projectRepo;
@@ -1,10 +1,11 @@
package org.zmlx.hg4idea;
package org.zmlx.hg4idea.test;
import com.intellij.openapi.vcs.VcsException;
import com.intellij.openapi.vcs.history.VcsFileRevision;
import com.intellij.openapi.vcs.history.VcsHistorySession;
import com.intellij.vcsUtil.VcsUtil;
import org.testng.annotations.Test;
import org.zmlx.hg4idea.HgVcs;
import java.io.File;
import java.util.Collection;
@@ -16,7 +17,7 @@ import static org.testng.Assert.assertTrue;
/**
* HgHistoryTestCase tests retrieving file history and specific revisions.
*/
public class HgHistoryTestCase extends AbstractHgTestCase {
public class HgHistoryTestCase extends HgAbstractTestCase {
/**
* 1. Make two versions of a file (create, add, commit, modify, commit).
@@ -10,16 +10,17 @@
// 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.zmlx.hg4idea;
package org.zmlx.hg4idea.test;
import org.testng.annotations.Test;
import org.zmlx.hg4idea.HgFileRevision;
import org.zmlx.hg4idea.command.HgLogCommand;
import java.util.List;
import static org.testng.Assert.assertEquals;
public class HgLogTestCase extends AbstractHgTestCase {
public class HgLogTestCase extends HgAbstractTestCase {
@Test
public void testCommitMessagesWithMultipleLines() throws Exception {
@@ -10,14 +10,14 @@
// 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.zmlx.hg4idea;
package org.zmlx.hg4idea.test;
import com.intellij.openapi.vfs.VirtualFile;
import org.testng.annotations.Test;
import java.io.File;
public class HgMoveTestCase extends AbstractHgTestCase {
public class HgMoveTestCase extends HgAbstractTestCase {
@Test
public void testMoveNewFile() throws Exception {
@@ -10,14 +10,14 @@
// 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.zmlx.hg4idea;
package org.zmlx.hg4idea.test;
import com.intellij.openapi.vfs.VirtualFile;
import org.testng.annotations.Test;
import java.io.File;
public class HgRenameTestCase extends AbstractHgTestCase {
public class HgRenameTestCase extends HgAbstractTestCase {
@Test
public void testRenameUnmodifiedFile() throws Exception {
@@ -10,14 +10,14 @@
// 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.zmlx.hg4idea;
package org.zmlx.hg4idea.test;
import com.intellij.openapi.vfs.VirtualFile;
import org.testng.Assert;
import org.testng.annotations.Test;
import org.zmlx.hg4idea.command.HgResolveCommand;
public class HgResolveConflictTestCase extends AbstractHgTestCase {
public class HgResolveConflictTestCase extends HgAbstractTestCase {
public static final String BASE = "one\n" +
"conflicting\n" +
@@ -1,6 +1,7 @@
package org.zmlx.hg4idea;
package org.zmlx.hg4idea.test;
import org.testng.annotations.Test;
import org.zmlx.hg4idea.HgRevisionNumber;
import org.zmlx.hg4idea.command.HgCatCommand;
import org.zmlx.hg4idea.command.HgRevertCommand;
@@ -8,7 +9,7 @@ import java.nio.charset.Charset;
import static org.testng.Assert.assertEquals;
public class HgRevertTestCase extends AbstractHgTestCase {
public class HgRevertTestCase extends HgAbstractTestCase {
@Test
public void testRevertToCurrentRevision() throws Exception {
fillFile(myProjectRepo, new String[]{"file.txt"}, "initial contents");
@@ -10,7 +10,7 @@
// 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.zmlx.hg4idea;
package org.zmlx.hg4idea.test;
import com.intellij.execution.process.ProcessOutput;
import com.intellij.openapi.progress.EmptyProgressIndicator;
@@ -18,6 +18,8 @@ import com.intellij.openapi.vcs.VcsException;
import com.intellij.openapi.vcs.update.UpdatedFiles;
import com.intellij.openapi.vfs.VirtualFile;
import org.testng.annotations.Test;
import org.zmlx.hg4idea.HgFile;
import org.zmlx.hg4idea.HgRevisionNumber;
import org.zmlx.hg4idea.command.*;
import org.zmlx.hg4idea.provider.update.HgRegularUpdater;
@@ -10,7 +10,7 @@
// 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.zmlx.hg4idea;
package org.zmlx.hg4idea.test;
import org.testng.Assert;
import org.testng.annotations.Test;
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.zmlx.hg4idea.org.zmlx.hg4idea.test;
package org.zmlx.hg4idea.test;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.project.Project;
@@ -16,12 +16,14 @@
package org.jetbrains.idea.svn;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.MessageType;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.vcs.changes.ui.ChangesViewBalloonProblemNotifier;
import com.intellij.ui.GuiUtils;
import com.intellij.util.containers.SoftHashMap;
import com.intellij.util.net.HttpConfigurable;
import org.jetbrains.annotations.Nullable;
@@ -35,36 +37,41 @@ import org.tmatesoft.svn.core.io.SVNRepository;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.Iterator;
import java.util.Map;
import java.util.StringTokenizer;
import java.util.concurrent.atomic.AtomicBoolean;
/**
* @author alex
*/
public class SvnAuthenticationManager extends DefaultSVNAuthenticationManager {
private static final Logger LOG = Logger.getInstance(SvnAuthenticationManager.class.getName());
private final Project myProject;
private final File myConfigDirectory;
private PersistentAuthenticationProviderProxy myPersistentAuthenticationProviderProxy;
private SvnConfiguration myConfig;
private AtomicBoolean myStoreInPlainTextAnyway = new AtomicBoolean(false);
public SvnAuthenticationManager(final Project project, final File configDirectory) {
super(configDirectory, true, null, null);
myProject = project;
super(configDirectory, true, null, null);
myProject = project;
myConfigDirectory = configDirectory;
myConfig = SvnConfiguration.getInstance(myProject);
if (myPersistentAuthenticationProviderProxy != null) {
myPersistentAuthenticationProviderProxy.setProject(myProject);
}
if (myPersistentAuthenticationProviderProxy != null) {
myPersistentAuthenticationProviderProxy.setProject(myProject);
}
}
@Override
protected ISVNAuthenticationProvider createCacheAuthenticationProvider(File authDir, String userName) {
myStoreInPlainTextAnyway = new AtomicBoolean(false);
myPersistentAuthenticationProviderProxy = new PersistentAuthenticationProviderProxy(super.createCacheAuthenticationProvider(authDir, userName), authDir);
return myPersistentAuthenticationProviderProxy;
}
private static class PersistentAuthenticationProviderProxy implements ISVNAuthenticationProvider, IPersistentAuthenticationProvider {
private class PersistentAuthenticationProviderProxy implements ISVNAuthenticationProvider, IPersistentAuthenticationProvider {
private final Map<SvnAuthWrapperEqualable, Long> myRewritePreventer;
private static final long ourRefreshInterval = 6000 * 1000;
private final ISVNAuthenticationProvider myDelegate;
@@ -84,7 +91,7 @@ public class SvnAuthenticationManager extends DefaultSVNAuthenticationManager {
public SVNAuthentication requestClientAuthentication(final String kind, final SVNURL url, final String realm, final SVNErrorMessage errorMessage,
final SVNAuthentication previousAuth,
final boolean authMayBeStored) {
return myDelegate.requestClientAuthentication(kind, url, realm, errorMessage, previousAuth, authMayBeStored);
return myDelegate.requestClientAuthentication(kind, url, realm, errorMessage, previousAuth, false);
}
public int acceptServerAuthentication(final SVNURL url, final String realm, final Object certificate, final boolean resultMayBeStored) {
@@ -101,7 +108,22 @@ public class SvnAuthenticationManager extends DefaultSVNAuthenticationManager {
File authFile = new File(dir, fileName);
if ((! authFile.exists()) || recent == null || ((recent != null) && ((currTime - recent.longValue()) > ourRefreshInterval))) {
((IPersistentAuthenticationProvider) myDelegate).saveAuthentication(auth, kind, realm);
if (auth.isStorageAllowed() && ISVNAuthenticationManager.USERNAME != kind) {
try {
GuiUtils.runOrInvokeAndWait(new Runnable() {
public void run() {
checkContinueSaveCredentials(auth, kind, realm);
}
});
} catch (InvocationTargetException e) {
LOG.error(e);
} catch (InterruptedException e) {
LOG.error(e);
}
}
((DefaultSVNAuthenticationManager.IPersistentAuthenticationProvider)myDelegate).saveAuthentication(auth, kind, realm);
// do not make password file readonly
setWriteable(authFile);
@@ -305,7 +327,7 @@ public class SvnAuthenticationManager extends DefaultSVNAuthenticationManager {
catch (SVNException e) {
return false;
}
final String host = svnurl.getHost();
return matches(patterns, host) && (! matches(exceptions, host));
}
@@ -419,52 +441,61 @@ public class SvnAuthenticationManager extends DefaultSVNAuthenticationManager {
}
// check can encrypt
if (! (SystemInfo.isWindows && SVNJNAUtil.isWinCryptEnabled())) {
if (!(SystemInfo.isWindows && SVNJNAUtil.isWinCryptEnabled())) {
if (ISVNAuthenticationManager.SSL.equals(kind)) {
try {
if (! isStorePlainTextPassphrases(realm, auth)) {
final SVNSSLAuthentication svnsslAuthentication = (SVNSSLAuthentication)auth;
ApplicationManager.getApplication().invokeLater(new Runnable() {
public void run() {
Messages.showWarningDialog(myProject, "Your passphrase for client certificate:\n\n" +
svnsslAuthentication.getCertificateFile().getPath() +
"\n\ncan only be stored to disk unencrypted. (Encryption is not supported)\n\n" +
"But storage in plain text is not allowed.\nTo allow plain text passphrases caching, set \"store-ssl-client-cert-pp-plaintext=yes\"",
"Cannot save passphrase");
}
});
/*ChangesViewBalloonProblemNotifier.showMe(myProject, "Your passphrase for client certificate:\n" +
svnsslAuthentication.getCertificateFile().getPath() +
"\ncan only be stored to disk unencrypted! (Encryption is not supported)\n" +
"But storage in plain text is not allowed.\nTo allow plain text passphrases caching, set \"store-ssl-client-cert-pp-plaintext\"=\"yes\"", MessageType.ERROR);*/
return false;
if (!isStorePlainTextPassphrases(realm, auth)) {
return askToStoreUnencrypted("Store the passphrase in plaintext?",
String.format("Your passphrase for client certificate:\n%s\ncan only be stored to disk unencrypted. Would you like to store it in plaintext?",
((SVNSSLAuthentication)auth).getCertificateFile().getPath()));
}
}
catch (SVNException e) {
// should not occur, anyway means not allowed
} catch (SVNException e) {
LOG.error(e); // should not occur, anyway means not allowed
}
} else {
try {
if (! isStorePlainTextPasswords(realm, auth)) {
ApplicationManager.getApplication().invokeLater(new Runnable() {
public void run() {
Messages.showWarningDialog(myProject, "Your password for authentication realm:\n\n" + realm +
"\n\ncan only be stored to disk unencrypted. (Encryption is not supported)\n\n" +
"But storage in plain text is not allowed.\nTo allow plain text passwords caching, set \"store-plaintext-passwords=yes\"",
"Cannot save password");
}
});
/*ChangesViewBalloonProblemNotifier.showMe(myProject, "Your password for authentication realm:\n" + realm +
"\ncan only be stored to disk unencrypted! (Encryption is not supported)\n" +
"But storage in plain text is not allowed.\nTo allow plain text passwords caching, set \"store-plaintext-passwords\"=\"yes\"", MessageType.ERROR);*/
return false;
if (!isStorePlainTextPasswords(realm, auth)) {
return askToStoreUnencrypted("Store the password in plaintext?",
String.format("Your password for authentication realm:\n%s\ncan only be stored to disk unencrypted. Would you like to store it in plaintext?",
realm));
}
}
catch (SVNException e) {
//
} catch (SVNException e) {
LOG.error(e);
}
}
}
return true;
}
}
@Override
protected boolean isStorePlainTextPasswords(String realm, SVNAuthentication auth) throws SVNException {
// normally check user preferences, but the user may override them via the dialog from checkContinueSaveCredentials()
return myStoreInPlainTextAnyway.get() || super.isStorePlainTextPasswords(realm, auth);
}
@Override
protected boolean isStorePlainTextPassphrases(String realm, SVNAuthentication auth) throws SVNException {
return myStoreInPlainTextAnyway.get() || super.isStorePlainTextPassphrases(realm, auth);
}
/**
* Shows a yes/no question whether user wants to store his password in plain text and returns his answer.
* Also updates the 'myStoreInPlainTextAnyway' variable correspondingly.
* This method shuld be called from the event dispatching thread.
* @param title title of the questioning dialog.
* @param message questioning message to be displayed.
* @return true if user agrees to store his password in plaintext, false if he doesn't.
*/
private boolean askToStoreUnencrypted(String title, String message) {
final int answer = Messages.showYesNoDialog(myProject, message, title, Messages.getQuestionIcon());
if (answer == 0) {
myStoreInPlainTextAnyway.set(true);
} else {
myStoreInPlainTextAnyway.set(false);
ChangesViewBalloonProblemNotifier.showMe(myProject, "Cannot store password", MessageType.ERROR);
}
return myStoreInPlainTextAnyway.get();
}
}
@@ -173,15 +173,9 @@ public class SvnInteractiveAuthenticationProvider implements ISVNAuthenticationP
}
log("3 authentication result: " + result[0]);
}
final boolean wasCanceled = result[0] == null;
callState.setWasCancelled(wasCanceled);
if ((! wasCanceled) && (ISVNAuthenticationManager.USERNAME != kind) && (result[0].isStorageAllowed())) {
ApplicationManager.getApplication().executeOnPooledThread(new Runnable() {
public void run() {
myManager.checkContinueSaveCredentials(result[0], kind, realm);
}
});
}
return result[0];
}
@@ -17,7 +17,6 @@ package com.intellij.xml.util;
import com.intellij.codeInsight.daemon.impl.analysis.XmlHighlightVisitor;
import com.intellij.lang.Language;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.UserDataCache;
@@ -31,6 +30,7 @@ import com.intellij.psi.util.CachedValueProvider;
import com.intellij.psi.util.CachedValuesManager;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.xml.*;
import com.intellij.util.NullableFunction;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.xml.XmlAttributeDescriptor;
import com.intellij.xml.XmlElementDescriptor;
@@ -102,14 +102,14 @@ public class XmlRefCountHolder {
}
else if (!soft) {
// mark as duplicate
Pair<XmlAttributeValue, Boolean> notSoft = ContainerUtil.find(list, new Condition<Pair<XmlAttributeValue, Boolean>>() {
List<XmlAttributeValue> notSoft = ContainerUtil.mapNotNull(list, new NullableFunction<Pair<XmlAttributeValue, Boolean>, XmlAttributeValue>() {
@Override
public boolean value(Pair<XmlAttributeValue, Boolean> xmlAttributeValueBooleanPair) {
return !xmlAttributeValueBooleanPair.second;
public XmlAttributeValue fun(Pair<XmlAttributeValue, Boolean> pair) {
return pair.second ? null : pair.first;
}
});
if (notSoft != null) {
myPossiblyDuplicateIds.add(notSoft.first);
if (!notSoft.isEmpty()) {
myPossiblyDuplicateIds.addAll(notSoft);
myPossiblyDuplicateIds.add(attributeValue);
}
}
@@ -20,7 +20,6 @@ import org.jetbrains.annotations.Nullable;
public interface XmlTagChild extends XmlElement{
XmlTagChild[] EMPTY_ARRAY = new XmlTagChild[0];
@Nullable
XmlTag getParentTag();
@Nullable