mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Merge remote-tracking branch 'origin/master'
This commit is contained in:
Generated
+1
@@ -79,6 +79,7 @@
|
||||
<module fileurl="file://$PROJECT_DIR$/platform/platform-main/platform-main.iml" filepath="$PROJECT_DIR$/platform/platform-main/platform-main.iml" group="platform" />
|
||||
<module fileurl="file://$PROJECT_DIR$/platform/platform-resources/platform-resources.iml" filepath="$PROJECT_DIR$/platform/platform-resources/platform-resources.iml" group="platform" />
|
||||
<module fileurl="file://$PROJECT_DIR$/platform/platform-resources-en/platform-resources-en.iml" filepath="$PROJECT_DIR$/platform/platform-resources-en/platform-resources-en.iml" group="platform" />
|
||||
<module fileurl="file://$PROJECT_DIR$/platform/platform-tests/platform-tests.iml" filepath="$PROJECT_DIR$/platform/platform-tests/platform-tests.iml" group="platform" />
|
||||
<module fileurl="file://$PROJECT_DIR$/plugins/properties/properties.iml" filepath="$PROJECT_DIR$/plugins/properties/properties.iml" group="plugins" />
|
||||
<module fileurl="file://$PROJECT_DIR$/xml/relaxng/relaxng.iml" filepath="$PROJECT_DIR$/xml/relaxng/relaxng.iml" group="plugins" />
|
||||
<module fileurl="file://$PROJECT_DIR$/resources/resources.iml" filepath="$PROJECT_DIR$/resources/resources.iml" />
|
||||
|
||||
+7
-1
@@ -48,6 +48,7 @@ public class DebuggerDataViewsConfigurable implements SearchableConfigurable {
|
||||
private JCheckBox myCbHideNullArrayElements;
|
||||
private JCheckBox myCbShowStatic;
|
||||
private JCheckBox myCbShowDeclaredType;
|
||||
private JCheckBox myCbShowFQNames;
|
||||
private JCheckBox myCbShowObjectId;
|
||||
|
||||
private StateRestoringCheckBox myCbShowStaticFinalFields;
|
||||
@@ -102,6 +103,7 @@ public class DebuggerDataViewsConfigurable implements SearchableConfigurable {
|
||||
}
|
||||
});
|
||||
myCbShowDeclaredType = new JCheckBox(DebuggerBundle.message("label.base.renderer.configurable.show.declared.type"));
|
||||
myCbShowFQNames = new JCheckBox(DebuggerBundle.message("label.base.renderer.configurable.show.fq.names"));
|
||||
myCbShowObjectId = new JCheckBox(DebuggerBundle.message("label.base.renderer.configurable.show.object.id"));
|
||||
|
||||
myCbEnableToString = new JCheckBox(DebuggerBundle.message("label.base.renderer.configurable.enable.tostring"));
|
||||
@@ -149,7 +151,8 @@ public class DebuggerDataViewsConfigurable implements SearchableConfigurable {
|
||||
showPanel.add(myCbShowObjectId, new GridBagConstraints(0, GridBagConstraints.RELATIVE, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(4, 0, 0, 0), 0, 0));
|
||||
showPanel.add(myCbShowSyntheticFields, new GridBagConstraints(1, GridBagConstraints.RELATIVE, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0, 10, 0, 0), 0, 0));
|
||||
showPanel.add(myCbShowStatic, new GridBagConstraints(1, GridBagConstraints.RELATIVE, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(4, 10, 0, 0), 0, 0));
|
||||
showPanel.add(myCbShowStaticFinalFields, new GridBagConstraints(2, 1, 1, 1, 1.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(4, 10, 0, 0), 0, 0));
|
||||
showPanel.add(myCbShowStaticFinalFields, new GridBagConstraints(2, 1, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(4, 10, 0, 0), 0, 0));
|
||||
showPanel.add(myCbShowFQNames, new GridBagConstraints(3, GridBagConstraints.RELATIVE, 1, 1, 1.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0, 10, 0, 0), 0, 0));
|
||||
|
||||
panel.add(showPanel, new GridBagConstraints(0, GridBagConstraints.RELATIVE, 3, 1, 1.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(4, 0, 0, 0), 0, 0));
|
||||
|
||||
@@ -193,6 +196,7 @@ public class DebuggerDataViewsConfigurable implements SearchableConfigurable {
|
||||
classRenderer.SHOW_STATIC_FINAL = myCbShowStaticFinalFields.isSelectedWhenSelectable();
|
||||
classRenderer.SHOW_SYNTHETICS = myCbShowSyntheticFields.isSelected();
|
||||
classRenderer.SHOW_DECLARED_TYPE = myCbShowDeclaredType.isSelected();
|
||||
classRenderer.SHOW_FQ_TYPE_NAMES = myCbShowFQNames.isSelected();
|
||||
classRenderer.SHOW_OBJECT_ID = myCbShowObjectId.isSelected();
|
||||
|
||||
final ToStringRenderer toStringRenderer = rendererSettings.getToStringRenderer();
|
||||
@@ -226,6 +230,7 @@ public class DebuggerDataViewsConfigurable implements SearchableConfigurable {
|
||||
myCbShowStaticFinalFields.makeUnselectable(false);
|
||||
}
|
||||
myCbShowDeclaredType.setSelected(classRenderer.SHOW_DECLARED_TYPE);
|
||||
myCbShowFQNames.setSelected(classRenderer.SHOW_FQ_TYPE_NAMES);
|
||||
myCbShowObjectId.setSelected(classRenderer.SHOW_OBJECT_ID);
|
||||
|
||||
final ToStringRenderer toStringRenderer = rendererSettings.getToStringRenderer();
|
||||
@@ -275,6 +280,7 @@ public class DebuggerDataViewsConfigurable implements SearchableConfigurable {
|
||||
(classRenderer.SHOW_STATIC_FINAL != myCbShowStaticFinalFields.isSelectedWhenSelectable()) ||
|
||||
(classRenderer.SHOW_SYNTHETICS != myCbShowSyntheticFields.isSelected()) ||
|
||||
(classRenderer.SHOW_DECLARED_TYPE != myCbShowDeclaredType.isSelected()) ||
|
||||
(classRenderer.SHOW_FQ_TYPE_NAMES != myCbShowFQNames.isSelected()) ||
|
||||
(classRenderer.SHOW_OBJECT_ID != myCbShowObjectId.isSelected());
|
||||
if (isClassRendererModified) {
|
||||
return true;
|
||||
|
||||
@@ -158,7 +158,7 @@ public class FieldDescriptorImpl extends ValueDescriptorImpl implements FieldDes
|
||||
buf.append(getName());
|
||||
if (classRenderer.SHOW_DECLARED_TYPE) {
|
||||
buf.append(": ");
|
||||
buf.append(myField.typeName());
|
||||
buf.append(classRenderer.renderTypeName(myField.typeName()));
|
||||
}
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
+1
-1
@@ -121,7 +121,7 @@ public class LocalVariableDescriptorImpl extends ValueDescriptorImpl implements
|
||||
buf.append(getName());
|
||||
if (classRenderer.SHOW_DECLARED_TYPE) {
|
||||
buf.append(": ");
|
||||
buf.append(myTypeName);
|
||||
buf.append(classRenderer.renderTypeName(myTypeName));
|
||||
}
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
+4
-1
@@ -23,7 +23,9 @@ package com.intellij.debugger.ui.impl.watch;
|
||||
import com.intellij.debugger.engine.DebuggerManagerThreadImpl;
|
||||
import com.intellij.debugger.engine.evaluation.EvaluateException;
|
||||
import com.intellij.debugger.engine.evaluation.EvaluationContextImpl;
|
||||
import com.intellij.debugger.settings.NodeRendererSettings;
|
||||
import com.intellij.debugger.ui.tree.StaticDescriptor;
|
||||
import com.intellij.debugger.ui.tree.render.ClassRenderer;
|
||||
import com.intellij.debugger.ui.tree.render.DescriptorLabelListener;
|
||||
import com.sun.jdi.Field;
|
||||
import com.sun.jdi.ReferenceType;
|
||||
@@ -64,6 +66,7 @@ public class StaticDescriptorImpl extends NodeDescriptorImpl implements StaticDe
|
||||
|
||||
protected String calcRepresentation(EvaluationContextImpl context, DescriptorLabelListener descriptorLabelListener) throws EvaluateException {
|
||||
DebuggerManagerThreadImpl.assertIsManagerThread();
|
||||
return getName() + " = " + myType.name();
|
||||
final ClassRenderer classRenderer = NodeRendererSettings.getInstance().getClassRenderer();
|
||||
return getName() + " = " + classRenderer.renderTypeName(myType.name());
|
||||
}
|
||||
}
|
||||
+6
-2
@@ -27,7 +27,9 @@ import com.intellij.debugger.engine.evaluation.EvaluateExceptionUtil;
|
||||
import com.intellij.debugger.engine.evaluation.EvaluationContextImpl;
|
||||
import com.intellij.debugger.engine.evaluation.TextWithImports;
|
||||
import com.intellij.debugger.impl.DebuggerUtilsEx;
|
||||
import com.intellij.debugger.settings.NodeRendererSettings;
|
||||
import com.intellij.debugger.ui.tree.UserExpressionDescriptor;
|
||||
import com.intellij.debugger.ui.tree.render.ClassRenderer;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.PsiClass;
|
||||
import com.intellij.psi.PsiCodeFragment;
|
||||
@@ -57,8 +59,10 @@ public class UserExpressionDescriptorImpl extends EvaluationDescriptor implement
|
||||
try {
|
||||
buffer.append(getName());
|
||||
buffer.append(": ");
|
||||
if(getValue() != null) {
|
||||
buffer.append(getValue().type().name());
|
||||
final Value value = getValue();
|
||||
if(value != null) {
|
||||
final ClassRenderer classRenderer = NodeRendererSettings.getInstance().getClassRenderer();
|
||||
buffer.append(classRenderer.renderTypeName(value.type().name()));
|
||||
}
|
||||
|
||||
return buffer.toString();
|
||||
|
||||
@@ -378,7 +378,7 @@ public abstract class ValueDescriptorImpl extends NodeDescriptorImpl implements
|
||||
if (showConcreteType || classRenderer.SHOW_OBJECT_ID) {
|
||||
buf.append('{');
|
||||
if (showConcreteType) {
|
||||
buf.append(objRef.type().name());
|
||||
buf.append(classRenderer.renderTypeName(objRef.type().name()));
|
||||
}
|
||||
if (classRenderer.SHOW_OBJECT_ID) {
|
||||
buf.append('@');
|
||||
|
||||
@@ -63,6 +63,7 @@ public class ClassRenderer extends NodeRendererImpl{
|
||||
public boolean SHOW_STATIC = false;
|
||||
public boolean SHOW_STATIC_FINAL = false;
|
||||
|
||||
public boolean SHOW_FQ_TYPE_NAMES = true;
|
||||
public boolean SHOW_DECLARED_TYPE = false;
|
||||
public boolean SHOW_OBJECT_ID = true;
|
||||
|
||||
@@ -70,6 +71,17 @@ public class ClassRenderer extends NodeRendererImpl{
|
||||
myProperties.setEnabled(true);
|
||||
}
|
||||
|
||||
public final String renderTypeName(final String typeName) {
|
||||
if (SHOW_FQ_TYPE_NAMES) {
|
||||
return typeName;
|
||||
}
|
||||
final int dotIndex = typeName.lastIndexOf('.');
|
||||
if (dotIndex > 0) {
|
||||
return typeName.substring(dotIndex + 1);
|
||||
}
|
||||
return typeName;
|
||||
}
|
||||
|
||||
public String getUniqueId() {
|
||||
return UNIQUE_ID;
|
||||
}
|
||||
|
||||
+28
-1
@@ -36,6 +36,7 @@ import com.intellij.openapi.roots.ui.configuration.projectRoot.daemon.ProjectStr
|
||||
import com.intellij.openapi.ui.DetailsComponent;
|
||||
import com.intellij.openapi.ui.NamedConfigurable;
|
||||
import com.intellij.openapi.util.IconLoader;
|
||||
import com.intellij.ui.treeStructure.filtered.FilteringTreeBuilder;
|
||||
import com.intellij.util.ui.tree.TreeUtil;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -43,6 +44,8 @@ import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.event.ComponentAdapter;
|
||||
import java.awt.event.ComponentEvent;
|
||||
import java.util.*;
|
||||
import java.util.List;
|
||||
|
||||
@@ -55,6 +58,7 @@ public class FacetStructureConfigurable extends BaseStructureConfigurable {
|
||||
private final Map<FacetType<?, ?>, FacetTypeEditor> myFacetTypeEditors = new HashMap<FacetType<?,?>, FacetTypeEditor>();
|
||||
private MultipleFacetSettingsEditor myCurrentMultipleSettingsEditor;
|
||||
@NonNls private static final String NO_FRAMEWORKS_NODE = "No facets are configured";
|
||||
private boolean myTreeWasInitialized;
|
||||
|
||||
public FacetStructureConfigurable(final Project project, ModuleManager moduleManager) {
|
||||
super(project);
|
||||
@@ -77,7 +81,30 @@ public class FacetStructureConfigurable extends BaseStructureConfigurable {
|
||||
@Override
|
||||
protected void initTree() {
|
||||
super.initTree();
|
||||
myTree.setCellRenderer(new FacetsTreeCellRenderer());
|
||||
if (!myTreeWasInitialized) {
|
||||
myTreeWasInitialized = true;
|
||||
myTree.setCellRenderer(new FacetsTreeCellRenderer());
|
||||
myTree.addComponentListener(new ComponentAdapter() {
|
||||
@Override
|
||||
public void componentResized(ComponentEvent e) {
|
||||
revalidateTree();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void componentMoved(ComponentEvent e) {
|
||||
revalidateTree();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void componentShown(ComponentEvent e) {
|
||||
revalidateTree();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private void revalidateTree() {
|
||||
FilteringTreeBuilder.revalidateTree(myTree);
|
||||
}
|
||||
|
||||
protected void loadTree() {
|
||||
|
||||
+2
-2
@@ -56,8 +56,8 @@ public class FacetsTreeCellRenderer extends GroupedElementsRenderer.Tree impleme
|
||||
final Icon icon = configurable.getIcon(expanded);
|
||||
final boolean showSeparator = configurable instanceof FrameworkDetectionConfigurable;
|
||||
int width = -1;
|
||||
if (showSeparator) {
|
||||
final int treeWidth = tree.getSize().width;
|
||||
if (showSeparator && tree.isVisible()) {
|
||||
final int treeWidth = tree.getVisibleRect().width - 4;
|
||||
if (treeWidth > 0) {
|
||||
width = treeWidth;
|
||||
}
|
||||
|
||||
+21
-18
@@ -21,6 +21,7 @@ import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.patterns.ElementPattern;
|
||||
import com.intellij.patterns.PsiJavaPatterns;
|
||||
import com.intellij.pom.java.LanguageLevel;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.codeStyle.CodeStyleManager;
|
||||
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
|
||||
@@ -103,7 +104,8 @@ public class JavaMemberNameCompletionContributor extends CompletionContributor {
|
||||
|
||||
private static void completeLocalVariableName(Set<LookupElement> set, PrefixMatcher matcher, PsiVariable var, boolean includeOverlapped) {
|
||||
FeatureUsageTracker.getInstance().triggerFeatureUsed("editing.completion.variable.name");
|
||||
final JavaCodeStyleManager codeStyleManager = JavaCodeStyleManager.getInstance(var.getProject());
|
||||
Project project = var.getProject();
|
||||
final JavaCodeStyleManager codeStyleManager = JavaCodeStyleManager.getInstance(project);
|
||||
final VariableKind variableKind = codeStyleManager.getVariableKind(var);
|
||||
|
||||
String propertyName = null;
|
||||
@@ -119,7 +121,7 @@ public class JavaMemberNameCompletionContributor extends CompletionContributor {
|
||||
SuggestedNameInfo suggestedNameInfo = codeStyleManager.suggestVariableName(variableKind, propertyName, null, type, StringUtil.isEmpty(matcher.getPrefix()));
|
||||
suggestedNameInfo = codeStyleManager.suggestUniqueVariableName(suggestedNameInfo, var, false);
|
||||
final String[] suggestedNames = suggestedNameInfo.names;
|
||||
addLookupItems(set, suggestedNameInfo, matcher, suggestedNames);
|
||||
addLookupItems(set, suggestedNameInfo, matcher, project, suggestedNames);
|
||||
if (set.isEmpty()) {
|
||||
if (type.equalsToText(CommonClassNames.JAVA_LANG_OBJECT) && matcher.prefixMatches("object")) {
|
||||
set.add(LookupElementBuilder.create("object"));
|
||||
@@ -130,16 +132,16 @@ public class JavaMemberNameCompletionContributor extends CompletionContributor {
|
||||
}
|
||||
|
||||
if (set.isEmpty() && includeOverlapped) {
|
||||
addLookupItems(set, null, matcher, getOverlappedNameVersions(matcher.getPrefix(), suggestedNames, ""));
|
||||
addLookupItems(set, null, matcher, project, getOverlappedNameVersions(matcher.getPrefix(), suggestedNames, ""));
|
||||
}
|
||||
PsiElement parent = PsiTreeUtil.getParentOfType(var, PsiCodeBlock.class);
|
||||
if(parent == null) parent = PsiTreeUtil.getParentOfType(var, PsiMethod.class);
|
||||
addLookupItems(set, suggestedNameInfo, matcher, getUnresolvedReferences(parent, false));
|
||||
addLookupItems(set, suggestedNameInfo, matcher, project, getUnresolvedReferences(parent, false));
|
||||
|
||||
PsiExpression initializer = var.getInitializer();
|
||||
if (initializer != null) {
|
||||
SuggestedNameInfo initializerSuggestions = IntroduceVariableBase.getSuggestedName(type, initializer);
|
||||
addLookupItems(set, initializerSuggestions, matcher, initializerSuggestions.names);
|
||||
addLookupItems(set, initializerSuggestions, matcher, project, initializerSuggestions.names);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -216,18 +218,19 @@ public class JavaMemberNameCompletionContributor extends CompletionContributor {
|
||||
private static void completeFieldName(Set<LookupElement> set, PsiField var, final PrefixMatcher matcher, boolean includeOverlapped) {
|
||||
FeatureUsageTracker.getInstance().triggerFeatureUsed("editing.completion.variable.name");
|
||||
|
||||
JavaCodeStyleManager codeStyleManager = JavaCodeStyleManager.getInstance(var.getProject());
|
||||
final VariableKind variableKind = JavaCodeStyleManager.getInstance(var.getProject()).getVariableKind(var);
|
||||
Project project = var.getProject();
|
||||
JavaCodeStyleManager codeStyleManager = JavaCodeStyleManager.getInstance(project);
|
||||
final VariableKind variableKind = JavaCodeStyleManager.getInstance(project).getVariableKind(var);
|
||||
|
||||
final String prefix = matcher.getPrefix();
|
||||
if (PsiType.VOID.equals(var.getType()) || psiField().inClass(psiClass().isInterface()).accepts(var)) {
|
||||
completeVariableNameForRefactoring(var.getProject(), set, matcher, var.getType(), variableKind, includeOverlapped, true);
|
||||
completeVariableNameForRefactoring(project, set, matcher, var.getType(), variableKind, includeOverlapped, true);
|
||||
return;
|
||||
}
|
||||
|
||||
SuggestedNameInfo suggestedNameInfo = codeStyleManager.suggestVariableName(variableKind, null, null, var.getType());
|
||||
final String[] suggestedNames = suggestedNameInfo.names;
|
||||
addLookupItems(set, suggestedNameInfo, matcher, suggestedNames);
|
||||
addLookupItems(set, suggestedNameInfo, matcher, project, suggestedNames);
|
||||
|
||||
if (set.isEmpty() && includeOverlapped) {
|
||||
// use suggested names as suffixes
|
||||
@@ -238,17 +241,17 @@ public class JavaMemberNameCompletionContributor extends CompletionContributor {
|
||||
}
|
||||
|
||||
|
||||
addLookupItems(set, null, matcher, getOverlappedNameVersions(prefix, suggestedNames, requiredSuffix));
|
||||
addLookupItems(set, null, matcher, project, getOverlappedNameVersions(prefix, suggestedNames, requiredSuffix));
|
||||
}
|
||||
|
||||
addLookupItems(set, suggestedNameInfo, matcher, getUnresolvedReferences(var.getParent(), false));
|
||||
addLookupItems(set, suggestedNameInfo, matcher, project, getUnresolvedReferences(var.getParent(), false));
|
||||
|
||||
PsiExpression initializer = var.getInitializer();
|
||||
PsiClass containingClass = var.getContainingClass();
|
||||
if (initializer != null && containingClass != null) {
|
||||
SuggestedNameInfo initializerSuggestions = InplaceIntroduceFieldPopup.
|
||||
suggestFieldName(var.getType(), null, initializer, var.hasModifierProperty(PsiModifier.STATIC), containingClass);
|
||||
addLookupItems(set, initializerSuggestions, matcher, initializerSuggestions.names);
|
||||
addLookupItems(set, initializerSuggestions, matcher, project, initializerSuggestions.names);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -261,7 +264,7 @@ public class JavaMemberNameCompletionContributor extends CompletionContributor {
|
||||
SuggestedNameInfo suggestedNameInfo = codeStyleManager.suggestVariableName(varKind, null, null, varType);
|
||||
final String[] strings = completeVariableNameForRefactoring(codeStyleManager, matcher, varType, varKind, suggestedNameInfo,
|
||||
includeOverlapped, methodPrefix);
|
||||
addLookupItems(set, suggestedNameInfo, matcher, strings);
|
||||
addLookupItems(set, suggestedNameInfo, matcher, project, strings);
|
||||
}
|
||||
|
||||
public static String[] completeVariableNameForRefactoring(JavaCodeStyleManager codeStyleManager,
|
||||
@@ -303,7 +306,7 @@ public class JavaMemberNameCompletionContributor extends CompletionContributor {
|
||||
if (containingClass != null) {
|
||||
final String name = containingClass.getName();
|
||||
if (StringUtil.isNotEmpty(name)) {
|
||||
addLookupItems(set, null, matcher, name);
|
||||
addLookupItems(set, null, matcher, element.getProject(), name);
|
||||
}
|
||||
}
|
||||
return;
|
||||
@@ -312,9 +315,9 @@ public class JavaMemberNameCompletionContributor extends CompletionContributor {
|
||||
|
||||
PsiClass ourClassParent = PsiTreeUtil.getParentOfType(element, PsiClass.class);
|
||||
if (ourClassParent == null) return;
|
||||
addLookupItems(set, null, matcher, getUnresolvedReferences(ourClassParent, true));
|
||||
addLookupItems(set, null, matcher, element.getProject(), getUnresolvedReferences(ourClassParent, true));
|
||||
|
||||
addLookupItems(set, null, matcher, getPropertiesHandlersNames(
|
||||
addLookupItems(set, null, matcher, element.getProject(), getPropertiesHandlersNames(
|
||||
ourClassParent,
|
||||
((PsiModifierListOwner)element).hasModifierProperty(PsiModifier.STATIC),
|
||||
PsiUtil.getTypeByPsiElement(element), element));
|
||||
@@ -360,11 +363,11 @@ public class JavaMemberNameCompletionContributor extends CompletionContributor {
|
||||
return result.result;
|
||||
}
|
||||
|
||||
private static void addLookupItems(Set<LookupElement> lookupElements, @Nullable final SuggestedNameInfo callback, PrefixMatcher matcher, String... strings) {
|
||||
private static void addLookupItems(Set<LookupElement> lookupElements, @Nullable final SuggestedNameInfo callback, PrefixMatcher matcher, Project project, String... strings) {
|
||||
outer:
|
||||
for (int i = 0; i < strings.length; i++) {
|
||||
String name = strings[i];
|
||||
if (!matcher.prefixMatches(name)) {
|
||||
if (!matcher.prefixMatches(name) || !JavaPsiFacade.getInstance(project).getNameHelper().isIdentifier(name, LanguageLevel.HIGHEST)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
+21
-37
@@ -17,54 +17,38 @@ package com.intellij.codeInsight.completion;
|
||||
|
||||
import com.intellij.codeInsight.lookup.AutoCompletionPolicy;
|
||||
import com.intellij.codeInsight.lookup.LookupElement;
|
||||
import com.intellij.openapi.util.Ref;
|
||||
import com.intellij.util.Consumer;
|
||||
|
||||
/**
|
||||
* @author peter
|
||||
*/
|
||||
public class JavaNoVariantsDelegator extends CompletionContributor {
|
||||
public class JavaNoVariantsDelegator extends NoVariantsDelegator {
|
||||
|
||||
@Override
|
||||
public void fillCompletionVariants(final CompletionParameters parameters, final CompletionResultSet result) {
|
||||
final Ref<Boolean> empty = Ref.create(true);
|
||||
Consumer<CompletionResult> passResult = new Consumer<CompletionResult>() {
|
||||
public void consume(final CompletionResult lookupElement) {
|
||||
empty.set(false);
|
||||
result.passResult(lookupElement);
|
||||
}
|
||||
};
|
||||
result.runRemainingContributors(parameters, passResult);
|
||||
protected void delegate(CompletionParameters parameters, CompletionResultSet result, Consumer<CompletionResult> passResult) {
|
||||
if (parameters.getCompletionType() == CompletionType.BASIC &&
|
||||
parameters.getInvocationCount() <= 1 &&
|
||||
JavaCompletionContributor.mayStartClassName(result, false) &&
|
||||
JavaCompletionContributor.isClassNamePossible(parameters.getPosition())) {
|
||||
final ClassByNameMerger merger = new ClassByNameMerger(parameters.getInvocationCount() == 0, result);
|
||||
|
||||
if (!empty.get() && parameters.getInvocationCount() == 0) {
|
||||
result.restartCompletionWhenNothingMatches();
|
||||
}
|
||||
|
||||
if (empty.get()) {
|
||||
if (parameters.getCompletionType() == CompletionType.BASIC &&
|
||||
parameters.getInvocationCount() <= 1 &&
|
||||
JavaCompletionContributor.mayStartClassName(result, false) &&
|
||||
JavaCompletionContributor.isClassNamePossible(parameters.getPosition())) {
|
||||
final ClassByNameMerger merger = new ClassByNameMerger(parameters.getInvocationCount() == 0, result);
|
||||
|
||||
JavaClassNameCompletionContributor.addAllClasses(parameters, JavaCompletionSorting.addJavaSorting(parameters, result),
|
||||
true, new Consumer<LookupElement>() {
|
||||
@Override
|
||||
public void consume(LookupElement element) {
|
||||
JavaPsiClassReferenceElement classElement = element.as(JavaPsiClassReferenceElement.CLASS_CONDITION_KEY);
|
||||
if (classElement != null) {
|
||||
classElement.setAutoCompletionPolicy(AutoCompletionPolicy.NEVER_AUTOCOMPLETE);
|
||||
}
|
||||
|
||||
merger.consume(classElement);
|
||||
JavaClassNameCompletionContributor.addAllClasses(parameters, JavaCompletionSorting.addJavaSorting(parameters, result),
|
||||
true, new Consumer<LookupElement>() {
|
||||
@Override
|
||||
public void consume(LookupElement element) {
|
||||
JavaPsiClassReferenceElement classElement = element.as(JavaPsiClassReferenceElement.CLASS_CONDITION_KEY);
|
||||
if (classElement != null) {
|
||||
classElement.setAutoCompletionPolicy(AutoCompletionPolicy.NEVER_AUTOCOMPLETE);
|
||||
}
|
||||
});
|
||||
|
||||
merger.finishedClassProcessing();
|
||||
merger.consume(classElement);
|
||||
}
|
||||
});
|
||||
|
||||
} else if (parameters.getCompletionType() == CompletionType.SMART && parameters.getInvocationCount() == 2) {
|
||||
result.runRemainingContributors(parameters.withInvocationCount(3), passResult);
|
||||
}
|
||||
merger.finishedClassProcessing();
|
||||
|
||||
} else if (parameters.getCompletionType() == CompletionType.SMART && parameters.getInvocationCount() == 2) {
|
||||
result.runRemainingContributors(parameters.withInvocationCount(3), passResult);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,6 +18,8 @@ package com.intellij.codeInsight.daemon.impl.quickfix;
|
||||
import com.intellij.codeInsight.CodeInsightUtilBase;
|
||||
import com.intellij.codeInsight.daemon.QuickFixBundle;
|
||||
import com.intellij.codeInspection.LocalQuickFixAndIntentionActionOnPsiElement;
|
||||
import com.intellij.ide.util.SuperMethodWarningUtil;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.command.undo.UndoUtil;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
@@ -25,10 +27,16 @@ import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
|
||||
import com.intellij.psi.util.TypeConversionUtil;
|
||||
import com.intellij.refactoring.RefactoringBundle;
|
||||
import com.intellij.refactoring.changeSignature.ChangeSignatureProcessor;
|
||||
import com.intellij.refactoring.changeSignature.JavaChangeSignatureDialog;
|
||||
import com.intellij.refactoring.changeSignature.ParameterInfoImpl;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class VariableTypeFix extends LocalQuickFixAndIntentionActionOnPsiElement {
|
||||
static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.daemon.impl.quickfix.VariableTypeFix");
|
||||
|
||||
@@ -76,6 +84,7 @@ public class VariableTypeFix extends LocalQuickFixAndIntentionActionOnPsiElement
|
||||
@NotNull PsiElement startElement,
|
||||
@NotNull PsiElement endElement) {
|
||||
final PsiVariable myVariable = (PsiVariable)startElement;
|
||||
if (changeMethodSignatureIfNeeded(myVariable)) return;
|
||||
if (!CodeInsightUtilBase.prepareFileForWrite(myVariable.getContainingFile())) return;
|
||||
try {
|
||||
myVariable.normalizeDeclaration();
|
||||
@@ -88,6 +97,42 @@ public class VariableTypeFix extends LocalQuickFixAndIntentionActionOnPsiElement
|
||||
}
|
||||
}
|
||||
|
||||
private boolean changeMethodSignatureIfNeeded(PsiVariable myVariable) {
|
||||
if (myVariable instanceof PsiParameter) {
|
||||
final PsiElement scope = ((PsiParameter)myVariable).getDeclarationScope();
|
||||
if (scope instanceof PsiMethod) {
|
||||
final PsiMethod method = (PsiMethod)scope;
|
||||
final PsiMethod psiMethod = SuperMethodWarningUtil.checkSuperMethod(method, RefactoringBundle.message("to.refactor"));
|
||||
if (psiMethod == null) return true;
|
||||
final int parameterIndex = method.getParameterList().getParameterIndex((PsiParameter)myVariable);
|
||||
if (!CodeInsightUtilBase.prepareFileForWrite(psiMethod.getContainingFile())) return true;
|
||||
final ArrayList<ParameterInfoImpl> infos = new ArrayList<ParameterInfoImpl>();
|
||||
int i = 0;
|
||||
for (PsiParameter parameter : psiMethod.getParameterList().getParameters()) {
|
||||
final boolean changeType = i == parameterIndex;
|
||||
infos.add(new ParameterInfoImpl(i++, parameter.getName(), changeType ? getReturnType() : parameter.getType()));
|
||||
}
|
||||
|
||||
if (!ApplicationManager.getApplication().isUnitTestMode()) {
|
||||
final JavaChangeSignatureDialog dialog = new JavaChangeSignatureDialog(psiMethod.getProject(), psiMethod, false, myVariable);
|
||||
dialog.setParameterInfos(infos);
|
||||
dialog.show();
|
||||
}
|
||||
else {
|
||||
ChangeSignatureProcessor processor = new ChangeSignatureProcessor(psiMethod.getProject(),
|
||||
psiMethod,
|
||||
false, null,
|
||||
psiMethod.getName(),
|
||||
psiMethod.getReturnType(),
|
||||
infos.toArray(new ParameterInfoImpl[infos.size()]));
|
||||
processor.run();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
protected PsiType getReturnType() {
|
||||
return myReturnType;
|
||||
}
|
||||
|
||||
+13
-6
@@ -322,16 +322,26 @@ public class GenerateDelegateHandler implements LanguageCodeInsightActionHandler
|
||||
int offset = editor.getCaretModel().getOffset();
|
||||
PsiElement element = file.findElementAt(offset);
|
||||
if (element == null) return null;
|
||||
final PsiClass aClass = PsiTreeUtil.getParentOfType(element, PsiClass.class);
|
||||
PsiClass aClass = PsiTreeUtil.getParentOfType(element, PsiClass.class);
|
||||
if (aClass == null) return null;
|
||||
|
||||
List<PsiElementClassMember> result = new ArrayList<PsiElementClassMember>();
|
||||
|
||||
while (aClass != null) {
|
||||
collectTargetsInClass(element, aClass, result);
|
||||
if (aClass.hasModifierProperty(PsiModifier.STATIC)) break;
|
||||
aClass = PsiTreeUtil.getParentOfType(aClass, PsiClass.class, true);
|
||||
}
|
||||
|
||||
return result.toArray(new PsiElementClassMember[result.size()]);
|
||||
}
|
||||
|
||||
private static void collectTargetsInClass(PsiElement element, final PsiClass aClass, List<PsiElementClassMember> result) {
|
||||
final PsiField[] fields = aClass.getAllFields();
|
||||
PsiResolveHelper helper = JavaPsiFacade.getInstance(aClass.getProject()).getResolveHelper();
|
||||
for (PsiField field : fields) {
|
||||
final PsiType type = field.getType();
|
||||
if (helper.isAccessible(field, aClass, aClass) && type instanceof PsiClassType) {
|
||||
if (helper.isAccessible(field, aClass, aClass) && type instanceof PsiClassType && !PsiTreeUtil.isAncestor(field, element, false)) {
|
||||
result.add(new PsiFieldMember(field));
|
||||
}
|
||||
}
|
||||
@@ -341,7 +351,7 @@ public class GenerateDelegateHandler implements LanguageCodeInsightActionHandler
|
||||
if (CommonClassNames.JAVA_LANG_OBJECT.equals(method.getContainingClass().getQualifiedName())) continue;
|
||||
final PsiType returnType = method.getReturnType();
|
||||
if (returnType != null && PropertyUtil.isSimplePropertyGetter(method) && helper.isAccessible(method, aClass, aClass) &&
|
||||
returnType instanceof PsiClassType) {
|
||||
returnType instanceof PsiClassType && !PsiTreeUtil.isAncestor(method, element, false)) {
|
||||
result.add(new PsiMethodMember(method));
|
||||
}
|
||||
}
|
||||
@@ -373,8 +383,5 @@ public class GenerateDelegateHandler implements LanguageCodeInsightActionHandler
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result.toArray(new PsiElementClassMember[result.size()]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -176,7 +176,8 @@ public class GenerateEqualsWizard extends AbstractWizard {
|
||||
equalsFieldsSelected();
|
||||
}
|
||||
else if (getCurrentStep() == myHashcodeStepCode && myHashCodePanel != null) {
|
||||
Collection<MemberInfo> selectedMemberInfos = myHashCodePanel.getTable().getSelectedMemberInfos();
|
||||
Collection<MemberInfo> selectedMemberInfos = myEqualsPanel != null ? myEqualsPanel.getTable().getSelectedMemberInfos()
|
||||
: myHashCodePanel.getTable().getSelectedMemberInfos();
|
||||
updateNonNullMemberInfos(selectedMemberInfos);
|
||||
}
|
||||
|
||||
|
||||
@@ -18,21 +18,16 @@ package com.intellij.codeInspection;
|
||||
import com.intellij.CommonBundle;
|
||||
import com.intellij.codeInsight.CodeInsightUtilBase;
|
||||
import com.intellij.codeInsight.daemon.QuickFixBundle;
|
||||
import com.intellij.ide.util.PackageUtil;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.roots.ProjectRootManager;
|
||||
import com.intellij.openapi.ui.Messages;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.refactoring.PackageWrapper;
|
||||
import com.intellij.refactoring.move.moveClassesOrPackages.AutocreatingSingleSourceRootMoveDestination;
|
||||
import com.intellij.refactoring.move.moveClassesOrPackages.MoveClassesOrPackagesProcessor;
|
||||
import com.intellij.refactoring.move.moveClassesOrPackages.MoveClassesOrPackagesUtil;
|
||||
import com.intellij.refactoring.move.moveClassesOrPackages.SingleSourceRootMoveDestination;
|
||||
import com.intellij.refactoring.util.RefactoringMessageUtil;
|
||||
import com.intellij.refactoring.util.RefactoringUtil;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@@ -79,7 +74,7 @@ public class MoveToPackageFix implements LocalQuickFix {
|
||||
|
||||
private void chooseDirectoryAndMove(Project project, PsiFile myFile) {
|
||||
try {
|
||||
PsiDirectory directory = MoveClassesOrPackagesUtil.chooseDestinationPackage(project, myTargetPackage, null);
|
||||
PsiDirectory directory = MoveClassesOrPackagesUtil.chooseDestinationPackage(project, myTargetPackage, myFile.getContainingDirectory());
|
||||
|
||||
if (directory == null) {
|
||||
return;
|
||||
|
||||
@@ -128,7 +128,9 @@ public class CopyClassesHandler extends CopyHandlerDelegateBase {
|
||||
if (classes != null) {
|
||||
topLevelClasses = ArrayUtil.mergeArrays(classes, topLevelClasses, PsiClass.ARRAY_FACTORY);
|
||||
}
|
||||
result.put(containingFile, topLevelClasses);
|
||||
if (topLevelClasses != null) {
|
||||
result.put(containingFile, topLevelClasses);
|
||||
}
|
||||
}
|
||||
|
||||
public void doCopy(PsiElement[] elements, PsiDirectory defaultTargetDirectory) {
|
||||
|
||||
@@ -22,14 +22,15 @@ import com.intellij.psi.PsiReferenceExpression;
|
||||
import com.intellij.psi.PsiSubstitutor;
|
||||
import com.intellij.psi.util.PsiFormatUtil;
|
||||
import com.intellij.refactoring.HelpID;
|
||||
import com.intellij.refactoring.RefactoringBundle;
|
||||
import com.intellij.refactoring.JavaRefactoringSettings;
|
||||
import com.intellij.refactoring.RefactoringBundle;
|
||||
|
||||
public class InlineFieldDialog extends InlineOptionsDialog {
|
||||
public static final String REFACTORING_NAME = RefactoringBundle.message("inline.field.title");
|
||||
private final PsiReferenceExpression myReferenceExpression;
|
||||
|
||||
private final PsiField myField;
|
||||
protected final int myOccurrencesNumber;
|
||||
|
||||
public InlineFieldDialog(Project project, PsiField field, PsiReferenceExpression ref) {
|
||||
super(project, true, field);
|
||||
@@ -38,7 +39,7 @@ public class InlineFieldDialog extends InlineOptionsDialog {
|
||||
myInvokedOnReference = myReferenceExpression != null;
|
||||
|
||||
setTitle(REFACTORING_NAME);
|
||||
|
||||
myOccurrencesNumber = initOccurrencesNumber(myField);
|
||||
init();
|
||||
}
|
||||
|
||||
@@ -56,7 +57,8 @@ public class InlineFieldDialog extends InlineOptionsDialog {
|
||||
}
|
||||
|
||||
protected String getInlineAllText() {
|
||||
return RefactoringBundle.message("all.references.and.remove.the.field");
|
||||
final String occurrencesString = myOccurrencesNumber > -1 ? " (" + myOccurrencesNumber + " occurrence" + (myOccurrencesNumber == 1 ? ")" : "s)") : "";
|
||||
return RefactoringBundle.message("all.references.and.remove.the.field") + occurrencesString;
|
||||
}
|
||||
|
||||
protected boolean isInlineThis() {
|
||||
|
||||
@@ -17,18 +17,14 @@ package com.intellij.refactoring.inline;
|
||||
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.help.HelpManager;
|
||||
import com.intellij.openapi.progress.ProgressManager;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.PsiJavaCodeReferenceElement;
|
||||
import com.intellij.psi.PsiMethod;
|
||||
import com.intellij.psi.PsiSubstitutor;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.psi.search.PsiSearchHelper;
|
||||
import com.intellij.psi.search.searches.ReferencesSearch;
|
||||
import com.intellij.psi.util.PsiFormatUtil;
|
||||
import com.intellij.refactoring.HelpID;
|
||||
import com.intellij.refactoring.RefactoringBundle;
|
||||
import com.intellij.refactoring.JavaRefactoringSettings;
|
||||
import com.intellij.refactoring.RefactoringBundle;
|
||||
|
||||
public class InlineMethodDialog extends InlineOptionsDialog {
|
||||
public static final String REFACTORING_NAME = RefactoringBundle.message("inline.method.title");
|
||||
@@ -50,21 +46,10 @@ public class InlineMethodDialog extends InlineOptionsDialog {
|
||||
myInvokedOnReference = ref != null;
|
||||
|
||||
setTitle(REFACTORING_NAME);
|
||||
initOccurrencesNumber(method);
|
||||
myOccurrencesNumber = initOccurrencesNumber(method);
|
||||
init();
|
||||
}
|
||||
|
||||
private void initOccurrencesNumber(PsiMethod method) {
|
||||
final ProgressManager progressManager = ProgressManager.getInstance();
|
||||
final PsiSearchHelper searchHelper = PsiSearchHelper.SERVICE.getInstance(method.getProject());
|
||||
final GlobalSearchScope scope = GlobalSearchScope.projectScope(method.getProject());
|
||||
final boolean isCheapToSearch =
|
||||
searchHelper.isCheapEnoughToSearch(method.getName(), scope, null, progressManager.getProgressIndicator()) != PsiSearchHelper.SearchCostResult.TOO_MANY_OCCURRENCES;
|
||||
if (isCheapToSearch) {
|
||||
myOccurrencesNumber = ReferencesSearch.search(method).findAll().size();
|
||||
}
|
||||
}
|
||||
|
||||
protected String getNameLabelText() {
|
||||
String methodText = PsiFormatUtil.formatMethod(myMethod,
|
||||
PsiSubstitutor.EMPTY, PsiFormatUtil.SHOW_NAME | PsiFormatUtil.SHOW_PARAMETERS, PsiFormatUtil.SHOW_TYPE);
|
||||
|
||||
@@ -195,7 +195,7 @@ public class InlineMethodProcessor extends BaseRefactoringProcessor {
|
||||
final ReferencedElementsCollector collector,
|
||||
final MultiMap<PsiElement, String> conflicts) {
|
||||
element.accept(collector);
|
||||
final Map<PsiMember, Set<PsiMember>> containersToReferenced = getInaccessible(collector.myReferencedMembers, usages);
|
||||
final Map<PsiMember, Set<PsiMember>> containersToReferenced = getInaccessible(collector.myReferencedMembers, usages, element);
|
||||
|
||||
final Set<PsiMember> containers = containersToReferenced.keySet();
|
||||
for (PsiMember container : containers) {
|
||||
@@ -216,12 +216,17 @@ public class InlineMethodProcessor extends BaseRefactoringProcessor {
|
||||
*
|
||||
* @param referencedElements
|
||||
* @param usages
|
||||
* @param elementToInline
|
||||
*/
|
||||
private static Map<PsiMember, Set<PsiMember>> getInaccessible(HashSet<PsiMember> referencedElements, UsageInfo[] usages) {
|
||||
private static Map<PsiMember, Set<PsiMember>> getInaccessible(HashSet<PsiMember> referencedElements,
|
||||
UsageInfo[] usages,
|
||||
PsiElement elementToInline) {
|
||||
Map<PsiMember, Set<PsiMember>> result = new HashMap<PsiMember, Set<PsiMember>>();
|
||||
|
||||
for (UsageInfo usage : usages) {
|
||||
final PsiElement container = ConflictsUtil.getContainer(usage.getElement());
|
||||
final PsiElement usageElement = usage.getElement();
|
||||
if (usageElement == null) continue;
|
||||
final PsiElement container = ConflictsUtil.getContainer(usageElement);
|
||||
if (!(container instanceof PsiMember)) continue; // usage in import statement
|
||||
PsiMember memberContainer = (PsiMember)container;
|
||||
Set<PsiMember> inaccessibleReferenced = result.get(memberContainer);
|
||||
@@ -229,7 +234,8 @@ public class InlineMethodProcessor extends BaseRefactoringProcessor {
|
||||
inaccessibleReferenced = new HashSet<PsiMember>();
|
||||
result.put(memberContainer, inaccessibleReferenced);
|
||||
for (PsiMember member : referencedElements) {
|
||||
if (!PsiUtil.isAccessible(member, usage.getElement(), null)) {
|
||||
if (PsiTreeUtil.isAncestor(elementToInline, member, false)) continue;
|
||||
if (!PsiUtil.isAccessible(member, usageElement, null)) {
|
||||
inaccessibleReferenced.add(member);
|
||||
}
|
||||
}
|
||||
|
||||
+8
@@ -18,7 +18,10 @@ package com.intellij.refactoring.introduceField;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.editor.RangeMarker;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.search.LocalSearchScope;
|
||||
import com.intellij.psi.search.SearchScope;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.refactoring.introduceParameter.AbstractJavaInplaceIntroducer;
|
||||
import com.intellij.refactoring.ui.TypeSelectorManagerImpl;
|
||||
@@ -73,6 +76,11 @@ public abstract class AbstractInplaceIntroduceFieldPopup extends AbstractJavaInp
|
||||
return myParentClass;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected SearchScope getReferencesSearchScope(VirtualFile file) {
|
||||
return new LocalSearchScope(myParentClass);
|
||||
}
|
||||
|
||||
protected PsiElement getAnchorElement() {
|
||||
if (myAnchorIdx != -1 && myOccurrences[myAnchorIdx] != null) {
|
||||
return myOccurrences[myAnchorIdx].getParent();
|
||||
|
||||
+1
-2
@@ -248,7 +248,7 @@ public class MoveInstanceMethodProcessor extends BaseRefactoringProcessor{
|
||||
if (!methodExpression.isReferenceTo(myMethod)) return;
|
||||
final PsiExpression oldQualifier = methodExpression.getQualifierExpression();
|
||||
PsiExpression newQualifier = null;
|
||||
|
||||
final PsiClass classReferencedByThis = MoveInstanceMembersUtil.getClassReferencedByThis(methodExpression);
|
||||
if (myTargetVariable instanceof PsiParameter) {
|
||||
final int index = myMethod.getParameterList().getParameterIndex((PsiParameter)myTargetVariable);
|
||||
final PsiExpression[] arguments = expression.getArgumentList().getExpressions();
|
||||
@@ -264,7 +264,6 @@ public class MoveInstanceMethodProcessor extends BaseRefactoringProcessor{
|
||||
|
||||
PsiExpression newArgument = null;
|
||||
|
||||
final PsiClass classReferencedByThis = MoveInstanceMembersUtil.getClassReferencedByThis(methodExpression);
|
||||
if (classReferencedByThis != null) {
|
||||
@NonNls String thisArgumentText = null;
|
||||
if (manager.areElementsEquivalent(myMethod.getContainingClass(), classReferencedByThis)) {
|
||||
|
||||
@@ -169,9 +169,32 @@ public class PsiDiamondTypeImpl extends PsiDiamondType {
|
||||
final Project project = newExpression.getProject();
|
||||
final JavaPsiFacade facade = JavaPsiFacade.getInstance(project);
|
||||
final PsiResolveHelper resolveHelper = facade.getResolveHelper();
|
||||
final PsiExpression newExpressionQualifier = newExpression.getQualifier();
|
||||
final PsiElement qualifierElement = classReference.getQualifier();
|
||||
final String qualifier = qualifierElement != null ? qualifierElement.getText() : "";
|
||||
return resolveHelper.resolveReferencedClass(StringUtil.getQualifiedName(qualifier, text), newExpression);
|
||||
final String qualifiedName = StringUtil.getQualifiedName(qualifier, text);
|
||||
if (newExpressionQualifier != null) {
|
||||
final String newExpressionQualifierText = newExpressionQualifier.getText();
|
||||
if (newExpressionQualifier instanceof PsiReferenceExpression) {
|
||||
final PsiVariable variable = resolveHelper.resolveReferencedVariable(newExpressionQualifierText, newExpression);
|
||||
if (variable != null) {
|
||||
final PsiClass aClass = PsiUtil.resolveClassInType(variable.getType());
|
||||
if (aClass != null) {
|
||||
return aClass.findInnerClassByName(qualifiedName, false);
|
||||
}
|
||||
}
|
||||
} else if (newExpressionQualifier instanceof PsiCallExpression) {
|
||||
final JavaResolveResult resolveResult = ((PsiCallExpression)newExpressionQualifier).resolveMethodGenerics();
|
||||
final PsiElement method = resolveResult.getElement();
|
||||
if (method instanceof PsiMethod) {
|
||||
final PsiClass aClass = PsiUtil.resolveClassInType(resolveResult.getSubstitutor().substitute(((PsiMethod)method).getReturnType()));
|
||||
if (aClass != null) {
|
||||
return aClass.findInnerClassByName(qualifiedName, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return resolveHelper.resolveReferencedClass(qualifiedName, newExpression);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
<orderEntry type="module" module-name="execution-openapi" />
|
||||
<orderEntry type="module" module-name="IntentionPowerPackPlugin" />
|
||||
<orderEntry type="module" module-name="InspectionGadgetsPlugin" />
|
||||
<orderEntry type="module" module-name="platform-tests" scope="TEST" />
|
||||
</component>
|
||||
</module>
|
||||
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
public class TestSource7 {
|
||||
public void foo(){
|
||||
Class c<caret>
|
||||
}
|
||||
}
|
||||
+23
@@ -181,3 +181,26 @@ class PredefinedErrorsOverRaw<T> {
|
||||
PredefinedErrorsOverRaw mc = new <Boolean>PredefinedErrorsOverRaw<<error descr="Cannot use diamonds with explicit type parameters for constructor"></error>>("");
|
||||
}
|
||||
}
|
||||
|
||||
class Outer {
|
||||
class Inner<T> {}
|
||||
}
|
||||
class Outer1 {}
|
||||
|
||||
class Another {
|
||||
public static void main(String[] args) {
|
||||
Outer o = new Outer();
|
||||
Outer.Inner<String> i = o.new Inner<>();
|
||||
Outer.Inner<String> i1 = m().new Inner<>();
|
||||
Outer.Inner<String> i2 = m1().new Inner<>();
|
||||
|
||||
Outer.Inner<String> i3 = m2().new <error descr="Cannot resolve symbol 'Inner'">Inner</error><>();
|
||||
|
||||
System.out.println(i);
|
||||
}
|
||||
|
||||
static Outer m() {return null;}
|
||||
static <T extends Outer> T m1() {return null;}
|
||||
static <T> T m2() {return null;}
|
||||
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
// "Change 'i' type to 'java.lang.String'" "true"
|
||||
|
||||
class Base {
|
||||
void foo(String i) {}
|
||||
}
|
||||
|
||||
class Ex extends Base {
|
||||
@Override
|
||||
void foo(String i) {
|
||||
i = "abc"; // when I invoke "Change type of 'i' to 'String'", base method is ignored so method overriding is lost
|
||||
}
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
// "Change 'i' type to 'java.lang.String'" "true"
|
||||
|
||||
class Base {
|
||||
void foo(int i) {}
|
||||
}
|
||||
|
||||
class Ex extends Base {
|
||||
@Override
|
||||
void foo(int i) {
|
||||
i = <caret>"abc"; // when I invoke "Change type of 'i' to 'String'", base method is ignored so method overriding is lost
|
||||
}
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
<root>
|
||||
<item name='p.TestDeannotation java.lang.String get()'>
|
||||
<annotation name='org.jetbrains.annotations.NotNull'/>
|
||||
</item>
|
||||
<item name='p.TestDeannotation1 java.lang.String get(java.lang.String) 0'>
|
||||
<annotation name='org.jetbrains.annotations.NotNull'/>
|
||||
</item>
|
||||
</root>
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
<root>
|
||||
<item name='suppressed.ExistingExternalName java.lang.String foo()'>
|
||||
<annotation name='org.jetbrains.annotations.NotNull'/>
|
||||
</item>
|
||||
<item name='suppressed.SecondSuppression void second()'>
|
||||
<annotation name='java.lang.SuppressWarnings'>
|
||||
<val val="{DoesntMatterWhat}"/>
|
||||
</annotation>
|
||||
</item>
|
||||
</root>
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
<root>
|
||||
<item name='suppressed.ExistingExternalName java.lang.String foo()'>
|
||||
<annotation name='org.jetbrains.annotations.NotNull'/>
|
||||
<annotation name='java.lang.SuppressWarnings'>
|
||||
<val val=""SillyAssignment""/>
|
||||
</annotation>
|
||||
</item>
|
||||
<item name='suppressed.SecondSuppression void second()'>
|
||||
<annotation name='java.lang.SuppressWarnings'>
|
||||
<val val="{DoesntMatterWhat}"/>
|
||||
</annotation>
|
||||
</item>
|
||||
</root>
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
<root>
|
||||
<item name='suppressed.ExistingExternalName java.lang.String foo()'>
|
||||
<annotation name='org.jetbrains.annotations.NotNull'/>
|
||||
</item>
|
||||
<item name='suppressed.SecondSuppression void second()'>
|
||||
<annotation name='java.lang.SuppressWarnings'>
|
||||
<val val="{DoesntMatterWhat}"/>
|
||||
</annotation>
|
||||
</item>
|
||||
<item name='suppressed.NewSuppress void barr()'>
|
||||
<annotation name='java.lang.SuppressWarnings'>
|
||||
<val val=""SillyAssignment""/>
|
||||
</annotation>
|
||||
</item>
|
||||
</root>
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
<root>
|
||||
<item name='suppressed.ExistingExternalName java.lang.String foo()'>
|
||||
<annotation name='org.jetbrains.annotations.NotNull'/>
|
||||
</item>
|
||||
<item name='suppressed.SecondSuppression void second()'>
|
||||
<annotation name='java.lang.SuppressWarnings'>
|
||||
<val val="{DoesntMatterWhat, "SillyAssignment"}"/>
|
||||
</annotation>
|
||||
</item>
|
||||
</root>
|
||||
@@ -0,0 +1,6 @@
|
||||
package p;
|
||||
class Test {
|
||||
String g<caret>et() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package p;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
class Test {
|
||||
|
||||
@NotNull
|
||||
String g<caret>et() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package p;
|
||||
|
||||
public class TestDeannotation {
|
||||
|
||||
String g<caret>et() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package p;
|
||||
|
||||
public class TestDeannotation1 {
|
||||
|
||||
String get(String s<caret>s) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
package p;
|
||||
class Test {
|
||||
boolean g<caret>et() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
package suppressed;
|
||||
class ExistingExternalName {
|
||||
String foo(){
|
||||
String str = "";
|
||||
s<caret>tr = str;
|
||||
return str;
|
||||
}
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
package suppressed;
|
||||
class NewSuppress {
|
||||
void barr() {
|
||||
String str = "";
|
||||
st<caret>r = str;
|
||||
}
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
package suppressed;
|
||||
class SecondSuppression {
|
||||
void second() {
|
||||
String str = "";
|
||||
st<caret>r = str;
|
||||
}
|
||||
}
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
public class Foo {
|
||||
public static void f<caret>oo() {
|
||||
bar(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
doRun();
|
||||
}
|
||||
|
||||
private void doRun() {
|
||||
// Woo-hoo
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static void bar(final Runnable runnable) {
|
||||
runnable.run();
|
||||
}
|
||||
}
|
||||
|
||||
class Bar {
|
||||
public static void main(String[] args) {
|
||||
Foo.foo();
|
||||
}
|
||||
}
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
public class Foo {
|
||||
|
||||
public static void bar(final Runnable runnable) {
|
||||
runnable.run();
|
||||
}
|
||||
}
|
||||
|
||||
class Bar {
|
||||
public static void main(String[] args) {
|
||||
Foo.bar(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
doRun();
|
||||
}
|
||||
|
||||
private void doRun() {
|
||||
// Woo-hoo
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
public class A {
|
||||
|
||||
public void m<caret>(B b){
|
||||
System.out.println(this);
|
||||
}
|
||||
|
||||
public void show(B b){
|
||||
m(b);
|
||||
}
|
||||
|
||||
public void m (C c){
|
||||
System.out.println(this);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class B{}
|
||||
class C{}
|
||||
@@ -0,0 +1,18 @@
|
||||
public class A {
|
||||
|
||||
public void show(B b){
|
||||
b.m(this);
|
||||
}
|
||||
|
||||
public void m (C c){
|
||||
System.out.println(this);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class B{
|
||||
public void m(A a){
|
||||
System.out.println(a);
|
||||
}
|
||||
}
|
||||
class C{}
|
||||
@@ -0,0 +1,179 @@
|
||||
/*
|
||||
* User: anna
|
||||
* Date: 27-Jun-2007
|
||||
*/
|
||||
package com.intellij.codeInsight;
|
||||
|
||||
import com.intellij.codeInsight.intention.IntentionAction;
|
||||
import com.intellij.codeInsight.intention.impl.DeannotateIntentionAction;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.application.Result;
|
||||
import com.intellij.openapi.application.ex.PathManagerEx;
|
||||
import com.intellij.openapi.command.WriteCommandAction;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.fileEditor.FileDocumentManager;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.roots.AnnotationOrderRootType;
|
||||
import com.intellij.openapi.roots.ModifiableRootModel;
|
||||
import com.intellij.openapi.roots.ModuleRootManager;
|
||||
import com.intellij.openapi.roots.OrderRootType;
|
||||
import com.intellij.openapi.roots.libraries.Library;
|
||||
import com.intellij.openapi.roots.libraries.LibraryTable;
|
||||
import com.intellij.openapi.vfs.VfsUtil;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.PsiModifierListOwner;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.testFramework.IdeaTestCase;
|
||||
import com.intellij.testFramework.PsiTestUtil;
|
||||
import com.intellij.testFramework.UsefulTestCase;
|
||||
import com.intellij.testFramework.builders.JavaModuleFixtureBuilder;
|
||||
import com.intellij.testFramework.fixtures.*;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class AddAnnotationFixTest extends UsefulTestCase {
|
||||
private CodeInsightTestFixture myFixture;
|
||||
private Module myModule;
|
||||
|
||||
public AddAnnotationFixTest() {
|
||||
IdeaTestCase.initPlatformPrefix();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setUp() throws Exception {
|
||||
super.setUp();
|
||||
final TestFixtureBuilder<IdeaProjectTestFixture> projectBuilder = IdeaTestFixtureFactory.getFixtureFactory().createFixtureBuilder();
|
||||
|
||||
myFixture = JavaTestFixtureFactory.getFixtureFactory().createCodeInsightFixture(projectBuilder.getFixture());
|
||||
final String dataPath = PathManagerEx.getTestDataPath() + "/codeInsight/externalAnnotations";
|
||||
myFixture.setTestDataPath(dataPath);
|
||||
final JavaModuleFixtureBuilder builder = projectBuilder.addModule(JavaModuleFixtureBuilder.class);
|
||||
builder.setMockJdkLevel(JavaModuleFixtureBuilder.MockJdkLevel.jdk15);
|
||||
|
||||
myFixture.setUp();
|
||||
myModule = builder.getFixture().getModule();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void tearDown() throws Exception {
|
||||
super.tearDown();
|
||||
myFixture.tearDown();
|
||||
myFixture = null;
|
||||
myModule = null;
|
||||
}
|
||||
|
||||
protected void addLibrary() {
|
||||
ApplicationManager.getApplication().runWriteAction(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
final ModifiableRootModel model = ModuleRootManager.getInstance(myModule).getModifiableModel();
|
||||
final LibraryTable libraryTable = model.getModuleLibraryTable();
|
||||
final Library library = libraryTable.createLibrary("test");
|
||||
|
||||
final Library.ModifiableModel libraryModel = library.getModifiableModel();
|
||||
libraryModel.addRoot(VfsUtil.pathToUrl(myFixture.getTempDirPath() + "/lib"), OrderRootType.SOURCES);
|
||||
libraryModel.addRoot(VfsUtil.pathToUrl(myFixture.getTempDirPath() + "/content/anno"), AnnotationOrderRootType.getInstance());
|
||||
libraryModel.commit();
|
||||
model.commit();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void testAnnotateLibrary() throws Throwable {
|
||||
|
||||
addLibrary();
|
||||
myFixture.configureByFiles("lib/p/TestPrimitive.java", "content/anno/p/annotations.xml");
|
||||
myFixture.configureByFiles("lib/p/Test.java");
|
||||
final Project project = myFixture.getProject();
|
||||
final PsiFile file = myFixture.getFile();
|
||||
final Editor editor = myFixture.getEditor();
|
||||
|
||||
final IntentionAction fix = myFixture.findSingleIntention("Annotate method 'get' as @NotNull");
|
||||
assertTrue(fix.isAvailable(project, editor, file));
|
||||
|
||||
new WriteCommandAction(project){
|
||||
@Override
|
||||
protected void run(final Result result) throws Throwable {
|
||||
fix.invoke(project, editor, file);
|
||||
}
|
||||
}.execute();
|
||||
|
||||
FileDocumentManager.getInstance().saveAllDocuments();
|
||||
|
||||
final PsiElement psiElement = file.findElementAt(editor.getCaretModel().getOffset());
|
||||
assertNotNull(psiElement);
|
||||
final PsiModifierListOwner listOwner = PsiTreeUtil.getParentOfType(psiElement, PsiModifierListOwner.class);
|
||||
assertNotNull(listOwner);
|
||||
assertNotNull(ExternalAnnotationsManager.getInstance(project).findExternalAnnotation(listOwner, AnnotationUtil.NOT_NULL));
|
||||
}
|
||||
|
||||
public void testPrimitive() throws Throwable {
|
||||
PsiFile psiFile = myFixture.configureByFile("lib/p/TestPrimitive.java");
|
||||
PsiTestUtil.addSourceRoot(myModule, psiFile.getVirtualFile().getParent());
|
||||
|
||||
assertNotAvailable("Annotate method 'get' as @NotNull");
|
||||
}
|
||||
|
||||
private void assertNotAvailable(String hint) {
|
||||
List<IntentionAction> actions = myFixture.filterAvailableIntentions(hint);
|
||||
assertEmpty(actions);
|
||||
}
|
||||
|
||||
public void testAnnotated() throws Throwable {
|
||||
PsiFile psiFile = myFixture.configureByFile("lib/p/TestAnnotated.java");
|
||||
PsiTestUtil.addSourceRoot(myModule, psiFile.getVirtualFile().getParent());
|
||||
final Project project = myFixture.getProject();
|
||||
final PsiFile file = myFixture.getFile();
|
||||
final Editor editor = myFixture.getEditor();
|
||||
assertNotAvailable("Annotate method 'get' as @NotNull");
|
||||
assertNotAvailable("Annotate method 'get' as @Nullable");
|
||||
|
||||
final DeannotateIntentionAction deannotateFix = new DeannotateIntentionAction();
|
||||
assertFalse(deannotateFix.isAvailable(project, editor, file));
|
||||
}
|
||||
|
||||
public void testDeannotation() throws Throwable {
|
||||
addLibrary();
|
||||
myFixture.configureByFiles("lib/p/TestPrimitive.java", "content/anno/p/annotations.xml");
|
||||
doDeannotate("lib/p/TestDeannotation.java", "Annotate method 'get' as @NotNull", "Annotate method 'get' as @Nullable");
|
||||
}
|
||||
|
||||
public void testDeannotation1() throws Throwable {
|
||||
addLibrary();
|
||||
myFixture.configureByFiles("lib/p/TestPrimitive.java", "content/anno/p/annotations.xml");
|
||||
doDeannotate("lib/p/TestDeannotation1.java", "Annotate parameter 'ss' as @NotNull", "Annotate parameter 'ss' as @Nullable");
|
||||
}
|
||||
|
||||
private void doDeannotate(@NonNls final String testPath, String hint1, String hint2) throws Throwable {
|
||||
myFixture.configureByFile(testPath);
|
||||
final Project project = myFixture.getProject();
|
||||
final PsiFile file = myFixture.getFile();
|
||||
final Editor editor = myFixture.getEditor();
|
||||
|
||||
assertNotAvailable(hint1);
|
||||
assertNotAvailable(hint2);
|
||||
|
||||
final DeannotateIntentionAction deannotateFix = new DeannotateIntentionAction();
|
||||
assertTrue(deannotateFix.isAvailable(project, editor, file));
|
||||
|
||||
new WriteCommandAction(project){
|
||||
@Override
|
||||
protected void run(final Result result) throws Throwable {
|
||||
ExternalAnnotationsManager.getInstance(project).deannotate(DeannotateIntentionAction.getContainer(editor, file), AnnotationUtil.NOT_NULL);
|
||||
}
|
||||
}.execute();
|
||||
|
||||
FileDocumentManager.getInstance().saveAllDocuments();
|
||||
|
||||
IntentionAction fix = myFixture.findSingleIntention(hint1);
|
||||
assertNotNull(fix);
|
||||
|
||||
fix = myFixture.findSingleIntention(hint2);
|
||||
assertNotNull(fix);
|
||||
|
||||
assertFalse(deannotateFix.isAvailable(project, editor, file));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
/*
|
||||
* User: anna
|
||||
* Date: 17-Jun-2010
|
||||
*/
|
||||
package com.intellij.codeInsight;
|
||||
|
||||
import com.intellij.codeInsight.intention.IntentionAction;
|
||||
import com.intellij.codeInspection.sillyAssignment.SillyAssignmentInspection;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.application.ex.PathManagerEx;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.roots.AnnotationOrderRootType;
|
||||
import com.intellij.openapi.roots.LanguageLevelProjectExtension;
|
||||
import com.intellij.openapi.roots.ModifiableRootModel;
|
||||
import com.intellij.openapi.roots.ModuleRootManager;
|
||||
import com.intellij.openapi.vfs.VfsUtil;
|
||||
import com.intellij.pom.java.LanguageLevel;
|
||||
import com.intellij.psi.JavaPsiFacade;
|
||||
import com.intellij.testFramework.IdeaTestCase;
|
||||
import com.intellij.testFramework.UsefulTestCase;
|
||||
import com.intellij.testFramework.builders.JavaModuleFixtureBuilder;
|
||||
import com.intellij.testFramework.fixtures.*;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
public class SuppressExternalTest extends UsefulTestCase {
|
||||
protected CodeInsightTestFixture myFixture;
|
||||
|
||||
private LanguageLevel myLanguageLevel;
|
||||
|
||||
public SuppressExternalTest() {
|
||||
IdeaTestCase.initPlatformPrefix();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setUp() throws Exception {
|
||||
super.setUp();
|
||||
final IdeaTestFixtureFactory fixtureFactory = IdeaTestFixtureFactory.getFixtureFactory();
|
||||
final TestFixtureBuilder<IdeaProjectTestFixture> testFixtureBuilder = fixtureFactory.createFixtureBuilder();
|
||||
myFixture = JavaTestFixtureFactory.getFixtureFactory().createCodeInsightFixture(testFixtureBuilder.getFixture());
|
||||
myFixture.setTestDataPath(PathManagerEx.getTestDataPath() + "/codeInsight/externalAnnotations");
|
||||
final JavaModuleFixtureBuilder builder = testFixtureBuilder.addModule(JavaModuleFixtureBuilder.class);
|
||||
new File(myFixture.getTempDirPath() + "/src/").mkdir();
|
||||
builder.addContentRoot(myFixture.getTempDirPath()).addSourceRoot("src");
|
||||
builder.setMockJdkLevel(JavaModuleFixtureBuilder.MockJdkLevel.jdk15);
|
||||
myFixture.enableInspections(new SillyAssignmentInspection());
|
||||
myFixture.setUp();
|
||||
|
||||
addAnnotationsModuleRoot();
|
||||
|
||||
final JavaPsiFacade facade = JavaPsiFacade.getInstance(myFixture.getProject());
|
||||
myLanguageLevel = LanguageLevelProjectExtension.getInstance(facade.getProject()).getLanguageLevel();
|
||||
LanguageLevelProjectExtension.getInstance(facade.getProject()).setLanguageLevel(LanguageLevel.JDK_1_5);
|
||||
}
|
||||
|
||||
private void addAnnotationsModuleRoot() throws IOException {
|
||||
myFixture.copyDirectoryToProject("content/anno/suppressed", "content/anno/suppressed");
|
||||
ApplicationManager.getApplication().runWriteAction(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
final Module module = myFixture.getModule();
|
||||
final ModifiableRootModel model = ModuleRootManager.getInstance(module).getModifiableModel();
|
||||
model.setRootUrls(AnnotationOrderRootType.getInstance(), new String[]{VfsUtil.pathToUrl(myFixture.getTempDirPath() + "/content/anno")});
|
||||
model.commit();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void tearDown() throws Exception {
|
||||
LanguageLevelProjectExtension.getInstance(myFixture.getProject()).setLanguageLevel(myLanguageLevel);
|
||||
myFixture.tearDown();
|
||||
myFixture = null;
|
||||
super.tearDown();
|
||||
}
|
||||
|
||||
|
||||
private void doTest(String testName) throws Exception {
|
||||
final IntentionAction action = myFixture.getAvailableIntention("Suppress for method", "src/suppressed/" + testName + ".java");
|
||||
assertNotNull(action);
|
||||
myFixture.launchAction(action);
|
||||
myFixture.checkResultByFile("content/anno/suppressed/annotations.xml", "content/anno/suppressed/annotations" + testName + "_after.xml", true);
|
||||
}
|
||||
|
||||
|
||||
public void testNewSuppress() throws Throwable {
|
||||
doTest("NewSuppress");
|
||||
}
|
||||
|
||||
public void testExistingExternalName() throws Exception {
|
||||
doTest("ExistingExternalName");
|
||||
}
|
||||
|
||||
public void testSecondSuppression() throws Exception {
|
||||
doTest("SecondSuppression");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -640,6 +640,21 @@ public interface Test {
|
||||
assert !lookup
|
||||
}
|
||||
|
||||
public void testTemplatesWithNonImportedClasses() {
|
||||
CodeInsightSettings.instance.COMPLETION_CASE_SENSITIVE = CodeInsightSettings.NONE
|
||||
myFixture.addClass("package foo.bar; public class LayoutStore {}")
|
||||
try {
|
||||
myFixture.configureByText 'a.java', 'class Foo {{ foo(<caret>) }}'
|
||||
type 'lst'
|
||||
assert lookup
|
||||
assert 'lst' in myFixture.lookupElementStrings
|
||||
assert 'LayoutStore' in myFixture.lookupElementStrings
|
||||
}
|
||||
finally {
|
||||
CodeInsightSettings.instance.COMPLETION_CASE_SENSITIVE = CodeInsightSettings.FIRST_LETTER
|
||||
}
|
||||
}
|
||||
|
||||
public void testTemplateSelectionByComma() {
|
||||
myFixture.configureByText("a.java", """
|
||||
class Foo {
|
||||
|
||||
+6
@@ -70,6 +70,12 @@ public class VariablesCompletionTest extends LightFixtureCompletionTestCase {
|
||||
doTest("LocalReserved.java", "LocalReserved_after.java");
|
||||
}
|
||||
|
||||
public void testLocalReserved2() throws Exception {
|
||||
configureByFile(FILE_PREFIX + "locals/" + "LocalReserved2.java")
|
||||
checkResultByFile(FILE_PREFIX + "locals/" + "LocalReserved2.java");
|
||||
assert !myFixture.lookupElementStrings
|
||||
}
|
||||
|
||||
public void testUniqueNameInFor() throws Exception {
|
||||
doTest(getTestName(false) + ".java", getTestName(false) + "_after.java");
|
||||
}
|
||||
|
||||
@@ -0,0 +1,232 @@
|
||||
package com.intellij.lang.psi;
|
||||
|
||||
import com.intellij.lang.*;
|
||||
import com.intellij.lang.impl.PsiBuilderImpl;
|
||||
import com.intellij.lexer.JavaLexer;
|
||||
import com.intellij.openapi.fileTypes.StdFileTypes;
|
||||
import com.intellij.pom.java.LanguageLevel;
|
||||
import com.intellij.psi.JavaTokenType;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.impl.java.stubs.JavaStubElementTypes;
|
||||
import com.intellij.psi.impl.source.DummyHolder;
|
||||
import com.intellij.psi.impl.source.tree.JavaElementType;
|
||||
import com.intellij.psi.impl.source.tree.SharedImplUtil;
|
||||
import com.intellij.psi.impl.source.tree.TreeElement;
|
||||
import com.intellij.psi.text.BlockSupport;
|
||||
import com.intellij.testFramework.LightIdeaTestCase;
|
||||
import junit.framework.AssertionFailedError;
|
||||
|
||||
/**
|
||||
* Date: Jan 21, 2005
|
||||
* @author max
|
||||
*/
|
||||
public class PsiBuilderTest extends LightIdeaTestCase {
|
||||
private PsiBuilderImpl myBuilder;
|
||||
|
||||
public void testEmptyProgram() throws Exception {
|
||||
myBuilder = createBuilder("");
|
||||
final PsiBuilder.Marker fileMarker = myBuilder.mark();
|
||||
fileMarker.done(JavaStubElementTypes.JAVA_FILE);
|
||||
ASTNode fileNode = myBuilder.getTreeBuilt();
|
||||
assertNotNull(fileNode);
|
||||
assertEquals("", fileNode.getText());
|
||||
}
|
||||
|
||||
public void testProgramWithSingleKeyword() throws Exception {
|
||||
myBuilder = createBuilder("package");
|
||||
|
||||
final PsiBuilder.Marker fileMarker = myBuilder.mark();
|
||||
assertEquals("package", myBuilder.getTokenText());
|
||||
assertEquals(JavaTokenType.PACKAGE_KEYWORD, myBuilder.getTokenType());
|
||||
final PsiBuilder.Marker packageStatementMarker = myBuilder.mark();
|
||||
myBuilder.advanceLexer();
|
||||
assertTrue(myBuilder.eof());
|
||||
packageStatementMarker.done(JavaElementType.PACKAGE_STATEMENT);
|
||||
fileMarker.done(JavaStubElementTypes.JAVA_FILE);
|
||||
|
||||
ASTNode fileNode = myBuilder.getTreeBuilt();
|
||||
assertNotNull(fileNode);
|
||||
assertEquals("package", fileNode.getText());
|
||||
assertSame(fileNode.getFirstChildNode(), fileNode.getLastChildNode());
|
||||
ASTNode packageNode = fileNode.getFirstChildNode();
|
||||
assertNotNull(packageNode);
|
||||
assertEquals("package", packageNode.getText());
|
||||
assertEquals(JavaElementType.PACKAGE_STATEMENT, packageNode.getElementType());
|
||||
|
||||
ASTNode leaf = packageNode.getFirstChildNode();
|
||||
assertNotNull(leaf);
|
||||
assertEquals(JavaTokenType.PACKAGE_KEYWORD, leaf.getElementType());
|
||||
}
|
||||
|
||||
private static PsiBuilderImpl createBuilder(final String text) {
|
||||
return createBuilder(text,null);
|
||||
}
|
||||
private static PsiBuilderImpl createBuilder(final String text, ASTNode originalTree) {
|
||||
final Language lang = StdFileTypes.JAVA.getLanguage();
|
||||
final ParserDefinition parserDefinition = LanguageParserDefinitions.INSTANCE.forLanguage(lang);
|
||||
assertNotNull(parserDefinition);
|
||||
PsiFile psiFile = createFile("x.java", text);
|
||||
return new PsiBuilderImpl(getProject(), psiFile, parserDefinition, new JavaLexer(LanguageLevel.JDK_1_5),
|
||||
SharedImplUtil.findCharTableByTree(psiFile.getNode()), text, originalTree, null);
|
||||
}
|
||||
|
||||
public void testTrailingWhitespaces() throws Exception {
|
||||
myBuilder = createBuilder("foo\n\nx");
|
||||
final PsiBuilder.Marker marker = myBuilder.mark();
|
||||
while (!myBuilder.eof()) {
|
||||
myBuilder.advanceLexer();
|
||||
}
|
||||
marker.done(JavaStubElementTypes.JAVA_FILE);
|
||||
assertEquals("foo\n\nx", myBuilder.getTreeBuilt().getText());
|
||||
}
|
||||
|
||||
public void testRollback() throws Exception {
|
||||
myBuilder = createBuilder("package");
|
||||
|
||||
PsiBuilder.Marker fileMarker = myBuilder.mark();
|
||||
assertEquals("package", myBuilder.getTokenText());
|
||||
assertEquals(JavaTokenType.PACKAGE_KEYWORD, myBuilder.getTokenType());
|
||||
PsiBuilder.Marker packageStatementMarker = myBuilder.mark();
|
||||
myBuilder.advanceLexer();
|
||||
assertTrue(myBuilder.eof());
|
||||
packageStatementMarker.done(JavaElementType.PACKAGE_STATEMENT);
|
||||
|
||||
fileMarker.rollbackTo();
|
||||
|
||||
fileMarker = myBuilder.mark();
|
||||
assertEquals("package", myBuilder.getTokenText());
|
||||
assertEquals(JavaTokenType.PACKAGE_KEYWORD, myBuilder.getTokenType());
|
||||
packageStatementMarker = myBuilder.mark();
|
||||
myBuilder.advanceLexer();
|
||||
assertTrue(myBuilder.eof());
|
||||
packageStatementMarker.done(JavaElementType.PACKAGE_STATEMENT);
|
||||
fileMarker.done(JavaStubElementTypes.JAVA_FILE);
|
||||
|
||||
ASTNode fileNode = myBuilder.getTreeBuilt();
|
||||
assertNotNull(fileNode);
|
||||
assertEquals("package", fileNode.getText());
|
||||
assertSame(fileNode.getFirstChildNode(), fileNode.getLastChildNode());
|
||||
ASTNode packageNode = fileNode.getFirstChildNode();
|
||||
assertNotNull(packageNode);
|
||||
assertEquals("package", packageNode.getText());
|
||||
assertEquals(JavaElementType.PACKAGE_STATEMENT, packageNode.getElementType());
|
||||
|
||||
ASTNode leaf = packageNode.getFirstChildNode();
|
||||
assertNotNull(leaf);
|
||||
assertEquals(JavaTokenType.PACKAGE_KEYWORD, leaf.getElementType());
|
||||
}
|
||||
|
||||
public void testDrop() throws Exception {
|
||||
myBuilder = createBuilder("package");
|
||||
|
||||
final PsiBuilder.Marker fileMarker = myBuilder.mark();
|
||||
assertEquals("package", myBuilder.getTokenText());
|
||||
assertEquals(JavaTokenType.PACKAGE_KEYWORD, myBuilder.getTokenType());
|
||||
final PsiBuilder.Marker packageStatementMarker = myBuilder.mark();
|
||||
myBuilder.advanceLexer();
|
||||
assertTrue(myBuilder.eof());
|
||||
packageStatementMarker.drop();
|
||||
fileMarker.done(JavaStubElementTypes.JAVA_FILE);
|
||||
|
||||
ASTNode fileNode = myBuilder.getTreeBuilt();
|
||||
assertNotNull(fileNode);
|
||||
assertEquals("package", fileNode.getText());
|
||||
assertSame(fileNode.getFirstChildNode(), fileNode.getLastChildNode());
|
||||
|
||||
ASTNode leaf = fileNode.getFirstChildNode();
|
||||
assertNotNull(leaf);
|
||||
assertEquals(JavaTokenType.PACKAGE_KEYWORD, leaf.getElementType());
|
||||
assertEquals("package", leaf.getText());
|
||||
assertNull(leaf.getFirstChildNode());
|
||||
}
|
||||
|
||||
public void testAdvanceBeyondEof() {
|
||||
myBuilder = createBuilder("package");
|
||||
for(int i=0; i<20; i++) {
|
||||
myBuilder.eof();
|
||||
myBuilder.advanceLexer();
|
||||
}
|
||||
assertTrue(myBuilder.eof());
|
||||
}
|
||||
|
||||
public void testAssertionFailureOnUnbalancedMarkers() {
|
||||
myBuilder = createBuilder("foo");
|
||||
myBuilder.setDebugMode(true);
|
||||
final PsiBuilder.Marker m = myBuilder.mark();
|
||||
final PsiBuilder.Marker m1 = myBuilder.mark();
|
||||
myBuilder.getTokenType();
|
||||
myBuilder.advanceLexer();
|
||||
try {
|
||||
m.done(JavaTokenType.PACKAGE_KEYWORD);
|
||||
fail("Assertion must fire");
|
||||
}
|
||||
catch (AssertionFailedError e) {
|
||||
throw e;
|
||||
}
|
||||
catch (Throwable e) {
|
||||
if (!e.getMessage().startsWith("Another not done marker")) {
|
||||
fail("Wrong assertion message");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void testNotAllTokensProcessed() {
|
||||
myBuilder = createBuilder("foo");
|
||||
myBuilder.setDebugMode(true);
|
||||
final PsiBuilder.Marker m = myBuilder.mark();
|
||||
m.done(JavaTokenType.PACKAGE_KEYWORD);
|
||||
try {
|
||||
myBuilder.getTreeBuilt();
|
||||
fail("Assertion must fire");
|
||||
}
|
||||
catch (AssertionFailedError e) {
|
||||
throw e;
|
||||
}
|
||||
catch (Throwable e) {
|
||||
if (!e.getMessage().startsWith("Tokens [IDENTIFIER] were not inserted into the tree")) {
|
||||
fail("Wrong assertion message");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void testMergeWhenEmptyElementAfterWhitespaceIsLastChild() throws Throwable {
|
||||
myBuilder = createBuilder(" foo bar");
|
||||
parseWhenEmptyElementAfterWhitespaceIsLastChild();
|
||||
final ASTNode tree = myBuilder.getTreeBuilt();
|
||||
new DummyHolder(getPsiManager(), (TreeElement)tree, null);
|
||||
|
||||
myBuilder = createBuilder(" bar", tree);
|
||||
parseWhenEmptyElementAfterWhitespaceIsLastChild();
|
||||
try {
|
||||
myBuilder.getTreeBuilt();
|
||||
fail();
|
||||
}
|
||||
catch (BlockSupport.ReparsedSuccessfullyException e) {
|
||||
e.getDiffLog().performActualPsiChange(tree.getPsi().getContainingFile());
|
||||
}
|
||||
|
||||
assertEquals(" bar", tree.getText());
|
||||
}
|
||||
|
||||
private void parseWhenEmptyElementAfterWhitespaceIsLastChild() {
|
||||
final PsiBuilder.Marker root = myBuilder.mark();
|
||||
|
||||
final PsiBuilder.Marker composite = myBuilder.mark();
|
||||
final PsiBuilder.Marker backup = myBuilder.mark();
|
||||
if ("foo".equals(myBuilder.getTokenText())) {
|
||||
myBuilder.advanceLexer();
|
||||
myBuilder.getTokenType();
|
||||
myBuilder.mark().done(JavaStubElementTypes.TYPE_PARAMETER_LIST);
|
||||
backup.done(JavaStubElementTypes.ANNOTATION_METHOD);
|
||||
} else {
|
||||
backup.rollbackTo();
|
||||
}
|
||||
composite.done(JavaStubElementTypes.ANONYMOUS_CLASS);
|
||||
|
||||
myBuilder.getTokenType();
|
||||
myBuilder.advanceLexer();
|
||||
root.done(JavaStubElementTypes.ENUM_CONSTANT_INITIALIZER);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,110 @@
|
||||
package com.intellij.lexer;
|
||||
|
||||
import com.intellij.pom.java.LanguageLevel;
|
||||
import com.intellij.psi.JavaTokenType;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import junit.framework.TestCase;
|
||||
|
||||
/**
|
||||
* @author max
|
||||
*/
|
||||
public class LayeredLexerTest extends TestCase {
|
||||
public void testInTheMiddle() throws Exception {
|
||||
Lexer lexer = setupLexer("s=\"abc\\ndef\";");
|
||||
|
||||
assertEquals("s", nextToken(lexer));
|
||||
assertEquals("=", nextToken(lexer));
|
||||
assertEquals("\"abc", nextToken(lexer));
|
||||
assertEquals("\\n", nextToken(lexer));
|
||||
assertEquals("def\"", nextToken(lexer));
|
||||
assertEquals(";", nextToken(lexer));
|
||||
assertEquals(null, lexer.getTokenType());
|
||||
}
|
||||
|
||||
public void testModification() throws Exception {
|
||||
Lexer lexer = setupLexer("s=\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\";");
|
||||
assertEquals("s", nextToken(lexer));
|
||||
assertEquals("=", nextToken(lexer));
|
||||
assertEquals("\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\"", nextToken(lexer));
|
||||
assertEquals(";", nextToken(lexer));
|
||||
assertEquals(null, lexer.getTokenType());
|
||||
|
||||
lexer.start(lexer.getBufferSequence(), 2, lexer.getBufferEnd(), (short) 1);
|
||||
assertEquals("\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\"", nextToken(lexer));
|
||||
assertEquals(";", nextToken(lexer));
|
||||
assertEquals(null, lexer.getTokenType());
|
||||
}
|
||||
|
||||
|
||||
public void testInTheAtStartup() throws Exception {
|
||||
Lexer lexer = setupLexer("s=\"\\ndef\";");
|
||||
|
||||
assertEquals("s", nextToken(lexer));
|
||||
assertEquals("=", nextToken(lexer));
|
||||
assertEquals("\"", nextToken(lexer));
|
||||
assertEquals("\\n", nextToken(lexer));
|
||||
assertEquals("def\"", nextToken(lexer));
|
||||
assertEquals(";", nextToken(lexer));
|
||||
assertEquals(null, lexer.getTokenType());
|
||||
}
|
||||
|
||||
public void testInTheAtEnd() throws Exception {
|
||||
Lexer lexer = setupLexer("s=\"abc\\n\";");
|
||||
|
||||
assertEquals("s", nextToken(lexer));
|
||||
assertEquals("=", nextToken(lexer));
|
||||
assertEquals("\"abc", nextToken(lexer));
|
||||
assertEquals("\\n", nextToken(lexer));
|
||||
assertEquals("\"", nextToken(lexer));
|
||||
assertEquals(";", nextToken(lexer));
|
||||
assertEquals(null, lexer.getTokenType());
|
||||
}
|
||||
|
||||
public void testNonTerminated() throws Exception {
|
||||
Lexer lexer = setupLexer("s=\"abc\\n");
|
||||
|
||||
assertEquals("s", nextToken(lexer));
|
||||
assertEquals("=", nextToken(lexer));
|
||||
assertEquals("\"abc", nextToken(lexer));
|
||||
assertEquals("\\n", nextToken(lexer));
|
||||
assertEquals(null, lexer.getTokenType());
|
||||
}
|
||||
|
||||
public void testNonTerminated2() throws Exception {
|
||||
Lexer lexer = setupLexer("s=\"abc\\");
|
||||
|
||||
assertEquals("s", nextToken(lexer));
|
||||
assertEquals("=", nextToken(lexer));
|
||||
assertEquals("\"abc", nextToken(lexer));
|
||||
assertEquals("\\", nextToken(lexer));
|
||||
assertEquals(null, lexer.getTokenType());
|
||||
}
|
||||
|
||||
public void testUnicode() throws Exception {
|
||||
Lexer lexer = setupLexer("s=\"\\uFFFF\";");
|
||||
assertEquals("s", nextToken(lexer));
|
||||
assertEquals("=", nextToken(lexer));
|
||||
assertEquals("\"", nextToken(lexer));
|
||||
assertEquals("\\uFFFF", nextToken(lexer));
|
||||
assertEquals("\"", nextToken(lexer));
|
||||
assertEquals(";", nextToken(lexer));
|
||||
assertEquals(null, lexer.getTokenType());
|
||||
}
|
||||
|
||||
private Lexer setupLexer(String text) {
|
||||
LayeredLexer lexer = new LayeredLexer(new JavaLexer(LanguageLevel.JDK_1_3));
|
||||
lexer.registerSelfStoppingLayer(new StringLiteralLexer('\"', JavaTokenType.STRING_LITERAL),
|
||||
new IElementType[]{JavaTokenType.STRING_LITERAL},
|
||||
IElementType.EMPTY_ARRAY);
|
||||
|
||||
lexer.start(text);
|
||||
return lexer;
|
||||
}
|
||||
|
||||
private String nextToken(Lexer lexer) {
|
||||
assertTrue(lexer.getTokenType() != null);
|
||||
final String s = lexer.getBufferSequence().subSequence(lexer.getTokenStart(), lexer.getTokenEnd()).toString();
|
||||
lexer.advance();
|
||||
return s;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: mike
|
||||
* Date: Jun 14, 2002
|
||||
* Time: 8:05:58 PM
|
||||
* To change template for new class use
|
||||
* Code Style | Class Templates options (Tools | IDE Options).
|
||||
*/
|
||||
package com.intellij.psi.util;
|
||||
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.testFramework.LightCodeInsightTestCase;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
|
||||
public class PropertyUtilTest extends LightCodeInsightTestCase {
|
||||
public void testSuggestGetterName() throws Exception {
|
||||
assertEquals("isValid", PropertyUtil.suggestGetterName("valid", getType("boolean")));
|
||||
assertEquals("getValid", PropertyUtil.suggestGetterName("valid", getType("Object")));
|
||||
assertEquals("isValid", PropertyUtil.suggestGetterName(ourProject, createField("valid", "boolean")));
|
||||
assertEquals("getValid", PropertyUtil.suggestGetterName(ourProject, createField("valid", "Object")));
|
||||
|
||||
assertEquals("getURL", PropertyUtil.suggestGetterName("URL", getType("Object")));
|
||||
assertEquals("getURL", PropertyUtil.suggestGetterName(ourProject, createField("URL", "Object")));
|
||||
|
||||
assertEquals("isaURL", PropertyUtil.suggestGetterName(ourProject, createField("aURL", "boolean")));
|
||||
assertEquals("getaURL", PropertyUtil.suggestGetterName(ourProject, createField("aURL", "Object")));
|
||||
assertEquals("getBool", PropertyUtil.suggestGetterName(ourProject, createField("bool", "java.lang.Boolean")));
|
||||
}
|
||||
|
||||
public void testSuggestSetterName() throws Exception {
|
||||
assertEquals("setValid", PropertyUtil.suggestSetterName("valid"));
|
||||
assertEquals("setValid", PropertyUtil.suggestSetterName(ourProject, createField("valid", "Object")));
|
||||
|
||||
assertEquals("setURL", PropertyUtil.suggestSetterName("URL"));
|
||||
assertEquals("setURL", PropertyUtil.suggestSetterName(ourProject, createField("URL", "Object")));
|
||||
|
||||
assertEquals("setaURL", PropertyUtil.suggestSetterName("aURL"));
|
||||
assertEquals("setaURL", PropertyUtil.suggestSetterName(ourProject, createField("aURL", "Object")));
|
||||
assertEquals("setBool", PropertyUtil.suggestSetterName(ourProject, createField("bool", "java.lang.Boolean")));
|
||||
}
|
||||
|
||||
public void testSuggestPropertyName() throws Exception {
|
||||
assertEquals("valid", PropertyUtil.getPropertyName("isValid"));
|
||||
assertEquals("valid", PropertyUtil.getPropertyName("getValid"));
|
||||
assertEquals("valid", PropertyUtil.getPropertyName("setValid"));
|
||||
|
||||
assertEquals("URL", PropertyUtil.getPropertyName("isURL"));
|
||||
assertEquals("URL", PropertyUtil.getPropertyName("getURL"));
|
||||
assertEquals("URL", PropertyUtil.getPropertyName("setURL"));
|
||||
|
||||
assertEquals("aURL", PropertyUtil.getPropertyName("isaURL"));
|
||||
assertEquals("aURL", PropertyUtil.getPropertyName("getaURL"));
|
||||
assertEquals("aURL", PropertyUtil.getPropertyName("setaURL"));
|
||||
}
|
||||
|
||||
public void testBooleanPropertyGetters() {
|
||||
assertTrue(PropertyUtil.hasGetterName(createMethod("isOk", "boolean")));
|
||||
assertFalse(PropertyUtil.hasGetterName(createMethod("isOk", CommonClassNames.JAVA_LANG_BOOLEAN)));
|
||||
assertTrue(PropertyUtil.hasGetterName(createMethod("getOk", CommonClassNames.JAVA_LANG_BOOLEAN)));
|
||||
assertFalse(PropertyUtil.hasGetterName(createMethod("isOk", "int")));
|
||||
}
|
||||
|
||||
private static PsiType getType(@NonNls String type) throws IncorrectOperationException {
|
||||
return PsiElementFactory.SERVICE.getInstance(ourProject).createTypeFromText(type, null);
|
||||
}
|
||||
|
||||
private static PsiField createField(@NonNls String name, @NonNls String type) throws IncorrectOperationException {
|
||||
return PsiElementFactory.SERVICE.getInstance(ourProject).createField(name, getType(type));
|
||||
}
|
||||
|
||||
private static PsiMethod createMethod(@NonNls String name, String type) throws IncorrectOperationException {
|
||||
return PsiElementFactory.SERVICE.getInstance(ourProject).createMethod(name, getType(type));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
package com.intellij.psi.util;
|
||||
|
||||
import com.intellij.psi.JavaPsiFacade;
|
||||
import com.intellij.psi.PsiClass;
|
||||
import com.intellij.psi.PsiElementFactory;
|
||||
import com.intellij.psi.PsiTypeParameter;
|
||||
import com.intellij.testFramework.LightCodeInsightTestCase;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Iterator;
|
||||
|
||||
/**
|
||||
* @author dsl
|
||||
*/
|
||||
public class PsiUtilTest extends LightCodeInsightTestCase {
|
||||
public void testTypeParameterIterator() throws Exception {
|
||||
PsiClass classA = createClass("class A<T> {}");
|
||||
final Iterator<PsiTypeParameter> iterator = PsiUtil.typeParametersIterator(classA);
|
||||
compareIterator(new String[]{"T"}, iterator);
|
||||
}
|
||||
|
||||
private static PsiClass createClass(String text) throws IncorrectOperationException {
|
||||
final PsiElementFactory factory = JavaPsiFacade.getInstance(ourProject).getElementFactory();
|
||||
final PsiClass classA = factory.createClassFromText(text, null).getInnerClasses()[0];
|
||||
return classA;
|
||||
}
|
||||
|
||||
public void testTypeParameterIterator1() throws Exception {
|
||||
final PsiClass classA = createClass("class A<T> { class B<X> {}}");
|
||||
final Iterator<PsiTypeParameter> iterator = PsiUtil.typeParametersIterator(classA.getInnerClasses()[0]);
|
||||
compareIterator(new String[]{"X","T"}, iterator);
|
||||
}
|
||||
|
||||
public void testTypeParameterIterator2() throws Exception {
|
||||
final PsiClass classA = createClass("class A<T> { static class B<X> {}}");
|
||||
final Iterator<PsiTypeParameter> iterator = PsiUtil.typeParametersIterator(classA.getInnerClasses()[0]);
|
||||
compareIterator(new String[]{"X"}, iterator);
|
||||
}
|
||||
|
||||
public void testTypeParameterIterator3() throws Exception {
|
||||
final PsiClass classA = createClass("class A<T> { class B<X, Y> {}}");
|
||||
final Iterator<PsiTypeParameter> iterator = PsiUtil.typeParametersIterator(classA.getInnerClasses()[0]);
|
||||
compareIterator(new String[]{"Y", "X", "T"}, iterator);
|
||||
}
|
||||
|
||||
|
||||
private static void compareIterator(String[] expected, Iterator<PsiTypeParameter> it) {
|
||||
final ArrayList<String> actual = new ArrayList<String>();
|
||||
while (it.hasNext()) {
|
||||
PsiTypeParameter typeParameter = it.next();
|
||||
actual.add(typeParameter.getName());
|
||||
}
|
||||
assertEquals(Arrays.asList(expected).toString(), actual.toString());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright (c) 2000-2005 by JetBrains s.r.o. All Rights Reserved.
|
||||
* Use is subject to license terms.
|
||||
*/
|
||||
package com.intellij.psi.util.proximity;
|
||||
|
||||
import com.intellij.openapi.application.Result;
|
||||
import com.intellij.openapi.command.WriteCommandAction;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.testFramework.PsiTestUtil;
|
||||
import com.intellij.testFramework.fixtures.IdeaTestFixtureFactory;
|
||||
import com.intellij.testFramework.fixtures.JavaCodeInsightFixtureTestCase;
|
||||
import com.intellij.testFramework.fixtures.TempDirTestFixture;
|
||||
|
||||
/**
|
||||
* @author peter
|
||||
*/
|
||||
public class ProximityTest extends JavaCodeInsightFixtureTestCase {
|
||||
|
||||
public void testSameSourceRoot() throws Throwable {
|
||||
final TempDirTestFixture root1 = IdeaTestFixtureFactory.getFixtureFactory().createTempDirTestFixture();
|
||||
final TempDirTestFixture root2 = IdeaTestFixtureFactory.getFixtureFactory().createTempDirTestFixture();
|
||||
|
||||
root1.setUp();
|
||||
root2.setUp();
|
||||
|
||||
try {
|
||||
new WriteCommandAction(getProject()) {
|
||||
@Override
|
||||
protected void run(Result result) throws Throwable {
|
||||
PsiTestUtil.addSourceContentToRoots(myModule, root1.getFile(""));
|
||||
PsiTestUtil.addSourceContentToRoots(myModule, root2.getFile(""));
|
||||
}
|
||||
}.execute();
|
||||
|
||||
final VirtualFile file1 = root1.createFile("buy.txt", "");
|
||||
final VirtualFile file2 = root2.createFile("buy.txt", "");
|
||||
final VirtualFile ctx = root2.createFile("ctx.txt", "");
|
||||
|
||||
final PsiProximityComparator comparator = new PsiProximityComparator(getPsiManager().findFile(ctx));
|
||||
assertTrue(comparator.compare(getPsiManager().findFile(file1), getPsiManager().findFile(file2)) > 0);
|
||||
assertTrue(comparator.compare(getPsiManager().findFile(file2), getPsiManager().findFile(file1)) < 0);
|
||||
}
|
||||
finally {
|
||||
root1.tearDown();
|
||||
root2.tearDown();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
package com.intellij.refactoring;
|
||||
|
||||
import com.intellij.FileSetTestCase;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.refactoring.util.RefactoringUtil;
|
||||
import com.intellij.util.containers.HashSet;
|
||||
import junit.framework.Test;
|
||||
|
||||
import java.io.File;
|
||||
import java.net.URL;
|
||||
import java.util.Arrays;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author dsl
|
||||
*/
|
||||
public abstract class FixMethodJavadocTest extends FileSetTestCase {
|
||||
FixMethodJavadocTest() {
|
||||
super(findPath());
|
||||
}
|
||||
|
||||
private static String findPath() {
|
||||
final URL res = FixMethodJavadocTest.class.getResource("/" + FixMethodJavadocTest.class.getName().replace('.', '/') + ".class");
|
||||
File f = new File(res.getFile());
|
||||
String result = f.getParent() + File.separatorChar + "methodJavaDocData";
|
||||
result = result.replaceAll("classes", "");
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String transform(String testName, String[] data) throws Exception {
|
||||
final PsiManager manager = PsiManager.getInstance(myProject);
|
||||
final PsiElementFactory factory = JavaPsiFacade.getInstance(manager.getProject()).getElementFactory();
|
||||
final PsiMethod method = factory.createMethodFromText(data[0], null);
|
||||
final HashSet<PsiParameter> newParameters = new HashSet<PsiParameter>();
|
||||
if (data.length == 2) {
|
||||
final String[] strings = data[1].split("\\s+");
|
||||
collectNewParameters(method, strings, newParameters);
|
||||
}
|
||||
RefactoringUtil.fixJavadocsForParams(method, newParameters);
|
||||
return method.getText();
|
||||
}
|
||||
|
||||
private void collectNewParameters(PsiMethod method, String[] names, Set<PsiParameter> newParameters) {
|
||||
Set<String> newNames = new HashSet<String>(Arrays.asList(names));
|
||||
final PsiParameter[] parameters = method.getParameterList().getParameters();
|
||||
for (int i = 0; i < parameters.length; i++) {
|
||||
PsiParameter parameter = parameters[i];
|
||||
if (newNames.contains(parameter.getName())) {
|
||||
newParameters.add(parameter);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static Test suite() {
|
||||
return new FixMethodJavadocTest(){};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
package com.intellij.refactoring;
|
||||
|
||||
import com.intellij.codeInsight.CodeInsightTestCase;
|
||||
import com.intellij.openapi.application.ex.PathManagerEx;
|
||||
import com.intellij.openapi.fileEditor.FileDocumentManager;
|
||||
import com.intellij.openapi.projectRoots.impl.JavaSdkImpl;
|
||||
import com.intellij.openapi.vfs.LocalFileSystem;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.JavaPsiFacade;
|
||||
import com.intellij.psi.PsiPackage;
|
||||
import com.intellij.refactoring.rename.RenameProcessor;
|
||||
import com.intellij.testFramework.IdeaTestUtil;
|
||||
import com.intellij.testFramework.PsiTestUtil;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
public class RenamePackageTest extends CodeInsightTestCase {
|
||||
public void testJspImport() throws Exception {
|
||||
doTest("jspImport", "pack1", "pack2");
|
||||
}
|
||||
|
||||
public void testNonJava() throws Exception {
|
||||
doTest("nonJava", "com.foo", "fooNew");
|
||||
}
|
||||
|
||||
public void testInBrokenXml() throws Exception {
|
||||
doTest("inBrokenXml", "somepckg", "somepckg1");
|
||||
}
|
||||
|
||||
|
||||
public void testJsp() throws Exception {
|
||||
doTest("jsp", "pack1", "pack2");
|
||||
}
|
||||
|
||||
private void doTest(String testName, String packageName, String newPackageName) throws Exception {
|
||||
String root = PathManagerEx.getTestDataPath()+ "/refactoring/renamePackage/" + testName;
|
||||
|
||||
String rootBefore = root + "/before";
|
||||
PsiTestUtil.removeAllRoots(myModule, JavaSdkImpl.getMockJdk17());
|
||||
VirtualFile rootDir = PsiTestUtil.createTestProjectStructure(myProject, myModule, rootBefore, myFilesToDelete);
|
||||
|
||||
performAction(packageName, newPackageName);
|
||||
|
||||
String rootAfter = root + "/after";
|
||||
VirtualFile rootDir2 = LocalFileSystem.getInstance().findFileByPath(rootAfter.replace(File.separatorChar, '/'));
|
||||
IdeaTestUtil.assertDirectoriesEqual(rootDir2, rootDir, IdeaTestUtil.CVS_FILE_FILTER);
|
||||
}
|
||||
|
||||
private void performAction(String packageName, String newPackageName) throws Exception {
|
||||
PsiPackage aPackage = JavaPsiFacade.getInstance(myPsiManager.getProject()).findPackage(packageName);
|
||||
assertNotNull("Package " + packageName + " not found", aPackage);
|
||||
|
||||
//PsiDirectory dir = aPackage.getDirectories()[0];
|
||||
//it is now impossible to rename dir without renaming corresponding package via rename processor - move processor would be used instead
|
||||
new RenameProcessor(myProject, aPackage, newPackageName, true, true).run();
|
||||
FileDocumentManager.getInstance().saveAllDocuments();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isRunInWriteAction() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -170,6 +170,10 @@ public class InlineMethodTest extends LightRefactoringTestCase {
|
||||
public void testSuperMethodInAnonymousClass() throws Exception {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testInlineAnonymousClassWithPrivateMethodInside() throws Exception {
|
||||
doTest();
|
||||
}
|
||||
|
||||
private void doTest() throws Exception {
|
||||
String name = getTestName(false);
|
||||
|
||||
+2
@@ -51,6 +51,8 @@ public class MoveInstanceMethodTest extends LightRefactoringTestCase {
|
||||
|
||||
public void testThisInAnonymous() throws Exception { doTest(true, 0); }
|
||||
|
||||
public void testOverloadingMethods() throws Exception { doTest(true, 0); }
|
||||
|
||||
public void testEscalateVisibility() throws Exception {
|
||||
doTest(true, 0, VisibilityUtil.ESCALATE_VISIBILITY);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,116 @@
|
||||
package com.intellij.unscramble;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
|
||||
/**
|
||||
* @author cdr
|
||||
*/
|
||||
public class NormalizeTextTest extends TestCase {
|
||||
public void testCausedBy() {
|
||||
doTest("javax.faces.FacesException: Error calling action method of component with id _id6:_id10\n" +
|
||||
" at java.lang.Th\n" +
|
||||
"read.run(Thread.java:626)\n" +
|
||||
"Caused by: javax.faces.el.EvaluationException: Exception while invoking expression #{_loginAction.login}\n" +
|
||||
" at org.apache.myfaces.el.MethodBindingImpl.invoke(MethodBindingImpl.java:153)\n" +
|
||||
" at org.apache.myfaces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:63)\n",
|
||||
|
||||
"javax.faces.FacesException: Error calling action method of component with id _id6:_id10\n" +
|
||||
" at java.lang.Thread.run(Thread.java:626)\n" +
|
||||
"Caused by: javax.faces.el.EvaluationException: Exception while invoking expression #{_loginAction.login}\n" +
|
||||
" at org.apache.myfaces.el.MethodBindingImpl.invoke(MethodBindingImpl.java:153)\n" +
|
||||
" at org.apache.myfaces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:63)"
|
||||
);
|
||||
}
|
||||
|
||||
public void testThreadNames() {
|
||||
doTest("\"Background process\" prio=6 tid=0x21193b88 nid=0x11ea4 waiting on condition [0x2\n" + "2cbf000..0x22cbfd68]\n" +
|
||||
" at java.lang.Thread.sleep(Native Method)\n" + " at com.intellij.util.ui.Timer$1.run(Timer.java:23)\n" + "\n" +
|
||||
"\"Alarm pool\" prio=6 tid=0x37cacbe0 nid=0x7940 waiting on condition [0x3972f000..\n" + "0x3972fae8]\n" +
|
||||
" at sun.misc.Unsafe.park(Native Method)\n" +
|
||||
" at java.util.concurrent.locks.LockSupport.park(LockSupport.java:118)\n" +
|
||||
" at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject\n" +
|
||||
".await(AbstractQueuedSynchronizer.java:1767)\n\n" +
|
||||
" at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.jav\n" + "a:359)\n" +
|
||||
" at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.ja\n" + "va:470)\n" +
|
||||
" at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor\n" + ".java:674)\n" +
|
||||
" at java.lang.Thread.run(Thread.java:595)",
|
||||
|
||||
|
||||
"\"Background process\" prio=6 tid=0x21193b88 nid=0x11ea4 waiting on condition [0x22cbf000..0x22cbfd68]\n" +
|
||||
" at java.lang.Thread.sleep(Native Method)\n" +
|
||||
" at com.intellij.util.ui.Timer$1.run(Timer.java:23)\n" +
|
||||
"\n" +
|
||||
"\"Alarm pool\" prio=6 tid=0x37cacbe0 nid=0x7940 waiting on condition [0x3972f000..0x3972fae8]\n" +
|
||||
" at sun.misc.Unsafe.park(Native Method)\n" +
|
||||
" at java.util.concurrent.locks.LockSupport.park(LockSupport.java:118)\n" +
|
||||
" at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:1767)\n" +
|
||||
" at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:359)\n" +
|
||||
" at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:470)\n" +
|
||||
" at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:674)\n" +
|
||||
" at java.lang.Thread.run(Thread.java:595)"
|
||||
);
|
||||
}
|
||||
|
||||
public void testLocked() {
|
||||
doTest(" at com.intellij.lang.jsp.JspFileViewProviderImpl.getKeyPrefixes(JspFileV\n" + "iewProviderImpl.java:76)\n" +
|
||||
" at com.intellij.lang.jsp.JspFileViewProviderImpl.getKnownTaglibPrefixes(\n" + "JspFileViewProviderImpl.java:89)\n" +
|
||||
" - locked <0x04cc0768> (a java.lang.Object)\n" +
|
||||
" at com.intellij.psi.impl.source.parsing.jsp.JspLexer.doInitOriginal(JspL\n" + "exer.java:39)\n" +
|
||||
" at com.intellij.psi.impl.source.parsing.jsp.JspLexer.start(JspLexer.java\n" + ":49)",
|
||||
|
||||
" at com.intellij.lang.jsp.JspFileViewProviderImpl.getKeyPrefixes(JspFileViewProviderImpl.java:76)\n" +
|
||||
" at com.intellij.lang.jsp.JspFileViewProviderImpl.getKnownTaglibPrefixes(JspFileViewProviderImpl.java:89)\n" +
|
||||
" - locked <0x04cc0768> (a java.lang.Object)\n" +
|
||||
" at com.intellij.psi.impl.source.parsing.jsp.JspLexer.doInitOriginal(JspLexer.java:39)\n" +
|
||||
" at com.intellij.psi.impl.source.parsing.jsp.JspLexer.start(JspLexer.java:49)");
|
||||
}
|
||||
public void testAtSplit() {
|
||||
doTest("java.lang.Throwable\n" +
|
||||
"at\n" +
|
||||
"com.intellij.openapi.util.objectTree.ObjectNode.<init>(ObjectNode.jav\n" + "a:31)\n" +
|
||||
"at\n" +
|
||||
"com.intellij.openapi.util.objectTree.ObjectTree.getNodeFor(ObjectTree\n" + ".java:79)",
|
||||
|
||||
"java.lang.Throwable\n" +
|
||||
"at com.intellij.openapi.util.objectTree.ObjectNode.<init>(ObjectNode.java:31)\n" +
|
||||
"at com.intellij.openapi.util.objectTree.ObjectTree.getNodeFor(ObjectTree.java:79)");
|
||||
}
|
||||
|
||||
public void testSplitMergedLines() {
|
||||
doTest("org.apache.velocity.exception.MethodInvocationException " +
|
||||
"at org.apache.velocity.runtime.parser.node.ASTMethod.execute(ASTMethod.java:246) " +
|
||||
"at org.apache.velocity.runtime.parser.node.ASTReference.execute(ASTReference.java:175) " +
|
||||
"at org.apache.velocity.runtime.parser.node.ASTReference.value(ASTReference.java:327) " +
|
||||
"at org.apache.velocity.runtime.parser.node.ASTExpression.value(ASTExpression.java:51) " +
|
||||
"at org.apache.velocity.runtime.parser.node.ASTSetDirective.render(ASTSetDirective.java:95) " +
|
||||
"at org.apache.velocity.runtime.parser.node.ASTBlock.render(ASTBlock.java:55) " +
|
||||
"at org.apache.velocity.runtime.directive.Foreach.render(Foreach.java:166) " +
|
||||
"at org.apache.velocity.runtime.parser.node.ASTDirective.render(ASTDirective.java:114) " +
|
||||
"at org.apache.velocity.runtime.parser.node.SimpleNode.render(SimpleNode.java:230) " +
|
||||
"at org.apache.velocity.runtime.directive.VelocimacroProxy.render(VelocimacroProxy.java:172) " +
|
||||
"at org.apache.velocity.runtime.parser.node.ASTDirective.render(ASTDirective.java:114) " +
|
||||
"at org.apache.velocity.runtime.parser.node.SimpleNode.render(SimpleNode.java:230) " +
|
||||
"at org.apache.velocity.Template.merge(Template.java:256)",
|
||||
|
||||
"org.apache.velocity.exception.MethodInvocationException\n" +
|
||||
"at org.apache.velocity.runtime.parser.node.ASTMethod.execute(ASTMethod.java:246)\n" +
|
||||
"at org.apache.velocity.runtime.parser.node.ASTReference.execute(ASTReference.java:175)\n" +
|
||||
"at org.apache.velocity.runtime.parser.node.ASTReference.value(ASTReference.java:327)\n" +
|
||||
"at org.apache.velocity.runtime.parser.node.ASTExpression.value(ASTExpression.java:51)\n" +
|
||||
"at org.apache.velocity.runtime.parser.node.ASTSetDirective.render(ASTSetDirective.java:95)\n" +
|
||||
"at org.apache.velocity.runtime.parser.node.ASTBlock.render(ASTBlock.java:55)\n" +
|
||||
"at org.apache.velocity.runtime.directive.Foreach.render(Foreach.java:166)\n" +
|
||||
"at org.apache.velocity.runtime.parser.node.ASTDirective.render(ASTDirective.java:114)\n" +
|
||||
"at org.apache.velocity.runtime.parser.node.SimpleNode.render(SimpleNode.java:230)\n" +
|
||||
"at org.apache.velocity.runtime.directive.VelocimacroProxy.render(VelocimacroProxy.java:172)\n" +
|
||||
"at org.apache.velocity.runtime.parser.node.ASTDirective.render(ASTDirective.java:114)\n" +
|
||||
"at org.apache.velocity.runtime.parser.node.SimpleNode.render(SimpleNode.java:230)\n" +
|
||||
"at org.apache.velocity.Template.merge(Template.java:256)");
|
||||
}
|
||||
|
||||
private static void doTest(@NonNls String stackTrace, @NonNls String expected) {
|
||||
String normalized = UnscrambleDialog.normalizeText(stackTrace);
|
||||
assertEquals(expected, normalized);
|
||||
}
|
||||
}
|
||||
@@ -57,16 +57,6 @@ public class LanguageLevelModuleExtension extends ModuleExtension<LanguageLevelM
|
||||
|
||||
public void setLanguageLevel(final LanguageLevel languageLevel) {
|
||||
LOG.assertTrue(myWritable, "Writable model can be retrieved from writable ModifiableRootModel");
|
||||
if (mySource != null && myModule.isLoaded()) { //do not reload project for non-commited modules: j2me|project imports
|
||||
if (myLanguageLevel != languageLevel) {
|
||||
final LanguageLevelProjectExtension languageLevelProjectExtension = LanguageLevelProjectExtension.getInstance(myModule.getProject());
|
||||
final LanguageLevel projectLanguageLevel = languageLevelProjectExtension.getLanguageLevel();
|
||||
if (!(languageLevel == null && myLanguageLevel == projectLanguageLevel ||
|
||||
myLanguageLevel == null && languageLevel == projectLanguageLevel)) {
|
||||
languageLevelProjectExtension.reloadProjectOnLanguageLevelChange(languageLevel == null ? projectLanguageLevel : languageLevel, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
myLanguageLevel = languageLevel;
|
||||
}
|
||||
|
||||
@@ -103,6 +93,18 @@ public class LanguageLevelModuleExtension extends ModuleExtension<LanguageLevelM
|
||||
@Override
|
||||
public void commit() {
|
||||
if (mySource != null && mySource.myLanguageLevel != myLanguageLevel) {
|
||||
if (myModule.isLoaded()) { //do not reload project for non-committed modules: j2me|project imports
|
||||
if (mySource.myLanguageLevel != myLanguageLevel) {
|
||||
final LanguageLevelProjectExtension languageLevelProjectExtension =
|
||||
LanguageLevelProjectExtension.getInstance(myModule.getProject());
|
||||
final LanguageLevel projectLanguageLevel = languageLevelProjectExtension.getLanguageLevel();
|
||||
final boolean explicit2ImplicitProjectLevel = myLanguageLevel == null && mySource.myLanguageLevel == projectLanguageLevel;
|
||||
final boolean implicit2ExplicitProjectLevel = mySource.myLanguageLevel == null && myLanguageLevel == projectLanguageLevel;
|
||||
if (!(explicit2ImplicitProjectLevel || implicit2ExplicitProjectLevel)) {
|
||||
languageLevelProjectExtension.reloadProjectOnLanguageLevelChange(myLanguageLevel == null ? projectLanguageLevel : myLanguageLevel, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
mySource.myLanguageLevel = myLanguageLevel;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,137 @@
|
||||
/*
|
||||
* Copyright (c) 2000-2006 JetBrains s.r.o. All Rights Reserved.
|
||||
*/
|
||||
package com.intellij.mock;
|
||||
|
||||
import com.intellij.navigation.ItemPresentation;
|
||||
import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.search.PsiElementProcessor;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import com.intellij.lang.Language;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* @author peter
|
||||
*/
|
||||
public class MockPsiDirectory extends MockPsiElement implements PsiDirectory {
|
||||
private final PsiPackage myPackage;
|
||||
|
||||
public MockPsiDirectory(final PsiPackage aPackage, @NotNull Disposable parentDisposable) {
|
||||
super(parentDisposable);
|
||||
myPackage = aPackage;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDirectory() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Language getLanguage() {
|
||||
return Language.ANY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void checkCreateFile(@NotNull final String name) throws IncorrectOperationException {
|
||||
throw new IncorrectOperationException("Method checkCreateFile is not yet implemented in " + getClass().getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void checkCreateSubdirectory(@NotNull final String name) throws IncorrectOperationException {
|
||||
throw new IncorrectOperationException("Method checkCreateSubdirectory is not yet implemented in " + getClass().getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiDirectory getParent() {
|
||||
return getParentDirectory();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public PsiFile createFile(@NotNull final String name) throws IncorrectOperationException {
|
||||
throw new IncorrectOperationException("Method createFile is not yet implemented in " + getClass().getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public PsiFile copyFileFrom(@NotNull final String newName, @NotNull final PsiFile originalFile) throws IncorrectOperationException {
|
||||
throw new IncorrectOperationException("Method copyFileFrom is not yet implemented in " + getClass().getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public PsiDirectory createSubdirectory(@NotNull final String name) throws IncorrectOperationException {
|
||||
throw new IncorrectOperationException("Method createSubdirectory is not yet implemented in " + getClass().getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public PsiFile findFile(@NotNull @NonNls final String name) {
|
||||
throw new UnsupportedOperationException("Method findFile is not yet implemented in " + getClass().getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public PsiDirectory findSubdirectory(@NotNull final String name) {
|
||||
throw new UnsupportedOperationException("Method findSubdirectory is not yet implemented in " + getClass().getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public PsiFile[] getFiles() {
|
||||
throw new UnsupportedOperationException("Method getFiles is not yet implemented in " + getClass().getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public String getName() {
|
||||
throw new UnsupportedOperationException("Method getName is not yet implemented in " + getClass().getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public PsiDirectory getParentDirectory() {
|
||||
final PsiPackage psiPackage = myPackage.getParentPackage();
|
||||
return psiPackage == null ? null : new MockPsiDirectory(psiPackage, getProject());
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public PsiDirectory[] getSubdirectories() {
|
||||
throw new UnsupportedOperationException("Method getSubdirectories is not yet implemented in " + getClass().getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public VirtualFile getVirtualFile() {
|
||||
throw new UnsupportedOperationException("Method getVirtualFile is not yet implemented in " + getClass().getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean processChildren(final PsiElementProcessor<PsiFileSystemItem> processor) {
|
||||
throw new UnsupportedOperationException("Method processChildren is not yet implemented in " + getClass().getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public PsiElement setName(@NotNull final String name) throws IncorrectOperationException {
|
||||
throw new IncorrectOperationException("Method setName is not yet implemented in " + getClass().getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void checkSetName(final String name) throws IncorrectOperationException {
|
||||
throw new IncorrectOperationException("Method checkSetName is not yet implemented in " + getClass().getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public ItemPresentation getPresentation() {
|
||||
throw new UnsupportedOperationException("Method getPresentation is not yet implemented in " + getClass().getName());
|
||||
}
|
||||
}
|
||||
@@ -15,40 +15,12 @@
|
||||
*/
|
||||
package com.intellij.testFramework;
|
||||
|
||||
import com.intellij.ide.util.treeView.AbstractTreeNode;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.roots.LanguageLevelModuleExtension;
|
||||
import com.intellij.openapi.roots.LanguageLevelProjectExtension;
|
||||
import com.intellij.openapi.ui.Queryable;
|
||||
import com.intellij.pom.java.LanguageLevel;
|
||||
|
||||
import java.util.Comparator;
|
||||
|
||||
public class IdeaTestUtil extends PlatformTestUtil {
|
||||
public static Comparator<AbstractTreeNode> createComparator(final Queryable.PrintInfo printInfo) {
|
||||
return new Comparator<AbstractTreeNode>() {
|
||||
@Override
|
||||
public int compare(final AbstractTreeNode o1, final AbstractTreeNode o2) {
|
||||
String displayText1 = o1.toTestString(printInfo);
|
||||
String displayText2 = o2.toTestString(printInfo);
|
||||
return displayText1.compareTo(displayText2);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Use {@link #createComparator(com.intellij.openapi.ui.Queryable.PrintInfo)} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
public static final Comparator<AbstractTreeNode> DEFAULT_COMPARATOR = new Comparator<AbstractTreeNode>() {
|
||||
@Override
|
||||
public int compare(AbstractTreeNode o1, AbstractTreeNode o2) {
|
||||
String displayText1 = o1.getTestPresentation();
|
||||
String displayText2 = o2.getTestPresentation();
|
||||
return displayText1.compareTo(displayText2);
|
||||
}
|
||||
};
|
||||
|
||||
public static void main(String[] args) {
|
||||
printDetectedPerformanceTimings();
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
* Copyright 2000-2011 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.
|
||||
@@ -30,6 +30,8 @@ import com.intellij.util.ThrowableRunnable;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* Service for reformatting code fragments, getting names for elements
|
||||
* according to the user's code style and working with import statements and full-qualified names.
|
||||
@@ -123,9 +125,7 @@ public abstract class CodeStyleManager {
|
||||
boolean canChangeWhiteSpacesOnly) throws IncorrectOperationException;
|
||||
|
||||
/**
|
||||
* Reformats a range of text in the specified file. This method works faster than
|
||||
* {@link #reformatRange(com.intellij.psi.PsiElement, int, int)} but invalidates the
|
||||
* PSI structure for the file.
|
||||
* Delegates to the {@link #reformatText(PsiFile, Collection)} with the single range defined by the given offsets.
|
||||
*
|
||||
* @param element the file to reformat.
|
||||
* @param startOffset the start of the text range to reformat.
|
||||
@@ -135,7 +135,18 @@ public abstract class CodeStyleManager {
|
||||
public abstract void reformatText(@NotNull PsiFile element, int startOffset, int endOffset) throws IncorrectOperationException;
|
||||
|
||||
/**
|
||||
* Reformats the specified range of a file, modifying only line indents and leaving
|
||||
* Re-formats a ranges of text in the specified file. This method works faster than
|
||||
* {@link #reformatRange(com.intellij.psi.PsiElement, int, int)} but invalidates the
|
||||
* PSI structure for the file.
|
||||
*
|
||||
* @param element the file to reformat
|
||||
* @param ranges ranges to process
|
||||
* @throws IncorrectOperationException if the file to reformat is read-only.
|
||||
*/
|
||||
public abstract void reformatText(@NotNull PsiFile element, @NotNull Collection<TextRange> ranges) throws IncorrectOperationException;
|
||||
|
||||
/**
|
||||
* Re-formats the specified range of a file, modifying only line indents and leaving
|
||||
* all other whitespace intact.
|
||||
*
|
||||
* @param file the file to reformat.
|
||||
|
||||
@@ -776,6 +776,7 @@ public class DocumentImpl extends UserDataHolderBase implements DocumentEx {
|
||||
|
||||
@Override
|
||||
public final void setInBulkUpdate(boolean value) {
|
||||
ApplicationManager.getApplication().assertIsDispatchThread();
|
||||
myDoingBulkUpdate = value;
|
||||
myText.setDeferredChangeMode(value);
|
||||
if (value) {
|
||||
|
||||
@@ -20,7 +20,11 @@
|
||||
package com.intellij.lang;
|
||||
|
||||
import com.intellij.psi.PsiFile;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public class LanguageImportStatements extends LanguageExtension<ImportOptimizer> {
|
||||
public static final LanguageImportStatements INSTANCE = new LanguageImportStatements();
|
||||
@@ -29,9 +33,15 @@ public class LanguageImportStatements extends LanguageExtension<ImportOptimizer>
|
||||
super("com.intellij.lang.importOptimizer");
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public ImportOptimizer forFile(PsiFile file) {
|
||||
ImportOptimizer optimizer = forLanguage(file.getLanguage());
|
||||
return optimizer != null && optimizer.supports(file) ? optimizer : null;
|
||||
public List<Runnable> forFile(PsiFile file) {
|
||||
List<Runnable> runnables = new ArrayList<Runnable>();
|
||||
Set<ImportOptimizer> optimizers = new HashSet<ImportOptimizer>();
|
||||
for (PsiFile psiFile : file.getViewProvider().getAllFiles()) {
|
||||
ImportOptimizer optimizer = forLanguage(psiFile.getLanguage());
|
||||
if (optimizer != null && optimizer.supports(psiFile) && optimizers.add(optimizer)) {
|
||||
runnables.add(optimizer.processFile(psiFile));
|
||||
}
|
||||
}
|
||||
return runnables;
|
||||
}
|
||||
}
|
||||
@@ -125,6 +125,9 @@ public class ModuleUtil {
|
||||
if (orderEntries.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
if (orderEntries.size() == 1) {
|
||||
return orderEntries.get(0).getOwnerModule();
|
||||
}
|
||||
Set<Module> modules = new HashSet<Module>();
|
||||
for (OrderEntry orderEntry : orderEntries) {
|
||||
modules.add(orderEntry.getOwnerModule());
|
||||
|
||||
@@ -59,7 +59,7 @@ public class CommonRefactoringUtil {
|
||||
}
|
||||
}
|
||||
|
||||
public static void showErrorHint(Project project, @Nullable Editor editor, String message, String title, String helpId) {
|
||||
public static void showErrorHint(Project project, @Nullable Editor editor, String message, String title, @Nullable @NonNls String helpId) {
|
||||
if (ApplicationManager.getApplication().isUnitTestMode()) throw new RefactoringErrorHintException(message);
|
||||
|
||||
if (editor == null) {
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
<exclude-output />
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/testSrc" isTestSource="true" />
|
||||
</content>
|
||||
<orderEntry type="module" module-name="boot" />
|
||||
<orderEntry type="inheritedJdk" />
|
||||
@@ -19,11 +18,9 @@
|
||||
<orderEntry type="module" module-name="platform-impl" exported="" />
|
||||
<orderEntry type="module" module-name="usageView" exported="" />
|
||||
<orderEntry type="library" name="Guava" level="project" />
|
||||
<orderEntry type="library" scope="TEST" name="Mocks" level="project" />
|
||||
<orderEntry type="module" module-name="xdebugger-api" />
|
||||
<orderEntry type="library" name="xpp3-1.1.4-min" level="project" />
|
||||
<orderEntry type="library" exported="" name="cli-parser" level="project" />
|
||||
<orderEntry type="module" module-name="testFramework" scope="TEST" />
|
||||
<orderEntry type="library" name="http-client-3.1" level="project" />
|
||||
</component>
|
||||
</module>
|
||||
|
||||
+41
-18
@@ -66,18 +66,18 @@ public abstract class AbstractLayoutCodeProcessor {
|
||||
private final String myProgressText;
|
||||
private final String myCommandName;
|
||||
private final Runnable myPostRunnable;
|
||||
private final boolean myProcessChangedTextOnly;
|
||||
|
||||
protected AbstractLayoutCodeProcessor(Project project, String commandName, String progressText) {
|
||||
myProject = project;
|
||||
myModule = null;
|
||||
myDirectory = null;
|
||||
myIncludeSubdirs = true;
|
||||
myCommandName = commandName;
|
||||
myProgressText = progressText;
|
||||
myPostRunnable = null;
|
||||
protected AbstractLayoutCodeProcessor(Project project, String commandName, String progressText, boolean processChangedTextOnly) {
|
||||
this(project, (Module)null, commandName, progressText, processChangedTextOnly);
|
||||
}
|
||||
|
||||
protected AbstractLayoutCodeProcessor(Project project, Module module, String commandName, String progressText) {
|
||||
protected AbstractLayoutCodeProcessor(Project project,
|
||||
@Nullable Module module,
|
||||
String commandName,
|
||||
String progressText,
|
||||
boolean processChangedTextOnly)
|
||||
{
|
||||
myProject = project;
|
||||
myModule = module;
|
||||
myDirectory = null;
|
||||
@@ -85,9 +85,16 @@ public abstract class AbstractLayoutCodeProcessor {
|
||||
myCommandName = commandName;
|
||||
myProgressText = progressText;
|
||||
myPostRunnable = null;
|
||||
myProcessChangedTextOnly = processChangedTextOnly;
|
||||
}
|
||||
|
||||
protected AbstractLayoutCodeProcessor(Project project, PsiDirectory directory, boolean includeSubdirs, String progressText, String commandName) {
|
||||
protected AbstractLayoutCodeProcessor(Project project,
|
||||
PsiDirectory directory,
|
||||
boolean includeSubdirs,
|
||||
String progressText,
|
||||
String commandName,
|
||||
boolean processChangedTextOnly)
|
||||
{
|
||||
myProject = project;
|
||||
myModule = null;
|
||||
myDirectory = directory;
|
||||
@@ -95,24 +102,38 @@ public abstract class AbstractLayoutCodeProcessor {
|
||||
myProgressText = progressText;
|
||||
myCommandName = commandName;
|
||||
myPostRunnable = null;
|
||||
myProcessChangedTextOnly = processChangedTextOnly;
|
||||
}
|
||||
|
||||
protected AbstractLayoutCodeProcessor(Project project, PsiFile file, String progressText, String commandName) {
|
||||
protected AbstractLayoutCodeProcessor(Project project,
|
||||
PsiFile file,
|
||||
String progressText,
|
||||
String commandName,
|
||||
boolean processChangedTextOnly)
|
||||
{
|
||||
myProject = project;
|
||||
myModule = null;
|
||||
myFile = file;
|
||||
myProgressText = progressText;
|
||||
myCommandName = commandName;
|
||||
myPostRunnable = null;
|
||||
myProcessChangedTextOnly = processChangedTextOnly;
|
||||
}
|
||||
|
||||
protected AbstractLayoutCodeProcessor(Project project, PsiFile[] files, String progressText, String commandName, Runnable postRunnable) {
|
||||
protected AbstractLayoutCodeProcessor(Project project,
|
||||
PsiFile[] files,
|
||||
String progressText,
|
||||
String commandName,
|
||||
@Nullable Runnable postRunnable,
|
||||
boolean processChangedTextOnly)
|
||||
{
|
||||
myProject = project;
|
||||
myModule = null;
|
||||
myFiles = filterFiles(files);
|
||||
myProgressText = progressText;
|
||||
myCommandName = commandName;
|
||||
myPostRunnable = postRunnable;
|
||||
myProcessChangedTextOnly = processChangedTextOnly;
|
||||
}
|
||||
|
||||
private static PsiFile[] filterFiles(PsiFile[] files){
|
||||
@@ -128,13 +149,15 @@ public abstract class AbstractLayoutCodeProcessor {
|
||||
/**
|
||||
* Ensures that given file is ready to reformatting and prepares it if necessary.
|
||||
*
|
||||
* @param file file to process
|
||||
* @param file file to process
|
||||
* @param processChangedTextOnly flag that defines is only the changed text (in terms of VCS change) should be processed
|
||||
* @return task that triggers formatting of the given file. Returns value of that task indicates whether formatting
|
||||
* is finished correctly or not (exception occurred, user cancelled formatting etc)
|
||||
* @throws IncorrectOperationException if unexpected exception occurred during formatting
|
||||
*/
|
||||
@NotNull
|
||||
protected abstract FutureTask<Boolean> preprocessFile(PsiFile file) throws IncorrectOperationException;
|
||||
protected abstract FutureTask<Boolean> preprocessFile(@NotNull PsiFile file, boolean processChangedTextOnly)
|
||||
throws IncorrectOperationException;
|
||||
|
||||
public void run() {
|
||||
if (myDirectory != null){
|
||||
@@ -154,7 +177,7 @@ public abstract class AbstractLayoutCodeProcessor {
|
||||
}
|
||||
}
|
||||
|
||||
private void runProcessFile(final PsiFile file) {
|
||||
private void runProcessFile(@NotNull final PsiFile file) {
|
||||
Document document = PsiDocumentManager.getInstance(myProject).getDocument(file);
|
||||
|
||||
if (document == null) {
|
||||
@@ -174,7 +197,7 @@ public abstract class AbstractLayoutCodeProcessor {
|
||||
public void run() {
|
||||
if (!checkFileWritable(file)) return;
|
||||
try{
|
||||
resultRunnable[0] = preprocessFile(file);
|
||||
resultRunnable[0] = preprocessFile(file, myProcessChangedTextOnly);
|
||||
}
|
||||
catch(IncorrectOperationException e){
|
||||
LOG.error(e);
|
||||
@@ -223,7 +246,7 @@ public abstract class AbstractLayoutCodeProcessor {
|
||||
}
|
||||
if (file.isWritable()){
|
||||
try{
|
||||
tasks.add(preprocessFile(file));
|
||||
tasks.add(preprocessFile(file, myProcessChangedTextOnly));
|
||||
}
|
||||
catch(IncorrectOperationException e){
|
||||
LOG.error(e);
|
||||
@@ -487,7 +510,7 @@ public abstract class AbstractLayoutCodeProcessor {
|
||||
}
|
||||
|
||||
public void runWithoutProgress() throws IncorrectOperationException {
|
||||
final Runnable runnable = preprocessFile(myFile);
|
||||
final Runnable runnable = preprocessFile(myFile, myProcessChangedTextOnly);
|
||||
runnable.run();
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,211 @@
|
||||
/*
|
||||
* Copyright 2000-2011 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.codeInsight.actions;
|
||||
|
||||
import com.intellij.openapi.application.ReadAction;
|
||||
import com.intellij.openapi.application.Result;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.editor.markup.RangeHighlighter;
|
||||
import com.intellij.openapi.module.ModifiableModuleModel;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.module.ModuleManager;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.roots.ModuleRootManager;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.openapi.vcs.changes.Change;
|
||||
import com.intellij.openapi.vcs.changes.ChangeListManager;
|
||||
import com.intellij.openapi.vcs.ex.LineStatusTracker;
|
||||
import com.intellij.openapi.vcs.ex.Range;
|
||||
import com.intellij.openapi.vcs.impl.LineStatusTrackerManager;
|
||||
import com.intellij.openapi.vcs.impl.LineStatusTrackerManagerI;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.PsiDirectory;
|
||||
import com.intellij.psi.PsiDocumentManager;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Contains utility methods for 'format only changed text' (in terms of VCS changes).
|
||||
*
|
||||
* @author Denis Zhdanov
|
||||
* @since 12/19/11 10:55 AM
|
||||
*/
|
||||
public class FormatChangedTextUtil {
|
||||
|
||||
private FormatChangedTextUtil() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows to answer if given file has changes in comparison with VCS.
|
||||
*
|
||||
* @param file target file
|
||||
* @return <code>true</code> if given file has changes; <code>false</code> otherwise
|
||||
*/
|
||||
public static boolean hasChanges(@NotNull PsiFile file) {
|
||||
final Project project = file.getProject();
|
||||
final VirtualFile virtualFile = file.getVirtualFile();
|
||||
if (virtualFile != null) {
|
||||
final Change change = ChangeListManager.getInstance(project).getChange(virtualFile);
|
||||
if (change != null && change.getType() == Change.Type.NEW) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
final LineStatusTrackerManagerI manager = LineStatusTrackerManager.getInstance(project);
|
||||
if (manager == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final Document document = PsiDocumentManager.getInstance(project).getDocument(file);
|
||||
if (document == null) {
|
||||
return false;
|
||||
}
|
||||
final LineStatusTracker lineStatusTracker = manager.getLineStatusTracker(document);
|
||||
if (lineStatusTracker == null) {
|
||||
return false;
|
||||
}
|
||||
final List<Range> ranges = lineStatusTracker.getRanges();
|
||||
if (ranges == null || ranges.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
for (Range range : ranges) {
|
||||
if (range.getType() != Range.DELETED) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows to answer if any file below the given directory (any level of nesting) has changes in comparison with VCS.
|
||||
*
|
||||
* @param directory target directory to check
|
||||
* @return <code>true</code> if any file below the given directory has changes in comparison with VCS;
|
||||
* <code>false</code> otherwise
|
||||
*/
|
||||
public static boolean hasChanges(@NotNull PsiDirectory directory) {
|
||||
return hasChanges(directory.getVirtualFile(), directory.getProject());
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows to answer if given file or any file below the given directory (any level of nesting) has changes in comparison with VCS.
|
||||
*
|
||||
* @param file target directory to check
|
||||
* @param project target project
|
||||
* @return <code>true</code> if given file or any file below the given directory has changes in comparison with VCS;
|
||||
* <code>false</code> otherwise
|
||||
*/
|
||||
public static boolean hasChanges(@NotNull VirtualFile file, @NotNull Project project) {
|
||||
final Collection<Change> changes = ChangeListManager.getInstance(project).getChangesIn(file);
|
||||
for (Change change : changes) {
|
||||
if (change.getType() == Change.Type.NEW || change.getType() == Change.Type.MODIFICATION) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows to answer if any file that belongs to the given module has changes in comparison with VCS.
|
||||
*
|
||||
* @param module target module to check
|
||||
* @return <code>true</code> if any file that belongs to the given module has changes in comparison with VCS
|
||||
* <code>false</code> otherwise
|
||||
*/
|
||||
public static boolean hasChanges(@NotNull Module module) {
|
||||
final ModuleRootManager rootManager = ModuleRootManager.getInstance(module);
|
||||
for (VirtualFile root : rootManager.getSourceRoots()) {
|
||||
if (hasChanges(root, module.getProject())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows to answer if any file that belongs to the given project has changes in comparison with VCS.
|
||||
*
|
||||
* @param project target project to check
|
||||
* @return <code>true</code> if any file that belongs to the given project has changes in comparison with VCS
|
||||
* <code>false</code> otherwise
|
||||
*/
|
||||
public static boolean hasChanges(@NotNull final Project project) {
|
||||
final ModifiableModuleModel moduleModel = new ReadAction<ModifiableModuleModel>() {
|
||||
protected void run(Result<ModifiableModuleModel> result) throws Throwable {
|
||||
result.setResult(ModuleManager.getInstance(project).getModifiableModel());
|
||||
}
|
||||
}.execute().getResultObject();
|
||||
try {
|
||||
for (Module module : moduleModel.getModules()) {
|
||||
if (hasChanges(module)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
finally {
|
||||
moduleModel.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows to ask for the changed text of the given file (in comparison with VCS).
|
||||
*
|
||||
* @param file target file
|
||||
* @return collection of changed regions for the given file
|
||||
*/
|
||||
@NotNull
|
||||
public static Collection<TextRange> getChanges(@NotNull PsiFile file) {
|
||||
final Set<TextRange> defaultResult = Collections.singleton(file.getTextRange());
|
||||
final VirtualFile virtualFile = file.getVirtualFile();
|
||||
if (virtualFile != null) {
|
||||
final Change change = ChangeListManager.getInstance(file.getProject()).getChange(virtualFile);
|
||||
if (change != null && change.getType() == Change.Type.NEW) {
|
||||
return defaultResult;
|
||||
}
|
||||
}
|
||||
|
||||
final LineStatusTrackerManagerI manager = LineStatusTrackerManager.getInstance(file.getProject());
|
||||
if (manager == null) {
|
||||
return defaultResult;
|
||||
}
|
||||
final Document document = PsiDocumentManager.getInstance(file.getProject()).getDocument(file);
|
||||
if (document == null) {
|
||||
return defaultResult;
|
||||
}
|
||||
final LineStatusTracker lineStatusTracker = manager.getLineStatusTracker(document);
|
||||
if (lineStatusTracker == null) {
|
||||
return defaultResult;
|
||||
}
|
||||
final List<Range> ranges = lineStatusTracker.getRanges();
|
||||
if (ranges == null || ranges.isEmpty()) {
|
||||
return defaultResult;
|
||||
}
|
||||
|
||||
List<TextRange> result = new ArrayList<TextRange>();
|
||||
for (Range range : ranges) {
|
||||
if (range.getType() != Range.DELETED) {
|
||||
final RangeHighlighter highlighter = range.getHighlighter();
|
||||
if (highlighter != null) {
|
||||
result.add(new TextRange(highlighter.getStartOffset(), highlighter.getEndOffset()));
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
+12
-15
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
* Copyright 2000-2011 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.
|
||||
@@ -13,22 +13,19 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.openapi.editor.impl.event;
|
||||
package com.intellij.codeInsight.actions;
|
||||
|
||||
import com.intellij.openapi.editor.markup.MarkupModel;
|
||||
import com.intellij.openapi.editor.markup.RangeHighlighter;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
|
||||
import java.util.EventObject;
|
||||
/**
|
||||
* @author Denis Zhdanov
|
||||
* @since 12/16/11 6:10 PM
|
||||
*/
|
||||
public class LayoutCodeConstants {
|
||||
|
||||
public class MarkupModelEvent extends EventObject {
|
||||
private final RangeHighlighter myHighlighter;
|
||||
|
||||
public MarkupModelEvent(MarkupModel source, RangeHighlighter segmentHighlighter) {
|
||||
super(source);
|
||||
myHighlighter = segmentHighlighter;
|
||||
}
|
||||
|
||||
public RangeHighlighter getHighlighter() {
|
||||
return myHighlighter;
|
||||
public static final @NonNls String OPTIMIZE_IMPORTS_KEY = "LayoutCode.optimizeImports";
|
||||
public static final @NonNls String PROCESS_CHANGED_TEXT_KEY = "LayoutCode.processChangedText";
|
||||
|
||||
private LayoutCodeConstants() {
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
* Copyright 2000-2011 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.
|
||||
@@ -26,7 +26,7 @@ import com.intellij.openapi.ui.DialogWrapper;
|
||||
import com.intellij.psi.PsiDirectory;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.util.ui.OptionsDialog;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
@@ -37,23 +37,23 @@ import java.awt.event.ItemEvent;
|
||||
import java.awt.event.ItemListener;
|
||||
|
||||
public class LayoutCodeDialog extends DialogWrapper {
|
||||
private final PsiFile myFile;
|
||||
private final PsiFile myFile;
|
||||
@Nullable private final PsiDirectory myDirectory;
|
||||
private final Boolean myTextSelected;
|
||||
private final Boolean myTextSelected;
|
||||
|
||||
private JRadioButton myRbFile;
|
||||
private JRadioButton myRbSelectedText;
|
||||
private JRadioButton myRbDirectory;
|
||||
private JCheckBox myCbIncludeSubdirs;
|
||||
private JCheckBox myCbOptimizeImports;
|
||||
private JCheckBox myDoNotAskMeCheckBox;
|
||||
private JCheckBox myCbIncludeSubdirs;
|
||||
private JCheckBox myCbOptimizeImports;
|
||||
private JCheckBox myCbOnlyVcsChangedRegions;
|
||||
private JCheckBox myDoNotAskMeCheckBox;
|
||||
|
||||
public static final @NonNls String OPTIMIZE_IMPORTS_KEY = "LayoutCode.optimizeImports";
|
||||
private final String myHelpId;
|
||||
|
||||
public LayoutCodeDialog(Project project,
|
||||
String title,
|
||||
PsiFile file,
|
||||
public LayoutCodeDialog(@NotNull Project project,
|
||||
@NotNull String title,
|
||||
@Nullable PsiFile file,
|
||||
@Nullable PsiDirectory directory,
|
||||
Boolean isTextSelected,
|
||||
final String helpId) {
|
||||
@@ -84,7 +84,7 @@ public class LayoutCodeDialog extends DialogWrapper {
|
||||
}
|
||||
|
||||
myCbIncludeSubdirs.setSelected(true);
|
||||
myCbOptimizeImports.setSelected(isOptmizeImportsOptionOn());
|
||||
myCbOptimizeImports.setSelected(PropertiesComponent.getInstance().getBoolean(LayoutCodeConstants.OPTIMIZE_IMPORTS_KEY, false));
|
||||
|
||||
ItemListener listener = new ItemListener() {
|
||||
public void itemStateChanged(ItemEvent e) {
|
||||
@@ -99,18 +99,17 @@ public class LayoutCodeDialog extends DialogWrapper {
|
||||
updateState();
|
||||
}
|
||||
|
||||
private static boolean isOptmizeImportsOptionOn() {
|
||||
return Boolean.toString(true).equals(PropertiesComponent.getInstance().getValue(OPTIMIZE_IMPORTS_KEY));
|
||||
}
|
||||
|
||||
private static void setOptimizeImportsOption(boolean state) {
|
||||
PropertiesComponent.getInstance().setValue(OPTIMIZE_IMPORTS_KEY, Boolean.toString(state));
|
||||
}
|
||||
|
||||
private void updateState() {
|
||||
myCbIncludeSubdirs.setEnabled(myRbDirectory.isSelected());
|
||||
myCbOptimizeImports.setEnabled(
|
||||
!myRbSelectedText.isSelected() && !(myFile != null && LanguageImportStatements.INSTANCE.forFile(myFile) == null && myRbFile.isSelected()));
|
||||
!myRbSelectedText.isSelected() &&
|
||||
!(myFile != null && LanguageImportStatements.INSTANCE.forFile(myFile).isEmpty() && myRbFile.isSelected()));
|
||||
|
||||
final boolean canTargetVcsChanges = canTargetVcsRegions();
|
||||
myCbOnlyVcsChangedRegions.setEnabled(canTargetVcsChanges);
|
||||
myCbOnlyVcsChangedRegions.setSelected(
|
||||
canTargetVcsChanges && PropertiesComponent.getInstance().getBoolean(LayoutCodeConstants.PROCESS_CHANGED_TEXT_KEY, false)
|
||||
);
|
||||
|
||||
myDoNotAskMeCheckBox.setEnabled(!myRbDirectory.isSelected());
|
||||
myRbDirectory.setEnabled(!myDoNotAskMeCheckBox.isSelected());
|
||||
@@ -163,6 +162,10 @@ public class LayoutCodeDialog extends DialogWrapper {
|
||||
panel.add(myCbOptimizeImports, gbConstraints);
|
||||
}
|
||||
|
||||
myCbOnlyVcsChangedRegions = new JCheckBox(CodeInsightBundle.message("reformat.option.vcs.changed.region"));
|
||||
gbConstraints.gridy++;
|
||||
panel.add(myCbOnlyVcsChangedRegions, gbConstraints);
|
||||
|
||||
ButtonGroup buttonGroup = new ButtonGroup();
|
||||
buttonGroup.add(myRbFile);
|
||||
buttonGroup.add(myRbSelectedText);
|
||||
@@ -201,7 +204,7 @@ public class LayoutCodeDialog extends DialogWrapper {
|
||||
public boolean isProcessWholeFile() {
|
||||
return myRbFile.isSelected();
|
||||
}
|
||||
|
||||
|
||||
public boolean isProcessDirectory() {
|
||||
return myRbDirectory.isSelected();
|
||||
}
|
||||
@@ -214,12 +217,35 @@ public class LayoutCodeDialog extends DialogWrapper {
|
||||
return myCbOptimizeImports.isSelected();
|
||||
}
|
||||
|
||||
public boolean isProcessOnlyChangedText() {
|
||||
return myCbOnlyVcsChangedRegions.isEnabled() && myCbOnlyVcsChangedRegions.isSelected();
|
||||
}
|
||||
|
||||
boolean isDoNotAskMe() {
|
||||
return myDoNotAskMeCheckBox.isSelected();
|
||||
return myDoNotAskMeCheckBox.isSelected();
|
||||
}
|
||||
|
||||
protected void doOKAction() {
|
||||
super.doOKAction();
|
||||
setOptimizeImportsOption(isOptimizeImports());
|
||||
PropertiesComponent.getInstance().setValue(LayoutCodeConstants.OPTIMIZE_IMPORTS_KEY, Boolean.toString(isOptimizeImports()));
|
||||
PropertiesComponent.getInstance().setValue(LayoutCodeConstants.PROCESS_CHANGED_TEXT_KEY, Boolean.toString(isProcessOnlyChangedText()));
|
||||
}
|
||||
|
||||
private boolean canTargetVcsRegions() {
|
||||
if (isProcessSelectedText()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (isProcessWholeFile()) {
|
||||
return FormatChangedTextUtil.hasChanges(myFile);
|
||||
}
|
||||
|
||||
if (isProcessDirectory()) {
|
||||
if (myDirectory == null) {
|
||||
return false;
|
||||
}
|
||||
return FormatChangedTextUtil.hasChanges(myDirectory);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
+46
-16
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
* Copyright 2000-2011 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.
|
||||
@@ -19,9 +19,12 @@ package com.intellij.codeInsight.actions;
|
||||
import com.intellij.codeInsight.CodeInsightBundle;
|
||||
import com.intellij.ide.util.PropertiesComponent;
|
||||
import com.intellij.openapi.help.HelpManager;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.DialogWrapper;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
@@ -30,36 +33,51 @@ import java.awt.*;
|
||||
* @author max
|
||||
*/
|
||||
public class LayoutProjectCodeDialog extends DialogWrapper {
|
||||
private static @NonNls final String OPTIMIZE_IMPORTS_KEY = "LayoutCode.optimizeImports";
|
||||
private static @NonNls final String HELP_ID = "editing.codeReformatting";
|
||||
|
||||
private final String myText;
|
||||
private final boolean mySuggestOptmizeImports;
|
||||
private final String myText;
|
||||
private final boolean mySuggestOptimizeImports;
|
||||
private final Project myProject;
|
||||
private final Module myModule;
|
||||
|
||||
private JCheckBox myCbOptimizeImports;
|
||||
private JCheckBox myCbOnlyVcsChangedRegions;
|
||||
|
||||
public LayoutProjectCodeDialog(Project project, String title, String text, boolean suggestOptmizeImports) {
|
||||
public LayoutProjectCodeDialog(@NotNull Project project,
|
||||
@Nullable Module module,
|
||||
String title,
|
||||
String text,
|
||||
boolean suggestOptimizeImports)
|
||||
{
|
||||
super(project, false);
|
||||
myText = text;
|
||||
mySuggestOptmizeImports = suggestOptmizeImports;
|
||||
mySuggestOptimizeImports = suggestOptimizeImports;
|
||||
myProject = project;
|
||||
myModule = module;
|
||||
|
||||
setOKButtonText(CodeInsightBundle.message("reformat.code.accept.button.text"));
|
||||
setTitle(title);
|
||||
init();
|
||||
}
|
||||
|
||||
protected JComponent createCenterPanel() {
|
||||
if (!mySuggestOptmizeImports) return new JLabel(myText);
|
||||
JPanel panel = new JPanel(new GridLayout(2, 1));
|
||||
if (!mySuggestOptimizeImports) return new JLabel(myText);
|
||||
JPanel panel = new JPanel(new GridLayout(3, 1));
|
||||
panel.add(new JLabel(myText));
|
||||
myCbOptimizeImports = new JCheckBox(CodeInsightBundle.message("reformat.option.optimize.imports"));
|
||||
panel.add(myCbOptimizeImports);
|
||||
myCbOptimizeImports.setSelected(Boolean.toString(true).equals(PropertiesComponent.getInstance().getValue(OPTIMIZE_IMPORTS_KEY)));
|
||||
myCbOptimizeImports.setSelected(PropertiesComponent.getInstance().getBoolean(LayoutCodeConstants.OPTIMIZE_IMPORTS_KEY, false));
|
||||
|
||||
myCbOnlyVcsChangedRegions = new JCheckBox(CodeInsightBundle.message("reformat.option.vcs.changed.region"));
|
||||
panel.add(myCbOnlyVcsChangedRegions);
|
||||
final boolean canTargetVcsRegions = canTargetVcsRegions();
|
||||
myCbOnlyVcsChangedRegions.setEnabled(canTargetVcsRegions);
|
||||
myCbOnlyVcsChangedRegions.setSelected(
|
||||
canTargetVcsRegions && PropertiesComponent.getInstance().getBoolean(LayoutCodeConstants.PROCESS_CHANGED_TEXT_KEY, false)
|
||||
);
|
||||
return panel;
|
||||
}
|
||||
|
||||
private void setOptimizeImportsOption(boolean state) {
|
||||
PropertiesComponent.getInstance().setValue(OPTIMIZE_IMPORTS_KEY, Boolean.toString(state));
|
||||
}
|
||||
|
||||
|
||||
protected Action[] createActions() {
|
||||
return new Action[]{getOKAction(), getCancelAction(), getHelpAction()};
|
||||
}
|
||||
@@ -70,12 +88,24 @@ public class LayoutProjectCodeDialog extends DialogWrapper {
|
||||
|
||||
protected void doOKAction() {
|
||||
super.doOKAction();
|
||||
if (mySuggestOptmizeImports) {
|
||||
setOptimizeImportsOption(isOptimizeImports());
|
||||
if (mySuggestOptimizeImports) {
|
||||
PropertiesComponent.getInstance().setValue(LayoutCodeConstants.OPTIMIZE_IMPORTS_KEY, Boolean.toString(isOptimizeImports()));
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isOptimizeImports() {
|
||||
return myCbOptimizeImports.isSelected();
|
||||
}
|
||||
|
||||
public boolean isProcessOnlyChangedText() {
|
||||
return myCbOnlyVcsChangedRegions.isEnabled() && myCbOnlyVcsChangedRegions.isSelected();
|
||||
}
|
||||
|
||||
private boolean canTargetVcsRegions() {
|
||||
if (myModule != null) {
|
||||
return FormatChangedTextUtil.hasChanges(myModule);
|
||||
}
|
||||
|
||||
return FormatChangedTextUtil.hasChanges(myProject);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
* Copyright 2000-2011 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.
|
||||
@@ -54,7 +54,7 @@ public class OptimizeImportsAction extends AnAction {
|
||||
if (file == null) return;
|
||||
dir = file.getContainingDirectory();
|
||||
}
|
||||
else if (ReformatCodeAction.areFiles(files)) {
|
||||
else if (files != null && ReformatCodeAction.areFiles(files)) {
|
||||
final ReadonlyStatusHandler.OperationStatus operationStatus = ReadonlyStatusHandler.getInstance(project).ensureFilesWritable(files);
|
||||
if (!operationStatus.hasReadonlyFiles()) {
|
||||
new OptimizeImportsProcessor(project, ReformatCodeAction.convertToPsiFiles(files, project), null).run();
|
||||
@@ -73,7 +73,8 @@ public class OptimizeImportsAction extends AnAction {
|
||||
else {
|
||||
text = CodeInsightBundle.message("process.scope.project", projectContext.getPresentableUrl());
|
||||
}
|
||||
LayoutProjectCodeDialog dialog = new LayoutProjectCodeDialog(project, CodeInsightBundle.message("process.optimize.imports"), text, false);
|
||||
LayoutProjectCodeDialog dialog
|
||||
= new LayoutProjectCodeDialog(project, null, CodeInsightBundle.message("process.optimize.imports"), text, false);
|
||||
dialog.show();
|
||||
if (!dialog.isOK()) return;
|
||||
if (moduleContext != null) {
|
||||
@@ -192,6 +193,6 @@ public class OptimizeImportsAction extends AnAction {
|
||||
}
|
||||
|
||||
private static boolean isOptimizeImportsAvailable(final PsiFile file) {
|
||||
return LanguageImportStatements.INSTANCE.forFile(file) != null;
|
||||
return !LanguageImportStatements.INSTANCE.forFile(file).isEmpty();
|
||||
}
|
||||
}
|
||||
|
||||
+17
-10
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
* Copyright 2000-2011 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.
|
||||
@@ -17,7 +17,6 @@
|
||||
package com.intellij.codeInsight.actions;
|
||||
|
||||
import com.intellij.codeInsight.CodeInsightBundle;
|
||||
import com.intellij.lang.ImportOptimizer;
|
||||
import com.intellij.lang.LanguageImportStatements;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.project.Project;
|
||||
@@ -27,6 +26,7 @@ import com.intellij.psi.PsiFile;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.FutureTask;
|
||||
|
||||
public class OptimizeImportsProcessor extends AbstractLayoutCodeProcessor {
|
||||
@@ -34,19 +34,19 @@ public class OptimizeImportsProcessor extends AbstractLayoutCodeProcessor {
|
||||
private static final String COMMAND_NAME = CodeInsightBundle.message("process.optimize.imports");
|
||||
|
||||
public OptimizeImportsProcessor(Project project) {
|
||||
super(project, COMMAND_NAME, PROGRESS_TEXT);
|
||||
super(project, COMMAND_NAME, PROGRESS_TEXT, false);
|
||||
}
|
||||
|
||||
public OptimizeImportsProcessor(Project project, Module module) {
|
||||
super(project, module, COMMAND_NAME, PROGRESS_TEXT);
|
||||
super(project, module, COMMAND_NAME, PROGRESS_TEXT, false);
|
||||
}
|
||||
|
||||
public OptimizeImportsProcessor(Project project, PsiDirectory directory, boolean includeSubdirs) {
|
||||
super(project, directory, includeSubdirs, PROGRESS_TEXT, COMMAND_NAME);
|
||||
super(project, directory, includeSubdirs, PROGRESS_TEXT, COMMAND_NAME, false);
|
||||
}
|
||||
|
||||
public OptimizeImportsProcessor(Project project, PsiFile file) {
|
||||
super(project, file, PROGRESS_TEXT, COMMAND_NAME);
|
||||
super(project, file, PROGRESS_TEXT, COMMAND_NAME, false);
|
||||
}
|
||||
|
||||
public OptimizeImportsProcessor(Project project, PsiFile[] files, Runnable postRunnable) {
|
||||
@@ -54,13 +54,20 @@ public class OptimizeImportsProcessor extends AbstractLayoutCodeProcessor {
|
||||
}
|
||||
|
||||
public OptimizeImportsProcessor(Project project, PsiFile[] files, String commandName, Runnable postRunnable) {
|
||||
super(project, files, PROGRESS_TEXT, commandName, postRunnable);
|
||||
super(project, files, PROGRESS_TEXT, commandName, postRunnable, false);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
protected FutureTask<Boolean> preprocessFile(final PsiFile file) throws IncorrectOperationException {
|
||||
final ImportOptimizer optimizer = LanguageImportStatements.INSTANCE.forFile(file);
|
||||
Runnable runnable = optimizer != null ? optimizer.processFile(file) : EmptyRunnable.getInstance();
|
||||
protected FutureTask<Boolean> preprocessFile(@NotNull final PsiFile file, boolean processChangedTextOnly) throws IncorrectOperationException {
|
||||
final List<Runnable> optimizers = LanguageImportStatements.INSTANCE.forFile(file);
|
||||
Runnable runnable = optimizers.isEmpty() ? EmptyRunnable.getInstance() : new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
for (Runnable optimizer : optimizers) {
|
||||
optimizer.run();
|
||||
}
|
||||
}
|
||||
};
|
||||
return new FutureTask<Boolean>(runnable, true);
|
||||
}
|
||||
}
|
||||
|
||||
+23
-19
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
* Copyright 2000-2011 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.
|
||||
@@ -38,40 +38,44 @@ public class ReformatAndOptimizeImportsProcessor extends AbstractLayoutCodeProce
|
||||
private final OptimizeImportsProcessor myOptimizeImportsProcessor;
|
||||
private final ReformatCodeProcessor myReformatCodeProcessor;
|
||||
|
||||
public ReformatAndOptimizeImportsProcessor(Project project) {
|
||||
super(project, COMMAND_NAME, PROGRESS_TEXT);
|
||||
public ReformatAndOptimizeImportsProcessor(Project project, boolean processChangedTextOnly) {
|
||||
super(project, COMMAND_NAME, PROGRESS_TEXT, processChangedTextOnly);
|
||||
myOptimizeImportsProcessor = new OptimizeImportsProcessor(project);
|
||||
myReformatCodeProcessor = new ReformatCodeProcessor(project);
|
||||
myReformatCodeProcessor = new ReformatCodeProcessor(project, processChangedTextOnly);
|
||||
}
|
||||
|
||||
public ReformatAndOptimizeImportsProcessor(Project project, Module module) {
|
||||
super(project, module, COMMAND_NAME, PROGRESS_TEXT);
|
||||
public ReformatAndOptimizeImportsProcessor(Project project, Module module, boolean processChangedTextOnly) {
|
||||
super(project, module, COMMAND_NAME, PROGRESS_TEXT, processChangedTextOnly);
|
||||
myOptimizeImportsProcessor = new OptimizeImportsProcessor(project, module);
|
||||
myReformatCodeProcessor = new ReformatCodeProcessor(project, module);
|
||||
myReformatCodeProcessor = new ReformatCodeProcessor(project, module, processChangedTextOnly);
|
||||
}
|
||||
|
||||
public ReformatAndOptimizeImportsProcessor(Project project, PsiFile[] files) {
|
||||
super(project, files, PROGRESS_TEXT, COMMAND_NAME, null);
|
||||
public ReformatAndOptimizeImportsProcessor(Project project, PsiFile[] files, boolean processChangedTextOnly) {
|
||||
super(project, files, PROGRESS_TEXT, COMMAND_NAME, null, processChangedTextOnly);
|
||||
myOptimizeImportsProcessor = new OptimizeImportsProcessor(project);
|
||||
myReformatCodeProcessor = new ReformatCodeProcessor(project);
|
||||
myReformatCodeProcessor = new ReformatCodeProcessor(project, processChangedTextOnly);
|
||||
}
|
||||
|
||||
public ReformatAndOptimizeImportsProcessor(Project project, PsiDirectory directory, boolean includeSubdirs) {
|
||||
super(project, directory, includeSubdirs, PROGRESS_TEXT, COMMAND_NAME);
|
||||
public ReformatAndOptimizeImportsProcessor(Project project,
|
||||
PsiDirectory directory,
|
||||
boolean includeSubdirs,
|
||||
boolean processChangedTextOnly)
|
||||
{
|
||||
super(project, directory, includeSubdirs, PROGRESS_TEXT, COMMAND_NAME, processChangedTextOnly);
|
||||
myOptimizeImportsProcessor = new OptimizeImportsProcessor(project, directory, includeSubdirs);
|
||||
myReformatCodeProcessor = new ReformatCodeProcessor(project, directory, includeSubdirs);
|
||||
myReformatCodeProcessor = new ReformatCodeProcessor(project, directory, includeSubdirs, processChangedTextOnly);
|
||||
}
|
||||
|
||||
public ReformatAndOptimizeImportsProcessor(Project project, PsiFile file) {
|
||||
super(project, file, PROGRESS_TEXT, COMMAND_NAME);
|
||||
public ReformatAndOptimizeImportsProcessor(Project project, PsiFile file, boolean processChangedTextOnly) {
|
||||
super(project, file, PROGRESS_TEXT, COMMAND_NAME, processChangedTextOnly);
|
||||
myOptimizeImportsProcessor = new OptimizeImportsProcessor(project, file);
|
||||
myReformatCodeProcessor = new ReformatCodeProcessor(project, file, null);
|
||||
myReformatCodeProcessor = new ReformatCodeProcessor(project, file, null, processChangedTextOnly);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
protected FutureTask<Boolean> preprocessFile(PsiFile file) throws IncorrectOperationException {
|
||||
final FutureTask<Boolean> reformatTask = myReformatCodeProcessor.preprocessFile(file);
|
||||
final FutureTask<Boolean> optimizeImportsTask = myOptimizeImportsProcessor.preprocessFile(file);
|
||||
protected FutureTask<Boolean> preprocessFile(@NotNull PsiFile file, boolean processChangedTextOnly) throws IncorrectOperationException {
|
||||
final FutureTask<Boolean> reformatTask = myReformatCodeProcessor.preprocessFile(file, processChangedTextOnly);
|
||||
final FutureTask<Boolean> optimizeImportsTask = myOptimizeImportsProcessor.preprocessFile(file, false);
|
||||
return new FutureTask<Boolean>(new Callable<Boolean>() {
|
||||
@Override
|
||||
public Boolean call() throws Exception {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
* Copyright 2000-2011 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.
|
||||
@@ -75,20 +75,22 @@ public class ReformatCodeAction extends AnAction implements DumbAware {
|
||||
else if (areFiles(files)) {
|
||||
final ReadonlyStatusHandler.OperationStatus operationStatus = ReadonlyStatusHandler.getInstance(project).ensureFilesWritable(files);
|
||||
if (!operationStatus.hasReadonlyFiles()) {
|
||||
final ReformatFilesDialog reformatFilesDialog = new ReformatFilesDialog(project);
|
||||
final ReformatFilesDialog reformatFilesDialog = new ReformatFilesDialog(project, files);
|
||||
reformatFilesDialog.show();
|
||||
if (!reformatFilesDialog.isOK()) return;
|
||||
if (reformatFilesDialog.optimizeImports() && !DumbService.getInstance(project).isDumb()) {
|
||||
new ReformatAndOptimizeImportsProcessor(project, convertToPsiFiles(files, project)).run();
|
||||
new ReformatAndOptimizeImportsProcessor(
|
||||
project, convertToPsiFiles(files, project), reformatFilesDialog.isProcessOnlyChangedText()
|
||||
).run();
|
||||
}
|
||||
else {
|
||||
new ReformatCodeProcessor(project, convertToPsiFiles(files, project), null).run();
|
||||
new ReformatCodeProcessor(project, convertToPsiFiles(files, project), null, reformatFilesDialog.isProcessOnlyChangedText()).run();
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
else{
|
||||
else {
|
||||
Project projectContext = PlatformDataKeys.PROJECT_CONTEXT.getData(dataContext);
|
||||
Module moduleContext = LangDataKeys.MODULE_CONTEXT.getData(dataContext);
|
||||
|
||||
@@ -98,26 +100,27 @@ public class ReformatCodeAction extends AnAction implements DumbAware {
|
||||
text = CodeInsightBundle.message("process.scope.module", moduleContext.getModuleFilePath());
|
||||
}
|
||||
else {
|
||||
text = CodeInsightBundle.message("process.scope.project", projectContext.getPresentableUrl());
|
||||
text = CodeInsightBundle.message("process.scope.project", project.getPresentableUrl());
|
||||
}
|
||||
|
||||
LayoutProjectCodeDialog dialog = new LayoutProjectCodeDialog(project, CodeInsightBundle.message("process.reformat.code"), text, true);
|
||||
LayoutProjectCodeDialog dialog
|
||||
= new LayoutProjectCodeDialog(project, moduleContext, CodeInsightBundle.message("process.reformat.code"), text, true);
|
||||
dialog.show();
|
||||
if (!dialog.isOK()) return;
|
||||
if (dialog.isOptimizeImports() && !DumbService.getInstance(project).isDumb()) {
|
||||
if (moduleContext != null) {
|
||||
new ReformatAndOptimizeImportsProcessor(project, moduleContext).run();
|
||||
new ReformatAndOptimizeImportsProcessor(project, moduleContext, dialog.isProcessOnlyChangedText()).run();
|
||||
}
|
||||
else {
|
||||
new ReformatAndOptimizeImportsProcessor(projectContext).run();
|
||||
new ReformatAndOptimizeImportsProcessor(project, dialog.isProcessOnlyChangedText()).run();
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (moduleContext != null) {
|
||||
new ReformatCodeProcessor(project, moduleContext).run();
|
||||
new ReformatCodeProcessor(project, moduleContext, dialog.isProcessOnlyChangedText()).run();
|
||||
}
|
||||
else {
|
||||
new ReformatCodeProcessor(projectContext).run();
|
||||
new ReformatCodeProcessor(project, dialog.isProcessOnlyChangedText()).run();
|
||||
}
|
||||
}
|
||||
return;
|
||||
@@ -140,6 +143,7 @@ public class ReformatCodeAction extends AnAction implements DumbAware {
|
||||
|
||||
boolean optimizeImports = ReformatFilesDialog.isOptmizeImportsOptionOn();
|
||||
boolean processWholeFile = false;
|
||||
boolean processChangedTextOnly = false;
|
||||
if (EditorSettingsExternalizable.getInstance().getOptions().SHOW_REFORMAT_DIALOG || (file == null && dir != null)) {
|
||||
final LayoutCodeDialog dialog = new LayoutCodeDialog(project, CodeInsightBundle.message("process.reformat.code"), file, dir,
|
||||
hasSelection ? Boolean.TRUE : Boolean.FALSE, HELP_ID);
|
||||
@@ -149,12 +153,14 @@ public class ReformatCodeAction extends AnAction implements DumbAware {
|
||||
updateShowDialogSetting(dialog, "\"Reformat Code\" dialog disabled");
|
||||
optimizeImports = dialog.isOptimizeImports();
|
||||
processWholeFile = dialog.isProcessWholeFile();
|
||||
processChangedTextOnly = dialog.isProcessOnlyChangedText();
|
||||
|
||||
if (dialog.isProcessDirectory()){
|
||||
if (optimizeImports) {
|
||||
new ReformatAndOptimizeImportsProcessor(project, dir, dialog.isIncludeSubdirectories()).run();
|
||||
new ReformatAndOptimizeImportsProcessor(project, dir, dialog.isIncludeSubdirectories(), processChangedTextOnly).run();
|
||||
}
|
||||
else {
|
||||
new ReformatCodeProcessor(project, dir, dialog.isIncludeSubdirectories()).run();
|
||||
new ReformatCodeProcessor(project, dir, dialog.isIncludeSubdirectories(), processChangedTextOnly).run();
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -170,14 +176,14 @@ public class ReformatCodeAction extends AnAction implements DumbAware {
|
||||
|
||||
if (optimizeImports && range == null) {
|
||||
if (file != null || dir == null) {
|
||||
new ReformatAndOptimizeImportsProcessor(project, file).run();
|
||||
new ReformatAndOptimizeImportsProcessor(project, file, processChangedTextOnly).run();
|
||||
}
|
||||
else {
|
||||
new ReformatAndOptimizeImportsProcessor(project, dir, true).run();
|
||||
new ReformatAndOptimizeImportsProcessor(project, dir, true, processChangedTextOnly).run();
|
||||
}
|
||||
}
|
||||
else {
|
||||
new ReformatCodeProcessor(project, file, range).run();
|
||||
new ReformatCodeProcessor(project, file, range, processChangedTextOnly).run();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+39
-23
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
* Copyright 2000-2011 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.
|
||||
@@ -27,7 +27,10 @@ import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.codeStyle.CodeStyleManager;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.FutureTask;
|
||||
|
||||
@@ -37,53 +40,66 @@ public class ReformatCodeProcessor extends AbstractLayoutCodeProcessor {
|
||||
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.actions.ReformatCodeProcessor");
|
||||
|
||||
private final TextRange myRange;
|
||||
private final Collection<TextRange> myRanges = new ArrayList<TextRange>();
|
||||
private static final String PROGRESS_TEXT = CodeInsightBundle.message("reformat.progress.common.text");
|
||||
|
||||
public ReformatCodeProcessor(Project project) {
|
||||
super(project, COMMAND_NAME, PROGRESS_TEXT);
|
||||
myRange = null;
|
||||
public ReformatCodeProcessor(Project project, boolean processChangedTextOnly) {
|
||||
super(project, COMMAND_NAME, PROGRESS_TEXT, processChangedTextOnly);
|
||||
}
|
||||
|
||||
public ReformatCodeProcessor(Project project, Module module) {
|
||||
super(project, module, COMMAND_NAME, PROGRESS_TEXT);
|
||||
myRange = null;
|
||||
public ReformatCodeProcessor(Project project, Module module, boolean processChangedTextOnly) {
|
||||
super(project, module, COMMAND_NAME, PROGRESS_TEXT, processChangedTextOnly);
|
||||
}
|
||||
|
||||
public ReformatCodeProcessor(Project project, PsiDirectory directory, boolean includeSubdirs) {
|
||||
super(project, directory, includeSubdirs, PROGRESS_TEXT, COMMAND_NAME);
|
||||
myRange = null;
|
||||
public ReformatCodeProcessor(Project project, PsiDirectory directory, boolean includeSubdirs, boolean processChangedTextOnly) {
|
||||
super(project, directory, includeSubdirs, PROGRESS_TEXT, COMMAND_NAME, processChangedTextOnly);
|
||||
}
|
||||
|
||||
public ReformatCodeProcessor(Project project, PsiFile file, TextRange range) {
|
||||
super(project, file, PROGRESS_TEXT, COMMAND_NAME);
|
||||
myRange = range;
|
||||
public ReformatCodeProcessor(Project project, PsiFile file, @Nullable TextRange range, boolean processChangedTextOnly) {
|
||||
super(project, file, PROGRESS_TEXT, COMMAND_NAME, processChangedTextOnly);
|
||||
if (range != null) {
|
||||
myRanges.add(range);
|
||||
}
|
||||
}
|
||||
|
||||
public ReformatCodeProcessor(Project project, PsiFile[] files, Runnable postRunnable) {
|
||||
this(project, files, COMMAND_NAME, postRunnable);
|
||||
public ReformatCodeProcessor(Project project, PsiFile[] files, Runnable postRunnable, boolean processChangedTextOnly) {
|
||||
this(project, files, COMMAND_NAME, postRunnable, processChangedTextOnly);
|
||||
}
|
||||
|
||||
public ReformatCodeProcessor(Project project, PsiFile[] files, String commandName, Runnable postRunnable) {
|
||||
super(project, files, PROGRESS_TEXT, commandName, postRunnable);
|
||||
myRange = null;
|
||||
|
||||
public ReformatCodeProcessor(Project project,
|
||||
PsiFile[] files,
|
||||
String commandName,
|
||||
Runnable postRunnable,
|
||||
boolean processChangedTextOnly)
|
||||
{
|
||||
super(project, files, PROGRESS_TEXT, commandName, postRunnable, processChangedTextOnly);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
protected FutureTask<Boolean> preprocessFile(final PsiFile file) throws IncorrectOperationException {
|
||||
protected FutureTask<Boolean> preprocessFile(@NotNull final PsiFile file, final boolean processChangedTextOnly)
|
||||
throws IncorrectOperationException
|
||||
{
|
||||
return new FutureTask<Boolean>(new Callable<Boolean>() {
|
||||
@Override
|
||||
public Boolean call() throws Exception {
|
||||
FormattingProgressTask.FORMATTING_CANCELLED_FLAG.set(false);
|
||||
try {
|
||||
TextRange range = myRange == null ? file.getTextRange() : myRange;
|
||||
CodeStyleManager.getInstance(myProject).reformatText(file, range.getStartOffset(), range.getEndOffset());
|
||||
if (myRanges.isEmpty() && processChangedTextOnly) {
|
||||
myRanges.addAll(FormatChangedTextUtil.getChanges(file));
|
||||
}
|
||||
if (myRanges.isEmpty()) {
|
||||
myRanges.add(file.getTextRange());
|
||||
}
|
||||
CodeStyleManager.getInstance(myProject).reformatText(file, myRanges);
|
||||
return !FormattingProgressTask.FORMATTING_CANCELLED_FLAG.get();
|
||||
}
|
||||
catch (IncorrectOperationException e) {
|
||||
LOG.error(e);
|
||||
return false;
|
||||
}
|
||||
finally {
|
||||
myRanges.clear();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1,27 +1,24 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="com.intellij.codeInsight.actions.ReformatFilesDialog">
|
||||
<grid id="59847" binding="myPanel" row-count="1" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||
<grid id="59847" binding="myPanel" layout-manager="GridLayoutManager" row-count="1" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||
<margin top="0" left="4" bottom="0" right="0"/>
|
||||
<constraints>
|
||||
<xy x="30" y="17" width="179" height="94"/>
|
||||
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3"/>
|
||||
<xy x="30" y="17" width="196" height="104"/>
|
||||
</constraints>
|
||||
<properties/>
|
||||
<border type="none"/>
|
||||
<children>
|
||||
<grid id="e83d0" row-count="3" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||
<grid id="e83d0" layout-manager="GridLayoutManager" row-count="4" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||
<margin top="0" left="0" bottom="0" right="0"/>
|
||||
<constraints>
|
||||
<xy x="4" y="0" width="119" height="94"/>
|
||||
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3"/>
|
||||
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties/>
|
||||
<border type="none"/>
|
||||
<children>
|
||||
<component id="cb57" class="javax.swing.JLabel">
|
||||
<constraints>
|
||||
<xy x="0" y="3" width="119" height="14"/>
|
||||
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0"/>
|
||||
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text resource-bundle="messages/CodeInsightBundle" key="dialog.reformat.files.reformat.selected.files.label"/>
|
||||
@@ -29,8 +26,7 @@
|
||||
</component>
|
||||
<component id="4c38e" class="javax.swing.JCheckBox" binding="myOptimizeImports">
|
||||
<constraints>
|
||||
<xy x="0" y="25" width="105" height="22"/>
|
||||
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0"/>
|
||||
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text resource-bundle="messages/CodeInsightBundle" key="dialog.reformat.files.optimize.imports.checkbox"/>
|
||||
@@ -38,16 +34,22 @@
|
||||
</component>
|
||||
<vspacer id="8d758">
|
||||
<constraints>
|
||||
<xy x="54" y="47" width="11" height="47"/>
|
||||
<grid row="2" column="0" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2"/>
|
||||
<grid row="3" column="0" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
</vspacer>
|
||||
<component id="a0a79" class="javax.swing.JCheckBox" binding="myOnlyChangedText">
|
||||
<constraints>
|
||||
<grid row="2" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text resource-bundle="messages/CodeInsightBundle" key="reformat.option.vcs.changed.region"/>
|
||||
</properties>
|
||||
</component>
|
||||
</children>
|
||||
</grid>
|
||||
<hspacer id="c7098">
|
||||
<constraints>
|
||||
<xy x="123" y="41" width="56" height="11"/>
|
||||
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="1" hsize-policy="6" anchor="0" fill="1"/>
|
||||
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="1" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
</hspacer>
|
||||
</children>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
* Copyright 2000-2011 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.
|
||||
@@ -20,17 +20,34 @@ import com.intellij.codeInsight.CodeInsightBundle;
|
||||
import com.intellij.ide.util.PropertiesComponent;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.DialogWrapper;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
public class ReformatFilesDialog extends DialogWrapper {
|
||||
private JPanel myPanel;
|
||||
private JCheckBox myOptimizeImports;
|
||||
private JCheckBox myOnlyChangedText;
|
||||
private final VirtualFile[] myFiles;
|
||||
|
||||
public ReformatFilesDialog(Project project) {
|
||||
public ReformatFilesDialog(@NotNull Project project, @NotNull VirtualFile[] files) {
|
||||
super(project, true);
|
||||
myFiles = files;
|
||||
setTitle(CodeInsightBundle.message("dialog.reformat.files.title"));
|
||||
myOptimizeImports.setSelected(isOptmizeImportsOptionOn());
|
||||
boolean canTargetVcsChanges = false;
|
||||
for (VirtualFile file : files) {
|
||||
if (FormatChangedTextUtil.hasChanges(file, project)) {
|
||||
canTargetVcsChanges = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
myOnlyChangedText.setEnabled(canTargetVcsChanges);
|
||||
myOnlyChangedText.setSelected(
|
||||
canTargetVcsChanges && PropertiesComponent.getInstance().getBoolean(LayoutCodeConstants.PROCESS_CHANGED_TEXT_KEY, false)
|
||||
);
|
||||
myOptimizeImports.setSelected(isOptmizeImportsOptionOn());
|
||||
init();
|
||||
}
|
||||
|
||||
@@ -42,13 +59,19 @@ public class ReformatFilesDialog extends DialogWrapper {
|
||||
return myOptimizeImports.isSelected();
|
||||
}
|
||||
|
||||
public boolean isProcessOnlyChangedText() {
|
||||
return myOnlyChangedText.isEnabled() && myOnlyChangedText.isSelected();
|
||||
}
|
||||
|
||||
protected void doOKAction() {
|
||||
PropertiesComponent.getInstance().setValue(LayoutCodeDialog.OPTIMIZE_IMPORTS_KEY, Boolean.toString(myOptimizeImports.isSelected()));
|
||||
super.doOKAction();
|
||||
PropertiesComponent.getInstance().setValue(LayoutCodeConstants.OPTIMIZE_IMPORTS_KEY, Boolean.toString(myOptimizeImports.isSelected()));
|
||||
PropertiesComponent.getInstance().setValue(LayoutCodeConstants.PROCESS_CHANGED_TEXT_KEY,
|
||||
Boolean.toString(myOnlyChangedText.isSelected()));
|
||||
}
|
||||
|
||||
static boolean isOptmizeImportsOptionOn() {
|
||||
return Boolean.valueOf(PropertiesComponent.getInstance().getValue(LayoutCodeDialog.OPTIMIZE_IMPORTS_KEY));
|
||||
return PropertiesComponent.getInstance().getBoolean(LayoutCodeConstants.OPTIMIZE_IMPORTS_KEY, false);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright 2000-2011 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.codeInsight.completion;
|
||||
|
||||
import com.intellij.openapi.util.Ref;
|
||||
import com.intellij.util.Consumer;
|
||||
|
||||
/**
|
||||
* @author Dmitry Avdeev
|
||||
* Date: 12/19/11
|
||||
*/
|
||||
public abstract class NoVariantsDelegator extends CompletionContributor {
|
||||
|
||||
@Override
|
||||
public void fillCompletionVariants(final CompletionParameters parameters, final CompletionResultSet result) {
|
||||
final Ref<Boolean> empty = Ref.create(true);
|
||||
Consumer<CompletionResult> passResult = new Consumer<CompletionResult>() {
|
||||
public void consume(final CompletionResult lookupElement) {
|
||||
empty.set(false);
|
||||
result.passResult(lookupElement);
|
||||
}
|
||||
};
|
||||
result.runRemainingContributors(parameters, passResult);
|
||||
|
||||
if (!empty.get() && parameters.getInvocationCount() == 0) {
|
||||
result.restartCompletionWhenNothingMatches();
|
||||
}
|
||||
|
||||
if (empty.get()) {
|
||||
delegate(parameters, result, passResult);
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract void delegate(CompletionParameters parameters, CompletionResultSet result, Consumer<CompletionResult> passResult);
|
||||
}
|
||||
+11
-4
@@ -31,6 +31,7 @@ import com.intellij.ide.PowerSaveMode;
|
||||
import com.intellij.lang.annotation.HighlightSeverity;
|
||||
import com.intellij.openapi.application.Application;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.application.ModalityState;
|
||||
import com.intellij.openapi.components.ProjectComponent;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
@@ -695,10 +696,16 @@ public class DaemonCodeAnalyzerImpl extends DaemonCodeAnalyzer implements JDOMEx
|
||||
// we'll restart when write action finish
|
||||
return;
|
||||
}
|
||||
if (PsiDocumentManager.getInstance(myProject).hasUncommitedDocuments()) {
|
||||
((PsiDocumentManagerImpl)PsiDocumentManager.getInstance(myProject)).cancelAndRunWhenAllCommitted(
|
||||
"restart daemon when all committed", this);
|
||||
return;
|
||||
PsiDocumentManager documentManager = PsiDocumentManager.getInstance(myProject);
|
||||
if (documentManager.hasUncommitedDocuments()) {
|
||||
if (ModalityState.current() == ModalityState.NON_MODAL) {
|
||||
((PsiDocumentManagerImpl)documentManager).cancelAndRunWhenAllCommitted("restart daemon when all committed", this);
|
||||
return;
|
||||
}
|
||||
else {
|
||||
// when modal dialog is open, DocumentCommitThread is not able to commit in background, so force commit here
|
||||
documentManager.commitAllDocuments();
|
||||
}
|
||||
}
|
||||
|
||||
Map<FileEditor, HighlightingPass[]> passes = new THashMap<FileEditor, HighlightingPass[]>(activeEditors.size());
|
||||
|
||||
+3
-1
@@ -297,7 +297,8 @@ public class DocumentationManager {
|
||||
}
|
||||
}, keyboardShortcut != null ? keyboardShortcut.getFirstKeyStroke() : null)); // Null keyStroke is ok here
|
||||
|
||||
final JBPopup hint = JBPopupFactory.getInstance().createComponentPopupBuilder(component, component)
|
||||
boolean hasLookup = LookupManager.getActiveLookup(myEditor) != null;
|
||||
final JBPopup hint = JBPopupFactory.getInstance().createComponentPopupBuilder(component, component)
|
||||
.setRequestFocusCondition(project, NotLookupOrSearchCondition.INSTANCE)
|
||||
.setProject(project)
|
||||
.addListener(updateProcessor)
|
||||
@@ -308,6 +309,7 @@ public class DocumentationManager {
|
||||
.setResizable(true)
|
||||
.setMovable(true)
|
||||
.setRequestFocus(requestFocus)
|
||||
.setCancelOnClickOutside(!hasLookup) // otherwise selecting lookup items by mouse would close the doc
|
||||
.setTitle(getTitle(element, false))
|
||||
.setCouldPin(pinCallback)
|
||||
.setCancelCallback(new Computable<Boolean>() {
|
||||
|
||||
+4
-1
@@ -29,6 +29,7 @@ import com.intellij.openapi.command.WriteCommandAction;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.editor.ex.util.EditorUtil;
|
||||
import com.intellij.openapi.fileEditor.FileDocumentManager;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.PsiDocumentManager;
|
||||
import com.intellij.psi.PsiFile;
|
||||
@@ -40,7 +41,9 @@ import java.util.Map;
|
||||
|
||||
public class ListTemplatesHandler implements CodeInsightActionHandler {
|
||||
public void invoke(@NotNull final Project project, @NotNull final Editor editor, @NotNull PsiFile file) {
|
||||
if (!file.isWritable()) return;
|
||||
if (!FileDocumentManager.getInstance().requestWriting(editor.getDocument(), project)) {
|
||||
return;
|
||||
}
|
||||
EditorUtil.fillVirtualSpaceUntilCaret(editor);
|
||||
|
||||
PsiDocumentManager.getInstance(project).commitDocument(editor.getDocument());
|
||||
|
||||
@@ -22,6 +22,7 @@ import com.intellij.ide.projectView.impl.ProjectRootsUtil;
|
||||
import com.intellij.ide.structureView.StructureView;
|
||||
import com.intellij.ide.structureView.StructureViewBuilder;
|
||||
import com.intellij.ide.structureView.StructureViewWrapper;
|
||||
import com.intellij.ide.structureView.impl.StructureViewComposite;
|
||||
import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.actionSystem.*;
|
||||
import com.intellij.openapi.application.ModalityState;
|
||||
@@ -43,6 +44,9 @@ import com.intellij.openapi.wm.ToolWindowId;
|
||||
import com.intellij.openapi.wm.ToolWindowManager;
|
||||
import com.intellij.openapi.wm.ex.IdeFocusTraversalPolicy;
|
||||
import com.intellij.psi.PsiDocumentManager;
|
||||
import com.intellij.ui.content.Content;
|
||||
import com.intellij.ui.content.ContentFactory;
|
||||
import com.intellij.ui.content.ContentManager;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
import com.intellij.util.ui.update.MergingUpdateQueue;
|
||||
import com.intellij.util.ui.update.Update;
|
||||
@@ -59,13 +63,14 @@ import java.awt.event.HierarchyListener;
|
||||
*/
|
||||
public class StructureViewWrapperImpl implements StructureViewWrapper, Disposable {
|
||||
private final Project myProject;
|
||||
private final ToolWindow myToolWindow;
|
||||
|
||||
private VirtualFile myFile;
|
||||
|
||||
private StructureView myStructureView;
|
||||
private ModuleStructureComponent myModuleStructureComponent;
|
||||
|
||||
private final JPanel myPanel;
|
||||
private JPanel[] myPanels = new JPanel[0];
|
||||
private final MergingUpdateQueue myUpdateQueue;
|
||||
private final String myKey = new String("DATA_SELECTOR");
|
||||
|
||||
@@ -75,17 +80,16 @@ public class StructureViewWrapperImpl implements StructureViewWrapper, Disposabl
|
||||
|
||||
private Runnable myPendingSelection;
|
||||
|
||||
public StructureViewWrapperImpl(Project project) {
|
||||
public StructureViewWrapperImpl(Project project, ToolWindow toolWindow) {
|
||||
myProject = project;
|
||||
myPanel = new ContentPanel();
|
||||
myPanel.setBackground(UIUtil.getTreeTextBackground());
|
||||
|
||||
myUpdateQueue = new MergingUpdateQueue("StructureView", Registry.intValue("structureView.coalesceTime"), false, myPanel, this, myPanel, true);
|
||||
myToolWindow = toolWindow;
|
||||
|
||||
myUpdateQueue = new MergingUpdateQueue("StructureView", Registry.intValue("structureView.coalesceTime"), false, myToolWindow.getComponent(), this, myToolWindow.getComponent(), true);
|
||||
myUpdateQueue.setRestartTimerOnAdd(true);
|
||||
|
||||
ActionManager.getInstance().addTimerListener(500, new TimerListener() {
|
||||
public ModalityState getModalityState() {
|
||||
return ModalityState.stateForComponent(myPanel);
|
||||
return ModalityState.stateForComponent(myToolWindow.getComponent());
|
||||
}
|
||||
|
||||
public void run() {
|
||||
@@ -93,20 +97,21 @@ public class StructureViewWrapperImpl implements StructureViewWrapper, Disposabl
|
||||
}
|
||||
});
|
||||
|
||||
getComponent().addHierarchyListener(new HierarchyListener() {
|
||||
myToolWindow.getComponent().addHierarchyListener(new HierarchyListener() {
|
||||
public void hierarchyChanged(HierarchyEvent e) {
|
||||
if ((e.getChangeFlags() & HierarchyEvent.DISPLAYABILITY_CHANGED) != 0) {
|
||||
scheduleRebuild();
|
||||
}
|
||||
}
|
||||
});
|
||||
Disposer.register(myToolWindow.getContentManager(), this);
|
||||
}
|
||||
|
||||
private void checkUpdate() {
|
||||
if (myProject.isDisposed()) return;
|
||||
|
||||
final Component owner = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner();
|
||||
if (SwingUtilities.isDescendingFrom(myPanel, owner) || JBPopupFactory.getInstance().isPopupActive()) return;
|
||||
if (SwingUtilities.isDescendingFrom(myToolWindow.getComponent(), owner) || JBPopupFactory.getInstance().isPopupActive()) return;
|
||||
|
||||
final DataContext dataContext = DataManager.getInstance().getDataContext(owner);
|
||||
if (dataContext.getData(myKey) == this) return;
|
||||
@@ -133,10 +138,6 @@ public class StructureViewWrapperImpl implements StructureViewWrapper, Disposabl
|
||||
// StructureView interface implementation
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
public JComponent getComponent() {
|
||||
return myPanel;
|
||||
}
|
||||
|
||||
public void dispose() {
|
||||
rebuild();
|
||||
}
|
||||
@@ -202,8 +203,8 @@ public class StructureViewWrapperImpl implements StructureViewWrapper, Disposabl
|
||||
myModuleStructureComponent = null;
|
||||
}
|
||||
|
||||
myPanel.removeAll();
|
||||
|
||||
final ContentManager contentManager = myToolWindow.getContentManager();
|
||||
contentManager.removeAllContents(true);
|
||||
if (!isStructureViewShowing()) {
|
||||
return;
|
||||
}
|
||||
@@ -216,19 +217,16 @@ public class StructureViewWrapperImpl implements StructureViewWrapper, Disposabl
|
||||
}
|
||||
}
|
||||
|
||||
String[] names = new String[] {""};
|
||||
JComponent focusedComponent = null;
|
||||
if (file != null && file.isValid()) {
|
||||
if (file.isDirectory()) {
|
||||
if (ProjectRootsUtil.isModuleContentRoot(file, myProject)) {
|
||||
Module module = ModuleUtil.findModuleForFile(file, myProject);
|
||||
if (module != null) {
|
||||
myModuleStructureComponent = new ModuleStructureComponent(module);
|
||||
myPanel.add(myModuleStructureComponent, BorderLayout.CENTER);
|
||||
if (hadFocus) {
|
||||
JComponent focusedComponent = IdeFocusTraversalPolicy.getPreferredFocusedComponent(myModuleStructureComponent);
|
||||
if (focusedComponent != null) {
|
||||
IdeFocusManager.getInstance(myProject).requestFocus(focusedComponent, true);
|
||||
}
|
||||
}
|
||||
focusedComponent = hadFocus ? IdeFocusTraversalPolicy.getPreferredFocusedComponent(myModuleStructureComponent) : null;
|
||||
createSinglePanel(myModuleStructureComponent.getComponent());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -246,13 +244,22 @@ public class StructureViewWrapperImpl implements StructureViewWrapper, Disposabl
|
||||
if (myStructureView instanceof StructureView.Scrollable) {
|
||||
((StructureView.Scrollable)myStructureView).setReferenceSizeWhileInitializing(referenceSize);
|
||||
}
|
||||
myPanel.add(myStructureView.getComponent(), BorderLayout.CENTER);
|
||||
if (hadFocus) {
|
||||
JComponent focusedComponent = IdeFocusTraversalPolicy.getPreferredFocusedComponent(myStructureView.getComponent());
|
||||
if (focusedComponent != null) {
|
||||
IdeFocusManager.getInstance(myProject).requestFocus(focusedComponent, true);
|
||||
|
||||
final StructureViewComposite.StructureViewDescriptor[] views;
|
||||
|
||||
if (myStructureView instanceof StructureViewComposite) {
|
||||
final StructureViewComposite composite = (StructureViewComposite)myStructureView;
|
||||
views = composite.getStructureViews();
|
||||
myPanels = new JPanel[views.length];
|
||||
names = new String[views.length];
|
||||
for (int i = 0; i < myPanels.length; i++) {
|
||||
myPanels[i] = createContentPanel(views[i].structureView.getComponent());
|
||||
names[i] = views[i].title;
|
||||
}
|
||||
} else {
|
||||
createSinglePanel(myStructureView.getComponent());
|
||||
}
|
||||
focusedComponent = hadFocus ? IdeFocusTraversalPolicy.getPreferredFocusedComponent(myStructureView.getComponent()) : null;
|
||||
myStructureView.restoreState();
|
||||
myStructureView.centerSelectedRow();
|
||||
}
|
||||
@@ -264,11 +271,19 @@ public class StructureViewWrapperImpl implements StructureViewWrapper, Disposabl
|
||||
}
|
||||
|
||||
if (myModuleStructureComponent == null && myStructureView == null) {
|
||||
myPanel.add(new JLabel(IdeBundle.message("message.nothing.to.show.in.structure.view"), SwingConstants.CENTER), BorderLayout.CENTER);
|
||||
createSinglePanel(new JLabel(IdeBundle.message("message.nothing.to.show.in.structure.view"), SwingConstants.CENTER));
|
||||
}
|
||||
|
||||
myPanel.validate();
|
||||
myPanel.repaint();
|
||||
for (int i = 0; i < myPanels.length; i++) {
|
||||
final Content content = ContentFactory.SERVICE.getInstance().createContent(myPanels[i], names[i], false);
|
||||
contentManager.addContent(content);
|
||||
if (i == 0 && myStructureView != null) {
|
||||
Disposer.register(content, myStructureView);
|
||||
}
|
||||
}
|
||||
if (hadFocus && focusedComponent != null) {
|
||||
IdeFocusManager.getInstance(myProject).requestFocus(focusedComponent, true);
|
||||
}
|
||||
|
||||
if (myPendingSelection != null) {
|
||||
Runnable selection = myPendingSelection;
|
||||
@@ -277,6 +292,18 @@ public class StructureViewWrapperImpl implements StructureViewWrapper, Disposabl
|
||||
}
|
||||
}
|
||||
|
||||
private void createSinglePanel(final JComponent component) {
|
||||
myPanels = new JPanel[1];
|
||||
myPanels[0] = createContentPanel(component);
|
||||
}
|
||||
|
||||
private ContentPanel createContentPanel(JComponent component) {
|
||||
final ContentPanel panel = new ContentPanel();
|
||||
panel.setBackground(UIUtil.getTreeTextBackground());
|
||||
panel.add(component, BorderLayout.CENTER);
|
||||
return panel;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private FileEditor createTempFileEditor(VirtualFile file) {
|
||||
FileEditorProviderManager editorProviderManager = FileEditorProviderManager.getInstance();
|
||||
|
||||
+1
-17
@@ -20,12 +20,9 @@ import com.intellij.ide.structureView.StructureView;
|
||||
import com.intellij.ide.structureView.StructureViewModel;
|
||||
import com.intellij.openapi.fileEditor.FileEditor;
|
||||
import com.intellij.openapi.util.Disposer;
|
||||
import com.intellij.ui.TabbedPaneWrapper;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.event.ChangeEvent;
|
||||
import javax.swing.event.ChangeListener;
|
||||
|
||||
/**
|
||||
* @author cdr
|
||||
@@ -33,8 +30,6 @@ import javax.swing.event.ChangeListener;
|
||||
public class StructureViewComposite implements StructureView {
|
||||
@NotNull private final StructureViewDescriptor[] myStructureViews;
|
||||
@NotNull private StructureViewDescriptor mySelectedViewDescriptor;
|
||||
@NotNull private final TabbedPaneWrapper myTabbedPaneWrapper;
|
||||
|
||||
public static class StructureViewDescriptor {
|
||||
public final String title;
|
||||
public final StructureView structureView;
|
||||
@@ -53,17 +48,6 @@ public class StructureViewComposite implements StructureView {
|
||||
Disposer.register(this, descriptor.structureView);
|
||||
}
|
||||
mySelectedViewDescriptor = views[0];
|
||||
myTabbedPaneWrapper = new TabbedPaneWrapper(this);
|
||||
for (StructureViewDescriptor descriptor : views) {
|
||||
myTabbedPaneWrapper.addTab(descriptor.title, descriptor.icon, descriptor.structureView.getComponent(), null);
|
||||
}
|
||||
myTabbedPaneWrapper.setSelectedIndex(0);
|
||||
myTabbedPaneWrapper.addChangeListener(new ChangeListener() {
|
||||
public void stateChanged(ChangeEvent e) {
|
||||
int index = myTabbedPaneWrapper.getSelectedIndex();
|
||||
mySelectedViewDescriptor = myStructureViews[index];
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public StructureView getSelectedStructureView() {
|
||||
@@ -84,7 +68,7 @@ public class StructureViewComposite implements StructureView {
|
||||
}
|
||||
|
||||
public JComponent getComponent() {
|
||||
return myTabbedPaneWrapper.getComponent();
|
||||
return mySelectedViewDescriptor.structureView.getComponent();
|
||||
}
|
||||
|
||||
public void dispose() {
|
||||
|
||||
+1
-8
@@ -25,14 +25,11 @@ import com.intellij.openapi.components.Storage;
|
||||
import com.intellij.openapi.extensions.Extensions;
|
||||
import com.intellij.openapi.fileEditor.FileEditor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Disposer;
|
||||
import com.intellij.openapi.util.MultiValuesMap;
|
||||
import com.intellij.openapi.util.NotNullLazyValue;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.wm.ToolWindow;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.ui.content.Content;
|
||||
import com.intellij.ui.content.ContentFactory;
|
||||
import com.intellij.util.ReflectionCache;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@@ -96,11 +93,7 @@ public final class StructureViewFactoryImpl extends StructureViewFactoryEx imple
|
||||
}
|
||||
|
||||
public void initToolWindow(ToolWindow toolWindow) {
|
||||
myStructureViewWrapperImpl = new StructureViewWrapperImpl(myProject);
|
||||
final Content content = ContentFactory.SERVICE.getInstance().createContent(myStructureViewWrapperImpl.getComponent(), "", false);
|
||||
Disposer.register(content, myStructureViewWrapperImpl);
|
||||
toolWindow.getContentManager().addContent(content);
|
||||
|
||||
myStructureViewWrapperImpl = new StructureViewWrapperImpl(myProject, toolWindow);
|
||||
if (myRunWhenInitialized != null) {
|
||||
myRunWhenInitialized.run();
|
||||
myRunWhenInitialized = null;
|
||||
|
||||
@@ -18,13 +18,15 @@ package com.intellij.injected.editor;
|
||||
|
||||
import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.editor.*;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.editor.EditorFactory;
|
||||
import com.intellij.openapi.editor.LogicalPosition;
|
||||
import com.intellij.openapi.editor.RangeMarker;
|
||||
import com.intellij.openapi.editor.event.DocumentListener;
|
||||
import com.intellij.openapi.editor.ex.DocumentEx;
|
||||
import com.intellij.openapi.editor.ex.EditReadOnlyListener;
|
||||
import com.intellij.openapi.editor.ex.LineIterator;
|
||||
import com.intellij.openapi.editor.ex.RangeMarkerEx;
|
||||
import com.intellij.openapi.editor.impl.DocumentImpl;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.util.ProperTextRange;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
@@ -46,21 +48,24 @@ import java.util.List;
|
||||
* @author Alexey
|
||||
*/
|
||||
public class DocumentWindowImpl extends UserDataHolderBase implements Disposable, DocumentWindow, DocumentEx {
|
||||
private static final Logger LOG = Logger.getInstance("com.intellij.openapi.editor.impl.injected.DocumentRangee");
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.injected.editor.DocumentWindowImpl");
|
||||
private final DocumentEx myDelegate;
|
||||
private final boolean myOneLine;
|
||||
private Place myShreds;
|
||||
private Place myShreds; // guarded by myLock
|
||||
private final int myPrefixLineCount;
|
||||
private final int mySuffixLineCount;
|
||||
private final Object myLock = new Object();
|
||||
|
||||
private CachedText myCachedText = null;
|
||||
|
||||
public DocumentWindowImpl(@NotNull DocumentEx delegate, boolean oneLine, Place shreds) {
|
||||
myDelegate = delegate;
|
||||
myOneLine = oneLine;
|
||||
myShreds = shreds;
|
||||
myPrefixLineCount = Math.max(1, 1 + StringUtil.countNewLines(myShreds.get(0).prefix));
|
||||
mySuffixLineCount = Math.max(1, 1 + StringUtil.countNewLines(myShreds.get(shreds.size()- 1).suffix));
|
||||
synchronized (myLock) {
|
||||
myShreds = shreds;
|
||||
}
|
||||
myPrefixLineCount = Math.max(1, 1 + StringUtil.countNewLines(shreds.get(0).prefix));
|
||||
mySuffixLineCount = Math.max(1, 1 + StringUtil.countNewLines(shreds.get(shreds.size()- 1).suffix));
|
||||
}
|
||||
|
||||
@Nullable("null means we were unable to calculate")
|
||||
@@ -70,20 +75,22 @@ public class DocumentWindowImpl extends UserDataHolderBase implements Disposable
|
||||
int iLineStartOffset = hostToInjected(hLineStartOffset);
|
||||
int iLine = getLineNumber(iLineStartOffset);
|
||||
|
||||
for (int i = myShreds.size() - 1; i >= 0; i--) {
|
||||
PsiLanguageInjectionHost.Shred shred = myShreds.get(i);
|
||||
if (!shred.isValid()) continue;
|
||||
int hShredEndOffset = shred.getHostRangeMarker().getEndOffset();
|
||||
int hShredStartOffset = shred.getHostRangeMarker().getStartOffset();
|
||||
synchronized (myLock) {
|
||||
for (int i = myShreds.size() - 1; i >= 0; i--) {
|
||||
PsiLanguageInjectionHost.Shred shred = myShreds.get(i);
|
||||
if (!shred.isValid()) continue;
|
||||
int hShredEndOffset = shred.getHostRangeMarker().getEndOffset();
|
||||
int hShredStartOffset = shred.getHostRangeMarker().getStartOffset();
|
||||
|
||||
int hShredStartLine = myDelegate.getLineNumber(hShredStartOffset);
|
||||
int hShredEndLine = myDelegate.getLineNumber(hShredEndOffset);
|
||||
int hShredStartLine = myDelegate.getLineNumber(hShredStartOffset);
|
||||
int hShredEndLine = myDelegate.getLineNumber(hShredEndOffset);
|
||||
|
||||
if (hShredStartLine <= hPos.line && hPos.line <= hShredEndLine) {
|
||||
int hColumnOfShredEnd = hShredEndOffset - hLineStartOffset;
|
||||
int iColumnOfShredEnd = hostToInjected(hShredEndOffset) - iLineStartOffset;
|
||||
int iColumn = iColumnOfShredEnd + hPos.column - hColumnOfShredEnd;
|
||||
return new LogicalPosition(iLine, iColumn);
|
||||
if (hShredStartLine <= hPos.line && hPos.line <= hShredEndLine) {
|
||||
int hColumnOfShredEnd = hShredEndOffset - hLineStartOffset;
|
||||
int iColumnOfShredEnd = hostToInjected(hShredEndOffset) - iLineStartOffset;
|
||||
int iColumn = iColumnOfShredEnd + hPos.column - hColumnOfShredEnd;
|
||||
return new LogicalPosition(iLine, iColumn);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -117,13 +124,29 @@ public class DocumentWindowImpl extends UserDataHolderBase implements Disposable
|
||||
|
||||
@Override
|
||||
public int getLineStartOffset(int line) {
|
||||
//int oldso = oldso(line);
|
||||
int newso = newStartOffset(line);
|
||||
//if (newso != oldso) {
|
||||
// int i = 0;
|
||||
//}
|
||||
LOG.assertTrue(line >= 0, line);
|
||||
if (line == 0) return 0;
|
||||
String hostText = myDelegate.getText();
|
||||
|
||||
return newso;
|
||||
int[] pos = new int[2]; // pos[0] = curLine; pos[1] == offset;
|
||||
synchronized (myLock) {
|
||||
for (PsiLanguageInjectionHost.Shred shred : myShreds) {
|
||||
RangeMarker hostRange = shred.getHostRangeMarker();
|
||||
if (!hostRange.isValid()) continue;
|
||||
|
||||
int found = countNewLinesIn(shred.prefix, pos, line);
|
||||
if (found != -1) return found;
|
||||
|
||||
String text = hostText.substring(hostRange.getStartOffset(), hostRange.getEndOffset());
|
||||
found = countNewLinesIn(text, pos, line);
|
||||
if (found != -1) return found;
|
||||
|
||||
found = countNewLinesIn(shred.suffix, pos, line);
|
||||
if (found != -1) return found;
|
||||
}
|
||||
}
|
||||
|
||||
return pos[1];
|
||||
}
|
||||
|
||||
// returns startOffset found, or -1 if need to continue searching
|
||||
@@ -140,35 +163,6 @@ public class DocumentWindowImpl extends UserDataHolderBase implements Disposable
|
||||
return -1;
|
||||
}
|
||||
|
||||
private int newStartOffset(int line) {
|
||||
LOG.assertTrue(line >= 0, line);
|
||||
if (line == 0) return 0;
|
||||
String hostText = myDelegate.getText();
|
||||
|
||||
int[] pos = new int[2]; // pos[0] = curLine; pos[1] == offset;
|
||||
for (PsiLanguageInjectionHost.Shred shred : myShreds) {
|
||||
RangeMarker hostRange = shred.getHostRangeMarker();
|
||||
if (!hostRange.isValid()) continue;
|
||||
|
||||
int found = countNewLinesIn(shred.prefix, pos, line);
|
||||
if (found != -1) return found;
|
||||
|
||||
String text = hostText.substring(hostRange.getStartOffset(), hostRange.getEndOffset());
|
||||
found = countNewLinesIn(text, pos, line);
|
||||
if (found != -1) return found;
|
||||
|
||||
found = countNewLinesIn(shred.suffix, pos, line);
|
||||
if (found != -1) return found;
|
||||
}
|
||||
|
||||
return pos[1];
|
||||
}
|
||||
|
||||
private int oldso(int line) {
|
||||
assert line >= 0 : line;
|
||||
return new DocumentImpl(getText()).getLineStartOffset(line);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLineEndOffset(int line) {
|
||||
LOG.assertTrue(line >= 0, line);
|
||||
@@ -191,12 +185,14 @@ public class DocumentWindowImpl extends UserDataHolderBase implements Disposable
|
||||
private String calcText() {
|
||||
StringBuilder text = new StringBuilder();
|
||||
CharSequence hostText = myDelegate.getCharsSequence();
|
||||
for (PsiLanguageInjectionHost.Shred shred : myShreds) {
|
||||
RangeMarker hostRange = shred.getHostRangeMarker();
|
||||
if (hostRange.isValid()) {
|
||||
text.append(shred.prefix);
|
||||
text.append(hostText, hostRange.getStartOffset(), hostRange.getEndOffset());
|
||||
text.append(shred.suffix);
|
||||
synchronized (myLock) {
|
||||
for (PsiLanguageInjectionHost.Shred shred : myShreds) {
|
||||
RangeMarker hostRange = shred.getHostRangeMarker();
|
||||
if (hostRange.isValid()) {
|
||||
text.append(shred.prefix);
|
||||
text.append(hostText, hostRange.getStartOffset(), hostRange.getEndOffset());
|
||||
text.append(shred.suffix);
|
||||
}
|
||||
}
|
||||
}
|
||||
return text.toString();
|
||||
@@ -223,11 +219,13 @@ public class DocumentWindowImpl extends UserDataHolderBase implements Disposable
|
||||
@Override
|
||||
public int getTextLength() {
|
||||
int length = 0;
|
||||
for (PsiLanguageInjectionHost.Shred shred : myShreds) {
|
||||
RangeMarker hostRange = shred.getHostRangeMarker();
|
||||
length += shred.prefix.length();
|
||||
length += hostRange.getEndOffset() - hostRange.getStartOffset();
|
||||
length += shred.suffix.length();
|
||||
synchronized (myLock) {
|
||||
for (PsiLanguageInjectionHost.Shred shred : myShreds) {
|
||||
RangeMarker hostRange = shred.getHostRangeMarker();
|
||||
length += shred.prefix.length();
|
||||
length += hostRange.getEndOffset() - hostRange.getStartOffset();
|
||||
length += shred.suffix.length();
|
||||
}
|
||||
}
|
||||
return length;
|
||||
}
|
||||
@@ -236,32 +234,34 @@ public class DocumentWindowImpl extends UserDataHolderBase implements Disposable
|
||||
public int getLineNumber(int offset) {
|
||||
int lineNumber = 0;
|
||||
String hostText = myDelegate.getText();
|
||||
for (PsiLanguageInjectionHost.Shred shred : myShreds) {
|
||||
String prefix = shred.prefix;
|
||||
String suffix = shred.suffix;
|
||||
lineNumber += StringUtil.getLineBreakCount(prefix.substring(0, Math.min(offset, prefix.length())));
|
||||
if (offset < prefix.length()) {
|
||||
return lineNumber;
|
||||
synchronized (myLock) {
|
||||
for (PsiLanguageInjectionHost.Shred shred : myShreds) {
|
||||
String prefix = shred.prefix;
|
||||
String suffix = shred.suffix;
|
||||
lineNumber += StringUtil.getLineBreakCount(prefix.substring(0, Math.min(offset, prefix.length())));
|
||||
if (offset < prefix.length()) {
|
||||
return lineNumber;
|
||||
}
|
||||
offset -= prefix.length();
|
||||
|
||||
RangeMarker currentRange = shred.getHostRangeMarker();
|
||||
if (!currentRange.isValid()) continue;
|
||||
int rangeLength = currentRange.getEndOffset() - currentRange.getStartOffset();
|
||||
String rangeText = hostText.substring(currentRange.getStartOffset(), currentRange.getEndOffset());
|
||||
|
||||
lineNumber += StringUtil.getLineBreakCount(rangeText.substring(0, Math.min(offset, rangeLength)));
|
||||
if (offset < rangeLength) {
|
||||
return lineNumber;
|
||||
}
|
||||
offset -= rangeLength;
|
||||
|
||||
lineNumber += StringUtil.getLineBreakCount(suffix.substring(0, Math.min(offset, suffix.length())));
|
||||
if (offset < suffix.length()) {
|
||||
return lineNumber;
|
||||
}
|
||||
|
||||
offset -= suffix.length();
|
||||
}
|
||||
offset -= prefix.length();
|
||||
|
||||
RangeMarker currentRange = shred.getHostRangeMarker();
|
||||
if (!currentRange.isValid()) continue;
|
||||
int rangeLength = currentRange.getEndOffset() - currentRange.getStartOffset();
|
||||
String rangeText = hostText.substring(currentRange.getStartOffset(), currentRange.getEndOffset());
|
||||
|
||||
lineNumber += StringUtil.getLineBreakCount(rangeText.substring(0, Math.min(offset, rangeLength)));
|
||||
if (offset < rangeLength) {
|
||||
return lineNumber;
|
||||
}
|
||||
offset -= rangeLength;
|
||||
|
||||
lineNumber += StringUtil.getLineBreakCount(suffix.substring(0, Math.min(offset, suffix.length())));
|
||||
if (offset < suffix.length()) {
|
||||
return lineNumber;
|
||||
}
|
||||
|
||||
offset -= suffix.length();
|
||||
}
|
||||
lineNumber = getLineCount() - 1;
|
||||
return lineNumber < 0 ? 0 : lineNumber;
|
||||
@@ -269,18 +269,22 @@ public class DocumentWindowImpl extends UserDataHolderBase implements Disposable
|
||||
|
||||
@Override
|
||||
public TextRange getHostRange(int hostOffset) {
|
||||
for (PsiLanguageInjectionHost.Shred shred : myShreds) {
|
||||
RangeMarker currentRange = shred.getHostRangeMarker();
|
||||
TextRange textRange = ProperTextRange.create(currentRange);
|
||||
if (textRange.grown(1).contains(hostOffset)) return textRange;
|
||||
}
|
||||
synchronized (myLock) {
|
||||
for (PsiLanguageInjectionHost.Shred shred : myShreds) {
|
||||
RangeMarker currentRange = shred.getHostRangeMarker();
|
||||
TextRange textRange = ProperTextRange.create(currentRange);
|
||||
if (textRange.grown(1).contains(hostOffset)) return textRange;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void insertString(final int offset, @NotNull CharSequence s) {
|
||||
LOG.assertTrue(offset >= myShreds.get(0).prefix.length(), myShreds.get(0).prefix);
|
||||
LOG.assertTrue(offset <= getTextLength() - myShreds.get(myShreds.size() - 1).suffix.length(), myShreds.get(myShreds.size() - 1).suffix);
|
||||
synchronized (myLock) {
|
||||
LOG.assertTrue(offset >= myShreds.get(0).prefix.length(), myShreds.get(0).prefix);
|
||||
LOG.assertTrue(offset <= getTextLength() - myShreds.get(myShreds.size() - 1).suffix.length(), myShreds.get(myShreds.size() - 1).suffix);
|
||||
}
|
||||
if (isOneLine()) {
|
||||
s = StringUtil.replace(s.toString(), "\n", "");
|
||||
}
|
||||
@@ -292,25 +296,28 @@ public class DocumentWindowImpl extends UserDataHolderBase implements Disposable
|
||||
assert intersectWithEditable(new TextRange(startOffset, startOffset)) != null;
|
||||
assert intersectWithEditable(new TextRange(endOffset, endOffset)) != null;
|
||||
|
||||
List<TextRange> hostRangesToDelete = new ArrayList<TextRange>(myShreds.size());
|
||||
List<TextRange> hostRangesToDelete;
|
||||
synchronized (myLock) {
|
||||
hostRangesToDelete = new ArrayList<TextRange>(myShreds.size());
|
||||
|
||||
int offset = startOffset;
|
||||
int curRangeStart = 0;
|
||||
for (PsiLanguageInjectionHost.Shred shred : myShreds) {
|
||||
curRangeStart += shred.prefix.length();
|
||||
if (offset < curRangeStart) offset = curRangeStart;
|
||||
if (offset >= endOffset) break;
|
||||
RangeMarker hostRange = shred.getHostRangeMarker();
|
||||
if (!hostRange.isValid()) continue;
|
||||
int hostRangeLength = hostRange.getEndOffset() - hostRange.getStartOffset();
|
||||
TextRange range = TextRange.from(curRangeStart, hostRangeLength);
|
||||
if (range.contains(offset)) {
|
||||
TextRange rangeToDelete = new TextRange(offset, Math.min(range.getEndOffset(), endOffset));
|
||||
hostRangesToDelete.add(rangeToDelete.shiftRight(hostRange.getStartOffset() - curRangeStart));
|
||||
offset = rangeToDelete.getEndOffset();
|
||||
int offset = startOffset;
|
||||
int curRangeStart = 0;
|
||||
for (PsiLanguageInjectionHost.Shred shred : myShreds) {
|
||||
curRangeStart += shred.prefix.length();
|
||||
if (offset < curRangeStart) offset = curRangeStart;
|
||||
if (offset >= endOffset) break;
|
||||
RangeMarker hostRange = shred.getHostRangeMarker();
|
||||
if (!hostRange.isValid()) continue;
|
||||
int hostRangeLength = hostRange.getEndOffset() - hostRange.getStartOffset();
|
||||
TextRange range = TextRange.from(curRangeStart, hostRangeLength);
|
||||
if (range.contains(offset)) {
|
||||
TextRange rangeToDelete = new TextRange(offset, Math.min(range.getEndOffset(), endOffset));
|
||||
hostRangesToDelete.add(rangeToDelete.shiftRight(hostRange.getStartOffset() - curRangeStart));
|
||||
offset = rangeToDelete.getEndOffset();
|
||||
}
|
||||
curRangeStart += hostRangeLength;
|
||||
curRangeStart += shred.suffix.length();
|
||||
}
|
||||
curRangeStart += hostRangeLength;
|
||||
curRangeStart += shred.suffix.length();
|
||||
}
|
||||
|
||||
int delta = 0;
|
||||
@@ -342,30 +349,33 @@ public class DocumentWindowImpl extends UserDataHolderBase implements Disposable
|
||||
assert intersectWithEditable(new TextRange(startOffset, startOffset)) != null;
|
||||
assert intersectWithEditable(new TextRange(endOffset, endOffset)) != null;
|
||||
|
||||
List<Pair<TextRange,CharSequence>> hostRangesToModify = new ArrayList<Pair<TextRange, CharSequence>>(myShreds.size());
|
||||
List<Pair<TextRange,CharSequence>> hostRangesToModify;
|
||||
synchronized (myLock) {
|
||||
hostRangesToModify = new ArrayList<Pair<TextRange, CharSequence>>(myShreds.size());
|
||||
|
||||
int offset = startOffset;
|
||||
int curRangeStart = 0;
|
||||
for (int i = 0; i < myShreds.size(); i++) {
|
||||
PsiLanguageInjectionHost.Shred shred = myShreds.get(i);
|
||||
curRangeStart += shred.prefix.length();
|
||||
if (offset < curRangeStart) offset = curRangeStart;
|
||||
RangeMarker hostRange = shred.getHostRangeMarker();
|
||||
if (!hostRange.isValid()) continue;
|
||||
int hostRangeLength = hostRange.getEndOffset() - hostRange.getStartOffset();
|
||||
TextRange range = TextRange.from(curRangeStart, hostRangeLength);
|
||||
if (range.contains(offset) || range.getEndOffset() == offset/* in case of inserting at the end*/) {
|
||||
TextRange rangeToModify = new TextRange(offset, Math.min(range.getEndOffset(), endOffset));
|
||||
TextRange hostRangeToModify = rangeToModify.shiftRight(hostRange.getStartOffset() - curRangeStart);
|
||||
CharSequence toReplace = i == myShreds.size() - 1 || range.getEndOffset() + shred.suffix.length() >= endOffset
|
||||
? s : s.subSequence(0, Math.min(hostRangeToModify.getLength(), s.length()));
|
||||
s = toReplace == s ? "" : s.subSequence(toReplace.length(), s.length());
|
||||
hostRangesToModify.add(Pair.create(hostRangeToModify, toReplace));
|
||||
offset = rangeToModify.getEndOffset();
|
||||
int offset = startOffset;
|
||||
int curRangeStart = 0;
|
||||
for (int i = 0; i < myShreds.size(); i++) {
|
||||
PsiLanguageInjectionHost.Shred shred = myShreds.get(i);
|
||||
curRangeStart += shred.prefix.length();
|
||||
if (offset < curRangeStart) offset = curRangeStart;
|
||||
RangeMarker hostRange = shred.getHostRangeMarker();
|
||||
if (!hostRange.isValid()) continue;
|
||||
int hostRangeLength = hostRange.getEndOffset() - hostRange.getStartOffset();
|
||||
TextRange range = TextRange.from(curRangeStart, hostRangeLength);
|
||||
if (range.contains(offset) || range.getEndOffset() == offset/* in case of inserting at the end*/) {
|
||||
TextRange rangeToModify = new TextRange(offset, Math.min(range.getEndOffset(), endOffset));
|
||||
TextRange hostRangeToModify = rangeToModify.shiftRight(hostRange.getStartOffset() - curRangeStart);
|
||||
CharSequence toReplace = i == myShreds.size() - 1 || range.getEndOffset() + shred.suffix.length() >= endOffset
|
||||
? s : s.subSequence(0, Math.min(hostRangeToModify.getLength(), s.length()));
|
||||
s = toReplace == s ? "" : s.subSequence(toReplace.length(), s.length());
|
||||
hostRangesToModify.add(Pair.create(hostRangeToModify, toReplace));
|
||||
offset = rangeToModify.getEndOffset();
|
||||
}
|
||||
curRangeStart += hostRangeLength;
|
||||
curRangeStart += shred.suffix.length();
|
||||
if (curRangeStart >= endOffset) break;
|
||||
}
|
||||
curRangeStart += hostRangeLength;
|
||||
curRangeStart += shred.suffix.length();
|
||||
if (curRangeStart >= endOffset) break;
|
||||
}
|
||||
|
||||
int delta = 0;
|
||||
@@ -484,18 +494,20 @@ public class DocumentWindowImpl extends UserDataHolderBase implements Disposable
|
||||
|
||||
@Override
|
||||
public void setText(@NotNull CharSequence text) {
|
||||
LOG.assertTrue(text.toString().startsWith(myShreds.get(0).prefix));
|
||||
LOG.assertTrue(text.toString().endsWith(myShreds.get(myShreds.size() - 1).suffix));
|
||||
if (isOneLine()) {
|
||||
text = StringUtil.replace(text.toString(), "\n", "");
|
||||
}
|
||||
String[] changes = calculateMinEditSequence(text.toString());
|
||||
assert changes.length == myShreds.size();
|
||||
for (int i = 0; i < changes.length; i++) {
|
||||
String change = changes[i];
|
||||
if (change != null) {
|
||||
RangeMarker hostRange = myShreds.get(i).getHostRangeMarker();
|
||||
myDelegate.replaceString(hostRange.getStartOffset(), hostRange.getEndOffset(), change);
|
||||
synchronized (myLock) {
|
||||
LOG.assertTrue(text.toString().startsWith(myShreds.get(0).prefix));
|
||||
LOG.assertTrue(text.toString().endsWith(myShreds.get(myShreds.size() - 1).suffix));
|
||||
if (isOneLine()) {
|
||||
text = StringUtil.replace(text.toString(), "\n", "");
|
||||
}
|
||||
String[] changes = calculateMinEditSequence(text.toString());
|
||||
assert changes.length == myShreds.size();
|
||||
for (int i = 0; i < changes.length; i++) {
|
||||
String change = changes[i];
|
||||
if (change != null) {
|
||||
RangeMarker hostRange = myShreds.get(i).getHostRangeMarker();
|
||||
myDelegate.replaceString(hostRange.getStartOffset(), hostRange.getEndOffset(), change);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -503,12 +515,14 @@ public class DocumentWindowImpl extends UserDataHolderBase implements Disposable
|
||||
@Override
|
||||
@NotNull
|
||||
public RangeMarker[] getHostRanges() {
|
||||
RangeMarker[] markers = new RangeMarker[myShreds.size()];
|
||||
for (int i = 0; i < myShreds.size(); i++) {
|
||||
PsiLanguageInjectionHost.Shred shred = myShreds.get(i);
|
||||
markers[i] = shred.getHostRangeMarker();
|
||||
synchronized (myLock) {
|
||||
RangeMarker[] markers = new RangeMarker[myShreds.size()];
|
||||
for (int i = 0; i < myShreds.size(); i++) {
|
||||
PsiLanguageInjectionHost.Shred shred = myShreds.get(i);
|
||||
markers[i] = shred.getHostRangeMarker();
|
||||
}
|
||||
return markers;
|
||||
}
|
||||
return markers;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -603,20 +617,22 @@ public class DocumentWindowImpl extends UserDataHolderBase implements Disposable
|
||||
//todo use escaper?
|
||||
@Override
|
||||
public int hostToInjected(int hostOffset) {
|
||||
if (hostOffset < myShreds.get(0).getHostRangeMarker().getStartOffset()) return myShreds.get(0).prefix.length();
|
||||
int offset = 0;
|
||||
for (int i = 0; i < myShreds.size(); i++) {
|
||||
offset += myShreds.get(i).prefix.length();
|
||||
RangeMarker currentRange = myShreds.get(i).getHostRangeMarker();
|
||||
RangeMarker nextRange = i == myShreds.size() - 1 ? null : myShreds.get(i + 1).getHostRangeMarker();
|
||||
if (nextRange == null || hostOffset < nextRange.getStartOffset()) {
|
||||
if (hostOffset >= currentRange.getEndOffset()) hostOffset = currentRange.getEndOffset();
|
||||
return offset + hostOffset - currentRange.getStartOffset();
|
||||
synchronized (myLock) {
|
||||
if (hostOffset < myShreds.get(0).getHostRangeMarker().getStartOffset()) return myShreds.get(0).prefix.length();
|
||||
int offset = 0;
|
||||
for (int i = 0; i < myShreds.size(); i++) {
|
||||
offset += myShreds.get(i).prefix.length();
|
||||
RangeMarker currentRange = myShreds.get(i).getHostRangeMarker();
|
||||
RangeMarker nextRange = i == myShreds.size() - 1 ? null : myShreds.get(i + 1).getHostRangeMarker();
|
||||
if (nextRange == null || hostOffset < nextRange.getStartOffset()) {
|
||||
if (hostOffset >= currentRange.getEndOffset()) hostOffset = currentRange.getEndOffset();
|
||||
return offset + hostOffset - currentRange.getStartOffset();
|
||||
}
|
||||
offset += currentRange.getEndOffset() - currentRange.getStartOffset();
|
||||
offset += myShreds.get(i).suffix.length();
|
||||
}
|
||||
offset += currentRange.getEndOffset() - currentRange.getStartOffset();
|
||||
offset += myShreds.get(i).suffix.length();
|
||||
return getTextLength() - myShreds.get(myShreds.size() - 1).suffix.length();
|
||||
}
|
||||
return getTextLength() - myShreds.get(myShreds.size() - 1).suffix.length();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -627,7 +643,9 @@ public class DocumentWindowImpl extends UserDataHolderBase implements Disposable
|
||||
|
||||
// heuristics: return offset closest to the caret
|
||||
Editor[] editors = EditorFactory.getInstance().getEditors(getDelegate());
|
||||
for (Editor editor : editors) {
|
||||
Editor editor = editors.length == 0 ? null : editors[0];
|
||||
if (editor != null)
|
||||
{
|
||||
if (editor instanceof EditorWindow) editor = ((EditorWindow)editor).getDelegate();
|
||||
int caret = editor.getCaretModel().getOffset();
|
||||
return Math.abs(caret - offsetInLeftFragment) < Math.abs(caret - offsetInRightFragment) ? offsetInLeftFragment : offsetInRightFragment;
|
||||
@@ -636,26 +654,28 @@ public class DocumentWindowImpl extends UserDataHolderBase implements Disposable
|
||||
}
|
||||
|
||||
private int injectedToHost(int offset, boolean preferLeftFragment) {
|
||||
if (offset < myShreds.get(0).prefix.length()) return myShreds.get(0).getHostRangeMarker().getStartOffset();
|
||||
int prevEnd = 0;
|
||||
for (int i = 0; i < myShreds.size(); i++) {
|
||||
RangeMarker currentRange = myShreds.get(i).getHostRangeMarker();
|
||||
offset -= myShreds.get(i).prefix.length();
|
||||
int length = currentRange.getEndOffset() - currentRange.getStartOffset();
|
||||
if (offset < 0) {
|
||||
return preferLeftFragment ? prevEnd : currentRange.getStartOffset() - 1;
|
||||
synchronized (myLock) {
|
||||
if (offset < myShreds.get(0).prefix.length()) return myShreds.get(0).getHostRangeMarker().getStartOffset();
|
||||
int prevEnd = 0;
|
||||
for (int i = 0; i < myShreds.size(); i++) {
|
||||
RangeMarker currentRange = myShreds.get(i).getHostRangeMarker();
|
||||
offset -= myShreds.get(i).prefix.length();
|
||||
int length = currentRange.getEndOffset() - currentRange.getStartOffset();
|
||||
if (offset < 0) {
|
||||
return preferLeftFragment ? prevEnd : currentRange.getStartOffset() - 1;
|
||||
}
|
||||
if (offset == 0) {
|
||||
return preferLeftFragment && i != 0 ? prevEnd : currentRange.getStartOffset();
|
||||
}
|
||||
if (offset < length || offset == length && preferLeftFragment) {
|
||||
return currentRange.getStartOffset() + offset;
|
||||
}
|
||||
offset -= length;
|
||||
offset -= myShreds.get(i).suffix.length();
|
||||
prevEnd = currentRange.getEndOffset();
|
||||
}
|
||||
if (offset == 0) {
|
||||
return preferLeftFragment && i != 0 ? prevEnd : currentRange.getStartOffset();
|
||||
}
|
||||
if (offset < length || offset == length && preferLeftFragment) {
|
||||
return currentRange.getStartOffset() + offset;
|
||||
}
|
||||
offset -= length;
|
||||
offset -= myShreds.get(i).suffix.length();
|
||||
prevEnd = currentRange.getEndOffset();
|
||||
return myShreds.get(myShreds.size() - 1).getHostRangeMarker().getEndOffset();
|
||||
}
|
||||
return myShreds.get(myShreds.size() - 1).getHostRangeMarker().getEndOffset();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -673,7 +693,9 @@ public class DocumentWindowImpl extends UserDataHolderBase implements Disposable
|
||||
@Override
|
||||
public int injectedToHostLine(int line) {
|
||||
if (line < myPrefixLineCount) {
|
||||
return myDelegate.getLineNumber(myShreds.get(0).getHostRangeMarker().getStartOffset());
|
||||
synchronized (myLock) {
|
||||
return myDelegate.getLineNumber(myShreds.get(0).getHostRangeMarker().getStartOffset());
|
||||
}
|
||||
}
|
||||
int lineCount = getLineCount();
|
||||
if (line > lineCount - mySuffixLineCount) {
|
||||
@@ -687,145 +709,140 @@ public class DocumentWindowImpl extends UserDataHolderBase implements Disposable
|
||||
|
||||
@Override
|
||||
public boolean containsRange(int start, int end) {
|
||||
if (end - start > myShreds.get(0).getHostRangeMarker().getEndOffset() - myShreds.get(0).getHostRangeMarker().getStartOffset()) return false;
|
||||
for (PsiLanguageInjectionHost.Shred shred : myShreds) {
|
||||
RangeMarker hostRange = shred.getHostRangeMarker();
|
||||
if (!hostRange.isValid()) continue;
|
||||
TextRange textRange = ProperTextRange.create(hostRange);
|
||||
if (textRange.contains(new ProperTextRange(start, end))) return true;
|
||||
synchronized (myLock) {
|
||||
if (end - start > myShreds.get(0).getHostRangeMarker().getEndOffset() - myShreds.get(0).getHostRangeMarker().getStartOffset()) return false;
|
||||
for (PsiLanguageInjectionHost.Shred shred : myShreds) {
|
||||
RangeMarker hostRange = shred.getHostRangeMarker();
|
||||
if (!hostRange.isValid()) continue;
|
||||
TextRange textRange = ProperTextRange.create(hostRange);
|
||||
if (textRange.contains(new ProperTextRange(start, end))) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
@Nullable
|
||||
public TextRange intersectWithEditable(@NotNull TextRange rangeToEdit) {
|
||||
int offset = 0;
|
||||
int startOffset = -1;
|
||||
int endOffset = -1;
|
||||
for (PsiLanguageInjectionHost.Shred shred : myShreds) {
|
||||
RangeMarker hostRange = shred.getHostRangeMarker();
|
||||
offset += shred.prefix.length();
|
||||
int length = hostRange.getEndOffset() - hostRange.getStartOffset();
|
||||
TextRange intersection = new ProperTextRange(offset, offset + length).intersection(rangeToEdit);
|
||||
if (intersection != null) {
|
||||
if (startOffset == -1) {
|
||||
startOffset = intersection.getStartOffset();
|
||||
synchronized (myLock) {
|
||||
int offset = 0;
|
||||
for (PsiLanguageInjectionHost.Shred shred : myShreds) {
|
||||
RangeMarker hostRange = shred.getHostRangeMarker();
|
||||
offset += shred.prefix.length();
|
||||
int length = hostRange.getEndOffset() - hostRange.getStartOffset();
|
||||
TextRange intersection = new ProperTextRange(offset, offset + length).intersection(rangeToEdit);
|
||||
if (intersection != null) {
|
||||
if (startOffset == -1) {
|
||||
startOffset = intersection.getStartOffset();
|
||||
}
|
||||
endOffset = intersection.getEndOffset();
|
||||
}
|
||||
endOffset = intersection.getEndOffset();
|
||||
offset += length;
|
||||
offset += shred.suffix.length();
|
||||
}
|
||||
offset += length;
|
||||
offset += shred.suffix.length();
|
||||
}
|
||||
if (startOffset == -1) return null;
|
||||
return new ProperTextRange(startOffset, endOffset);
|
||||
}
|
||||
|
||||
boolean intersects(DocumentWindowImpl documentWindow) {
|
||||
int i = 0;
|
||||
int j = 0;
|
||||
while (i < myShreds.size() && j < documentWindow.myShreds.size()) {
|
||||
RangeMarker range = myShreds.get(i).getHostRangeMarker();
|
||||
RangeMarker otherRange = documentWindow.myShreds.get(j).getHostRangeMarker();
|
||||
if (ProperTextRange.create(range).intersects(ProperTextRange.create(otherRange))) return true;
|
||||
if (range.getEndOffset() > otherRange.getStartOffset()) i++;
|
||||
else if (range.getStartOffset() < otherRange.getEndOffset()) j++;
|
||||
else {
|
||||
i++;
|
||||
j++;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// minimum sequence of text replacement operations for each host range
|
||||
// result[i] == null means no change
|
||||
// result[i] == "" means delete
|
||||
// result[i] == string means replace
|
||||
public String[] calculateMinEditSequence(String newText) {
|
||||
String[] result = new String[myShreds.size()];
|
||||
String hostText = myDelegate.getText();
|
||||
calculateMinEditSequence(hostText, newText, result, 0, result.length - 1);
|
||||
for (int i = 0; i < result.length; i++) {
|
||||
String change = result[i];
|
||||
if (change == null) continue;
|
||||
String prefix = myShreds.get(i).prefix;
|
||||
String suffix = myShreds.get(i).suffix;
|
||||
assert change.startsWith(prefix) : change + "/" + prefix;
|
||||
assert change.endsWith(suffix) : change + "/" + suffix;
|
||||
result[i] = StringUtil.trimEnd(StringUtil.trimStart(change, prefix), suffix);
|
||||
synchronized (myLock) {
|
||||
String[] result = new String[myShreds.size()];
|
||||
String hostText = myDelegate.getText();
|
||||
calculateMinEditSequence(hostText, newText, result, 0, result.length - 1);
|
||||
for (int i = 0; i < result.length; i++) {
|
||||
String change = result[i];
|
||||
if (change == null) continue;
|
||||
String prefix = myShreds.get(i).prefix;
|
||||
String suffix = myShreds.get(i).suffix;
|
||||
assert change.startsWith(prefix) : change + "/" + prefix;
|
||||
assert change.endsWith(suffix) : change + "/" + suffix;
|
||||
result[i] = StringUtil.trimEnd(StringUtil.trimStart(change, prefix), suffix);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private String getRangeText(String hostText, int hostNum) {
|
||||
PsiLanguageInjectionHost.Shred shred = myShreds.get(hostNum);
|
||||
return shred.prefix +
|
||||
hostText.substring(shred.getHostRangeMarker().getStartOffset(), shred.getHostRangeMarker().getEndOffset()) +
|
||||
shred.suffix;
|
||||
synchronized (myLock) {
|
||||
PsiLanguageInjectionHost.Shred shred = myShreds.get(hostNum);
|
||||
return shred.prefix +
|
||||
hostText.substring(shred.getHostRangeMarker().getStartOffset(), shred.getHostRangeMarker().getEndOffset()) +
|
||||
shred.suffix;
|
||||
}
|
||||
}
|
||||
private void calculateMinEditSequence(String hostText, String newText, String[] result, int i, int j) {
|
||||
String rangeText1 = getRangeText(hostText, i);
|
||||
if (i == j) {
|
||||
result[i] = rangeText1.equals(newText) ? null : newText;
|
||||
return;
|
||||
}
|
||||
if (StringUtil.startsWith(newText, rangeText1)) {
|
||||
result[i] = null; //no change
|
||||
calculateMinEditSequence(hostText, newText.substring(rangeText1.length()), result, i+1, j);
|
||||
return;
|
||||
}
|
||||
String rangeText2 = getRangeText(hostText, j);
|
||||
if (StringUtil.endsWith(newText, rangeText2)) {
|
||||
result[j] = null; //no change
|
||||
calculateMinEditSequence(hostText, newText.substring(0, newText.length() - rangeText2.length()), result, i, j-1);
|
||||
return;
|
||||
}
|
||||
if (i+1 == j) {
|
||||
String suffix = myShreds.get(i).suffix;
|
||||
String prefix = myShreds.get(j).prefix;
|
||||
String separator = suffix + prefix;
|
||||
if (separator.length() != 0) {
|
||||
int sep = newText.indexOf(separator);
|
||||
assert sep != -1;
|
||||
result[i] = newText.substring(0, sep + suffix.length());
|
||||
result[j] = newText.substring(sep + suffix.length() + prefix.length(), newText.length());
|
||||
synchronized (myLock) {
|
||||
String rangeText1 = getRangeText(hostText, i);
|
||||
if (i == j) {
|
||||
result[i] = rangeText1.equals(newText) ? null : newText;
|
||||
return;
|
||||
}
|
||||
String commonPrefix = StringUtil.commonPrefix(rangeText1, newText);
|
||||
result[i] = commonPrefix;
|
||||
result[j] = newText.substring(commonPrefix.length());
|
||||
return;
|
||||
if (StringUtil.startsWith(newText, rangeText1)) {
|
||||
result[i] = null; //no change
|
||||
calculateMinEditSequence(hostText, newText.substring(rangeText1.length()), result, i+1, j);
|
||||
return;
|
||||
}
|
||||
String rangeText2 = getRangeText(hostText, j);
|
||||
if (StringUtil.endsWith(newText, rangeText2)) {
|
||||
result[j] = null; //no change
|
||||
calculateMinEditSequence(hostText, newText.substring(0, newText.length() - rangeText2.length()), result, i, j-1);
|
||||
return;
|
||||
}
|
||||
if (i+1 == j) {
|
||||
String suffix = myShreds.get(i).suffix;
|
||||
String prefix = myShreds.get(j).prefix;
|
||||
String separator = suffix + prefix;
|
||||
if (!separator.isEmpty()) {
|
||||
int sep = newText.indexOf(separator);
|
||||
assert sep != -1;
|
||||
result[i] = newText.substring(0, sep + suffix.length());
|
||||
result[j] = newText.substring(sep + suffix.length() + prefix.length(), newText.length());
|
||||
return;
|
||||
}
|
||||
String commonPrefix = StringUtil.commonPrefix(rangeText1, newText);
|
||||
result[i] = commonPrefix;
|
||||
result[j] = newText.substring(commonPrefix.length());
|
||||
return;
|
||||
}
|
||||
String middleText = getRangeText(hostText, i + 1);
|
||||
int m = newText.indexOf(middleText);
|
||||
if (m != -1) {
|
||||
result[i] = newText.substring(0, m);
|
||||
result[i+1] = null;
|
||||
calculateMinEditSequence(hostText, newText.substring(m+middleText.length(), newText.length()), result, i+2, j);
|
||||
return;
|
||||
}
|
||||
middleText = getRangeText(hostText, j - 1);
|
||||
m = newText.lastIndexOf(middleText);
|
||||
if (m != -1) {
|
||||
result[j] = newText.substring(m+middleText.length());
|
||||
result[j-1] = null;
|
||||
calculateMinEditSequence(hostText, newText.substring(0, m), result, i, j-2);
|
||||
return;
|
||||
}
|
||||
result[i] = "";
|
||||
result[j] = "";
|
||||
calculateMinEditSequence(hostText, newText, result, i+1, j-1);
|
||||
}
|
||||
String middleText = getRangeText(hostText, i + 1);
|
||||
int m = newText.indexOf(middleText);
|
||||
if (m != -1) {
|
||||
result[i] = newText.substring(0, m);
|
||||
result[i+1] = null;
|
||||
calculateMinEditSequence(hostText, newText.substring(m+middleText.length(), newText.length()), result, i+2, j);
|
||||
return;
|
||||
}
|
||||
middleText = getRangeText(hostText, j - 1);
|
||||
m = newText.lastIndexOf(middleText);
|
||||
if (m != -1) {
|
||||
result[j] = newText.substring(m+middleText.length());
|
||||
result[j-1] = null;
|
||||
calculateMinEditSequence(hostText, newText.substring(0, m), result, i, j-2);
|
||||
return;
|
||||
}
|
||||
result[i] = "";
|
||||
result[j] = "";
|
||||
calculateMinEditSequence(hostText, newText, result, i+1, j-1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean areRangesEqual(@NotNull DocumentWindow otherd) {
|
||||
DocumentWindowImpl window = (DocumentWindowImpl)otherd;
|
||||
if (myShreds.size() != window.myShreds.size()) return false;
|
||||
for (int i = 0; i < myShreds.size(); i++) {
|
||||
PsiLanguageInjectionHost.Shred shred = myShreds.get(i);
|
||||
PsiLanguageInjectionHost.Shred otherShred = window.myShreds.get(i);
|
||||
Place shreds = getShreds();
|
||||
Place otherShreds = window.getShreds();
|
||||
if (shreds.size() != otherShreds.size()) return false;
|
||||
for (int i = 0; i < shreds.size(); i++) {
|
||||
PsiLanguageInjectionHost.Shred shred = shreds.get(i);
|
||||
PsiLanguageInjectionHost.Shred otherShred = otherShreds.get(i);
|
||||
if (!shred.prefix.equals(otherShred.prefix)) return false;
|
||||
if (!shred.suffix.equals(otherShred.suffix)) return false;
|
||||
|
||||
@@ -839,7 +856,9 @@ public class DocumentWindowImpl extends UserDataHolderBase implements Disposable
|
||||
|
||||
@Override
|
||||
public boolean isValid() {
|
||||
return myShreds.isValid();
|
||||
synchronized (myLock) {
|
||||
return myShreds.isValid();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean equals(Object o) {
|
||||
@@ -849,7 +868,9 @@ public class DocumentWindowImpl extends UserDataHolderBase implements Disposable
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return myShreds.get(0).getHostRangeMarker().getStartOffset();
|
||||
synchronized (myLock) {
|
||||
return myShreds.get(0).getHostRangeMarker().getStartOffset();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isOneLine() {
|
||||
@@ -858,14 +879,27 @@ public class DocumentWindowImpl extends UserDataHolderBase implements Disposable
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
for (PsiLanguageInjectionHost.Shred shred : myShreds) {
|
||||
RangeMarker rangeMarker = shred.getHostRangeMarker();
|
||||
rangeMarker.dispose();
|
||||
synchronized (myLock) {
|
||||
for (PsiLanguageInjectionHost.Shred shred : myShreds) {
|
||||
RangeMarker rangeMarker = shred.getHostRangeMarker();
|
||||
rangeMarker.dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void setShreds(Place shreds) {
|
||||
myShreds = shreds;
|
||||
public void setShreds(@NotNull Place shreds) {
|
||||
synchronized (myLock) {
|
||||
if (myShreds != shreds) {
|
||||
myShreds.dispose();
|
||||
myShreds = shreds;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Place getShreds() {
|
||||
synchronized (myLock) {
|
||||
return myShreds;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -39,6 +39,7 @@ import com.intellij.openapi.editor.impl.softwrap.SoftWrapAppliancePlaces;
|
||||
import com.intellij.openapi.editor.markup.MarkupModel;
|
||||
import com.intellij.openapi.editor.markup.TextAttributes;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Disposer;
|
||||
import com.intellij.openapi.util.UserDataHolderBase;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.PsiFile;
|
||||
@@ -109,7 +110,7 @@ public class EditorWindow extends UserDataHolderBase implements EditorEx {
|
||||
Iterator<EditorWindow> iterator = allEditors.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
EditorWindow editorWindow = iterator.next();
|
||||
if (!editorWindow.isValid()/* || myDocumentWindow.intersects(editorWindow.myDocumentWindow)*/) {
|
||||
if (!editorWindow.isValid()) {
|
||||
editorWindow.dispose();
|
||||
|
||||
InjectedLanguageUtil.clearCaches(editorWindow.myInjectedFile, editorWindow.getDocument());
|
||||
@@ -185,6 +186,7 @@ public class EditorWindow extends UserDataHolderBase implements EditorEx {
|
||||
myEditorMouseMotionListeners.clear();
|
||||
|
||||
myDisposed = true;
|
||||
Disposer.dispose(myDocumentWindow);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+3
-1
@@ -84,7 +84,9 @@ public class ReformatBeforeCheckinHandler extends CheckinHandler implements Chec
|
||||
};
|
||||
|
||||
if (reformat(configuration, true)) {
|
||||
new ReformatCodeProcessor(myProject, BeforeCheckinHandlerUtil.getPsiFiles(myProject, files), COMMAND_NAME, performCheckoutAction).run();
|
||||
new ReformatCodeProcessor(
|
||||
myProject, BeforeCheckinHandlerUtil.getPsiFiles(myProject, files), COMMAND_NAME, performCheckoutAction, false
|
||||
).run();
|
||||
}
|
||||
else {
|
||||
performCheckoutAction.run();
|
||||
|
||||
+8
-4
@@ -37,8 +37,12 @@ public class CompositeWhiteSpaceFormattingStrategy implements WhiteSpaceFormatti
|
||||
private final List<WhiteSpaceFormattingStrategy> myStrategies = new ArrayList<WhiteSpaceFormattingStrategy>();
|
||||
private boolean myReplaceDefaultStrategy;
|
||||
|
||||
public CompositeWhiteSpaceFormattingStrategy(@NotNull Collection<WhiteSpaceFormattingStrategy> strategies) {
|
||||
myStrategies.addAll(strategies);
|
||||
public CompositeWhiteSpaceFormattingStrategy(@NotNull Collection<WhiteSpaceFormattingStrategy> strategies)
|
||||
throws IllegalArgumentException
|
||||
{
|
||||
for (WhiteSpaceFormattingStrategy strategy : strategies) {
|
||||
addStrategy(strategy);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -64,9 +68,9 @@ public class CompositeWhiteSpaceFormattingStrategy implements WhiteSpaceFormatti
|
||||
return myReplaceDefaultStrategy;
|
||||
}
|
||||
|
||||
public void addStrategy(@NotNull WhiteSpaceFormattingStrategy strategy) throws IllegalStateException {
|
||||
public void addStrategy(@NotNull WhiteSpaceFormattingStrategy strategy) throws IllegalArgumentException {
|
||||
if (myReplaceDefaultStrategy && strategy.replaceDefaultStrategy()) {
|
||||
throw new IllegalStateException(String.format(
|
||||
throw new IllegalArgumentException(String.format(
|
||||
"Can't combine strategy '%s' with already registered strategies (%s). Reason: given strategy is marked to replace "
|
||||
+ "all existing strategies but strategy with such characteristics is already registered", strategy, myStrategies
|
||||
));
|
||||
|
||||
@@ -1,122 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2009 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.psi.impl.cache.impl;
|
||||
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.progress.ProgressIndicator;
|
||||
import com.intellij.openapi.progress.ProgressManager;
|
||||
import com.intellij.openapi.vfs.VfsUtil;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.openapi.vfs.VirtualFileFilter;
|
||||
import com.intellij.psi.PsiBundle;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class VfsIndexer {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.cache.impl.VfsIndexer");
|
||||
|
||||
public static VirtualFile[] writeFileIndex(
|
||||
OutputStream stream,
|
||||
VirtualFile root,
|
||||
VirtualFileFilter filter) throws IOException {
|
||||
|
||||
List<VirtualFile> result = new ArrayList<VirtualFile>();
|
||||
|
||||
ProgressIndicator progress = ProgressManager.getInstance().getProgressIndicator();
|
||||
if (progress != null){
|
||||
progress.setText2(PsiBundle.message("psi.scanning.files.in.folder.progress", root.getPresentableUrl()));
|
||||
}
|
||||
|
||||
DataOutputStream out = stream == null ? null : new DataOutputStream(stream);
|
||||
|
||||
_writeFileIndex(out, root, filter, result);
|
||||
|
||||
if (out != null){
|
||||
out.flush();
|
||||
}
|
||||
|
||||
return VfsUtil.toVirtualFileArray(result);
|
||||
}
|
||||
|
||||
private static void _writeFileIndex(DataOutputStream out, VirtualFile file, VirtualFileFilter filter, List<VirtualFile> result) throws IOException {
|
||||
ProgressManager.checkCanceled();
|
||||
|
||||
result.add(file);
|
||||
if (out != null){
|
||||
out.writeUTF(file.getName());
|
||||
}
|
||||
|
||||
VirtualFile[] children = file.getChildren();
|
||||
if (children == null) {
|
||||
if (out != null){
|
||||
out.writeInt(0);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
int childrenCount = 0;
|
||||
for (VirtualFile child : children) {
|
||||
if (filter.accept(child)) childrenCount++;
|
||||
}
|
||||
|
||||
if (out != null){
|
||||
out.writeInt(childrenCount);
|
||||
}
|
||||
for (VirtualFile child : children) {
|
||||
if (filter.accept(child)) {
|
||||
_writeFileIndex(out, child, filter, result);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static VirtualFile[] readFileIndex(
|
||||
InputStream stream,
|
||||
VirtualFile root,
|
||||
VirtualFileFilter filter
|
||||
) throws IOException {
|
||||
List<VirtualFile> result = new ArrayList<VirtualFile>();
|
||||
|
||||
DataInputStream in = new DataInputStream(stream);
|
||||
|
||||
String rootName = in.readUTF();
|
||||
LOG.assertTrue(root.getName().equals(rootName));
|
||||
_readFileIndex(in, root, filter, result);
|
||||
|
||||
return VfsUtil.toVirtualFileArray(result);
|
||||
}
|
||||
|
||||
private static void _readFileIndex(DataInputStream in, VirtualFile file, VirtualFileFilter filter, List<VirtualFile> result) throws IOException {
|
||||
ProgressManager.checkCanceled();
|
||||
|
||||
result.add(file);
|
||||
int childrenCount = in.readInt();
|
||||
if (childrenCount == 0) return;
|
||||
|
||||
for (int i = 0; i < childrenCount; i++) {
|
||||
String name = in.readUTF();
|
||||
VirtualFile child = file != null ? file.findChild(name) : null;
|
||||
|
||||
if (child != null && !filter.accept(child)){
|
||||
child = null;
|
||||
}
|
||||
|
||||
_readFileIndex(in, child, filter, result);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -319,7 +319,7 @@ public class PsiSearchHelperImpl implements PsiSearchHelper {
|
||||
}
|
||||
});
|
||||
}
|
||||
if (progress != null) {
|
||||
if (progress != null && progress.isRunning()) {
|
||||
double fraction = (double)counter.incrementAndGet() / size;
|
||||
progress.setFraction(fraction);
|
||||
}
|
||||
|
||||
+65
-26
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
* Copyright 2000-2011 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.
|
||||
@@ -48,6 +48,10 @@ import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class CodeStyleManagerImpl extends CodeStyleManager {
|
||||
@@ -137,6 +141,14 @@ public class CodeStyleManagerImpl extends CodeStyleManager {
|
||||
|
||||
@Override
|
||||
public void reformatText(@NotNull PsiFile file, int startOffset, int endOffset) throws IncorrectOperationException {
|
||||
reformatText(file, Collections.singleton(new TextRange(startOffset, endOffset)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reformatText(@NotNull PsiFile file, @NotNull Collection<TextRange> ranges) throws IncorrectOperationException {
|
||||
if (ranges.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
ApplicationManager.getApplication().assertWriteAccessAllowed();
|
||||
PsiDocumentManager.getInstance(getProject()).commitAllDocuments();
|
||||
|
||||
@@ -150,17 +162,9 @@ public class CodeStyleManagerImpl extends CodeStyleManager {
|
||||
|
||||
final CodeFormatterFacade codeFormatter = new CodeFormatterFacade(getSettings());
|
||||
LOG.assertTrue(file.isValid());
|
||||
final PsiElement start = findElementInTreeWithFormatterEnabled(file, startOffset);
|
||||
final PsiElement end = findElementInTreeWithFormatterEnabled(file, endOffset);
|
||||
if (start != null && !start.isValid()) {
|
||||
LOG.error("start=" + start + "; file=" + file);
|
||||
}
|
||||
if (end != null && !end.isValid()) {
|
||||
LOG.error("end=" + start + "; end=" + file);
|
||||
}
|
||||
|
||||
Editor editor = PsiUtilBase.findEditor(file);
|
||||
|
||||
|
||||
// There is a possible case that cursor is located at the end of the line that contains only white spaces. For example:
|
||||
// public void foo() {
|
||||
// <caret>
|
||||
@@ -168,7 +172,7 @@ public class CodeStyleManagerImpl extends CodeStyleManager {
|
||||
// Formatter removes such white spaces, i.e. keeps only line feed symbol. But we want to preserve caret position then.
|
||||
// So, we check if it should be preserved and restore it after formatting if necessary
|
||||
int visualColumnToRestore = -1;
|
||||
|
||||
|
||||
if (editor != null) {
|
||||
Document document = editor.getDocument();
|
||||
int caretOffset = editor.getCaretModel().getOffset();
|
||||
@@ -189,23 +193,40 @@ public class CodeStyleManagerImpl extends CodeStyleManager {
|
||||
visualColumnToRestore = editor.getCaretModel().getVisualPosition().column;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
boolean formatFromStart = startOffset == 0;
|
||||
boolean formatToEnd = endOffset == file.getTextLength();
|
||||
|
||||
final SmartPointerManager smartPointerManager = SmartPointerManager.getInstance(getProject());
|
||||
final SmartPsiElementPointer startPointer = start == null ? null : smartPointerManager.createSmartPsiElementPointer(start);
|
||||
|
||||
final SmartPsiElementPointer endPointer = end == null ? null : smartPointerManager.createSmartPsiElementPointer(end);
|
||||
|
||||
codeFormatter.processText(file, new FormatTextRanges(new TextRange(startOffset, endOffset), true), true);
|
||||
final PsiElement startElement = startPointer == null ? null : startPointer.getElement();
|
||||
final PsiElement endElement = endPointer == null ? null : endPointer.getElement();
|
||||
|
||||
if ((startElement != null || formatFromStart) && (endElement != null || formatToEnd)) {
|
||||
postProcessText(file, new TextRange(formatFromStart ? 0 : startElement.getTextRange().getStartOffset(),
|
||||
formatToEnd ? file.getTextLength() : endElement.getTextRange().getEndOffset()));
|
||||
List<RangeFormatInfo> infos = new ArrayList<RangeFormatInfo>();
|
||||
for (TextRange range : ranges) {
|
||||
final PsiElement start = findElementInTreeWithFormatterEnabled(file, range.getStartOffset());
|
||||
final PsiElement end = findElementInTreeWithFormatterEnabled(file, range.getEndOffset());
|
||||
if (start != null && !start.isValid()) {
|
||||
LOG.error("start=" + start + "; file=" + file);
|
||||
}
|
||||
if (end != null && !end.isValid()) {
|
||||
LOG.error("end=" + start + "; end=" + file);
|
||||
}
|
||||
boolean formatFromStart = range.getStartOffset() == 0;
|
||||
boolean formatToEnd = range.getEndOffset() == file.getTextLength();
|
||||
infos.add(new RangeFormatInfo(
|
||||
start == null ? null : smartPointerManager.createSmartPsiElementPointer(start),
|
||||
end == null ? null : smartPointerManager.createSmartPsiElementPointer(end),
|
||||
formatFromStart,
|
||||
formatToEnd
|
||||
));
|
||||
}
|
||||
|
||||
FormatTextRanges formatRanges = new FormatTextRanges();
|
||||
for (TextRange range : ranges) {
|
||||
formatRanges.add(range, true);
|
||||
}
|
||||
codeFormatter.processText(file, formatRanges, true);
|
||||
for (RangeFormatInfo info : infos) {
|
||||
final PsiElement startElement = info.startPointer == null ? null : info.startPointer.getElement();
|
||||
final PsiElement endElement = info.endPointer == null ? null : info.endPointer.getElement();
|
||||
if ((startElement != null || info.fromStart) && (endElement != null || info.toEnd)) {
|
||||
postProcessText(file, new TextRange(info.fromStart ? 0 : startElement.getTextRange().getStartOffset(),
|
||||
info.toEnd ? file.getTextLength() : endElement.getTextRange().getEndOffset()));
|
||||
}
|
||||
}
|
||||
|
||||
if (visualColumnToRestore < 0) {
|
||||
@@ -758,5 +779,23 @@ public class CodeStyleManagerImpl extends CodeStyleManager {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static class RangeFormatInfo{
|
||||
|
||||
public final SmartPsiElementPointer startPointer;
|
||||
public final SmartPsiElementPointer endPointer;
|
||||
public final boolean fromStart;
|
||||
public final boolean toEnd;
|
||||
|
||||
RangeFormatInfo(@Nullable SmartPsiElementPointer startPointer,
|
||||
@Nullable SmartPsiElementPointer endPointer,
|
||||
boolean fromStart,
|
||||
boolean toEnd)
|
||||
{
|
||||
this.startPointer = startPointer;
|
||||
this.endPointer = endPointer;
|
||||
this.fromStart = fromStart;
|
||||
this.toEnd = toEnd;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+9
-19
@@ -38,10 +38,9 @@ import java.util.List;
|
||||
* @author cdr
|
||||
*/
|
||||
public class InjectedFileViewProvider extends SingleRootFileViewProvider implements FreeThreadedFileViewProvider {
|
||||
private Place myShreds;
|
||||
private Project myProject;
|
||||
private final Object myLock = new Object();
|
||||
private final DocumentWindow myDocumentWindow;
|
||||
private final DocumentWindowImpl myDocumentWindow;
|
||||
private static final ThreadLocal<Boolean> disabledTemporarily = new ThreadLocal<Boolean>(){
|
||||
@Override
|
||||
protected Boolean initialValue() {
|
||||
@@ -52,15 +51,11 @@ public class InjectedFileViewProvider extends SingleRootFileViewProvider impleme
|
||||
|
||||
InjectedFileViewProvider(@NotNull PsiManager psiManager,
|
||||
@NotNull VirtualFileWindow virtualFile,
|
||||
@NotNull Place shreds,
|
||||
@NotNull DocumentWindow documentWindow,
|
||||
@NotNull DocumentWindowImpl documentWindow,
|
||||
@NotNull Language language) {
|
||||
super(psiManager, (VirtualFile)virtualFile, true, language);
|
||||
myDocumentWindow = documentWindow;
|
||||
synchronized (myLock) {
|
||||
myShreds = shreds;
|
||||
myProject = myShreds.get(0).host.getProject();
|
||||
}
|
||||
myProject = documentWindow.getShreds().get(0).host.getProject();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -69,11 +64,8 @@ public class InjectedFileViewProvider extends SingleRootFileViewProvider impleme
|
||||
if (!isPhysical()) return; // injected PSI change happened inside reparse; ignore
|
||||
if (myPatchingLeaves) return;
|
||||
|
||||
List<PsiLanguageInjectionHost.Shred> shreds;
|
||||
synchronized (myLock) {
|
||||
shreds = myShreds;
|
||||
}
|
||||
DocumentWindowImpl documentWindow = (DocumentWindowImpl)myDocumentWindow;
|
||||
DocumentWindowImpl documentWindow = myDocumentWindow;
|
||||
List<PsiLanguageInjectionHost.Shred> shreds = documentWindow.getShreds();
|
||||
assert documentWindow.getHostRanges().length == shreds.size();
|
||||
String[] changes = documentWindow.calculateMinEditSequence(psiFile.getNode().getText());
|
||||
assert changes.length == shreds.size();
|
||||
@@ -122,11 +114,10 @@ public class InjectedFileViewProvider extends SingleRootFileViewProvider impleme
|
||||
return file;
|
||||
}
|
||||
|
||||
void setShreds(Place shreds) {
|
||||
void setShreds(@NotNull Place shreds) {
|
||||
synchronized (myLock) {
|
||||
myShreds = new Place(shreds);
|
||||
myProject = shreds.get(0).host.getProject();
|
||||
((DocumentWindowImpl)myDocumentWindow).setShreds(myShreds);
|
||||
myDocumentWindow.setShreds(shreds);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -141,12 +132,11 @@ public class InjectedFileViewProvider extends SingleRootFileViewProvider impleme
|
||||
}
|
||||
|
||||
Place getShreds() {
|
||||
synchronized (myLock) {
|
||||
return myShreds;
|
||||
}
|
||||
return myDocumentWindow.getShreds();
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public DocumentWindow getDocument() {
|
||||
return myDocumentWindow;
|
||||
}
|
||||
|
||||
+1
-41
@@ -21,7 +21,6 @@ import com.intellij.lang.Language;
|
||||
import com.intellij.lang.injection.InjectedLanguageManager;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.editor.RangeMarker;
|
||||
import com.intellij.openapi.editor.SelectionModel;
|
||||
import com.intellij.openapi.editor.impl.EditorImpl;
|
||||
import com.intellij.openapi.fileEditor.FileEditorManager;
|
||||
@@ -31,7 +30,6 @@ import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.*;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.impl.PsiDocumentManagerImpl;
|
||||
import com.intellij.psi.impl.PsiManagerEx;
|
||||
import com.intellij.psi.impl.PsiParameterizedCachedValue;
|
||||
import com.intellij.psi.impl.source.DummyHolder;
|
||||
@@ -108,7 +106,7 @@ public class InjectedLanguageUtil {
|
||||
public static Place getShreds(@NotNull FileViewProvider viewProvider) {
|
||||
if (!(viewProvider instanceof InjectedFileViewProvider)) return null;
|
||||
InjectedFileViewProvider myFileViewProvider = (InjectedFileViewProvider)viewProvider;
|
||||
return myFileViewProvider.getShreds();
|
||||
return ((DocumentWindowImpl)myFileViewProvider.getDocument()).getShreds();
|
||||
}
|
||||
|
||||
public static void enumerate(@NotNull PsiElement host, @NotNull PsiLanguageInjectionHost.InjectedPsiVisitor visitor) {
|
||||
@@ -330,44 +328,6 @@ public class InjectedLanguageUtil {
|
||||
file.putUserData(INJECTED_DOCS_KEY, null);
|
||||
}
|
||||
|
||||
public static void commitAllInjectedDocuments(Document hostDocument, Project project) {
|
||||
PsiDocumentManager documentManager = PsiDocumentManager.getInstance(project);
|
||||
PsiFile hostPsiFile = documentManager.getPsiFile(hostDocument);
|
||||
if (hostPsiFile == null) return;
|
||||
|
||||
List<DocumentWindow> injected = getCachedInjectedDocuments(hostPsiFile);
|
||||
if (injected.isEmpty()) return;
|
||||
|
||||
for (int i = injected.size() - 1; i >= 0; i--) {
|
||||
DocumentWindow documentWindow = injected.get(i);
|
||||
ProgressManager.checkCanceled();
|
||||
RangeMarker rangeMarker = documentWindow.getHostRanges()[0];
|
||||
PsiElement element = rangeMarker.isValid() ? hostPsiFile.findElementAt(rangeMarker.getStartOffset()) : null;
|
||||
if (element == null) {
|
||||
injected.remove(i);
|
||||
continue;
|
||||
}
|
||||
final DocumentWindow[] stillInjectedDocument = {null};
|
||||
// it is here where the reparse happens and old file contents replaced
|
||||
enumerate(element, hostPsiFile, true, new PsiLanguageInjectionHost.InjectedPsiVisitor() {
|
||||
@Override
|
||||
public void visit(@NotNull PsiFile injectedPsi, @NotNull List<PsiLanguageInjectionHost.Shred> places) {
|
||||
stillInjectedDocument[0] = (DocumentWindow)injectedPsi.getViewProvider().getDocument();
|
||||
PsiDocumentManagerImpl.checkConsistency(injectedPsi, stillInjectedDocument[0]);
|
||||
}
|
||||
});
|
||||
if (stillInjectedDocument[0] == null) {
|
||||
injected.remove(i);
|
||||
}
|
||||
else if (stillInjectedDocument[0] != documentWindow) {
|
||||
injected.set(i,stillInjectedDocument[0]);
|
||||
}
|
||||
}
|
||||
EditorWindow.disposeInvalidEditors(); // in write action
|
||||
|
||||
PsiDocumentManagerImpl.checkConsistency(hostPsiFile, hostDocument);
|
||||
}
|
||||
|
||||
public static void clearCaches(@NotNull PsiFile injected, @NotNull DocumentWindowImpl documentWindow) {
|
||||
VirtualFileWindowImpl virtualFile = (VirtualFileWindowImpl)injected.getVirtualFile();
|
||||
PsiManagerEx psiManagerEx = (PsiManagerEx)injected.getManager();
|
||||
|
||||
+7
-6
@@ -220,7 +220,7 @@ public class MultiHostRegistrarImpl implements MultiHostRegistrar {
|
||||
}
|
||||
FileDocumentManagerImpl.registerDocument(decodedDocument, virtualFile);
|
||||
|
||||
InjectedFileViewProvider viewProvider = new InjectedFileViewProvider(myPsiManager, virtualFile, place, documentWindow, myLanguage);
|
||||
InjectedFileViewProvider viewProvider = new InjectedFileViewProvider(myPsiManager, virtualFile, documentWindow, myLanguage);
|
||||
ParserDefinition parserDefinition = LanguageParserDefinitions.INSTANCE.forLanguage(myLanguage);
|
||||
assert parserDefinition != null : "Parser definition for language "+myLanguage+" is null";
|
||||
PsiFile psiFile = parserDefinition.createFile(viewProvider);
|
||||
@@ -295,11 +295,11 @@ public class MultiHostRegistrarImpl implements MultiHostRegistrar {
|
||||
}
|
||||
}
|
||||
|
||||
private static void cacheEverything(Place place,
|
||||
DocumentWindowImpl documentWindow,
|
||||
InjectedFileViewProvider viewProvider,
|
||||
PsiFile psiFile,
|
||||
SmartPsiElementPointer<PsiLanguageInjectionHost> pointer) {
|
||||
private static void cacheEverything(@NotNull Place place,
|
||||
@NotNull DocumentWindowImpl documentWindow,
|
||||
@NotNull InjectedFileViewProvider viewProvider,
|
||||
@NotNull PsiFile psiFile,
|
||||
@NotNull SmartPsiElementPointer<PsiLanguageInjectionHost> pointer) {
|
||||
FileDocumentManagerImpl.registerDocument(documentWindow, viewProvider.getVirtualFile());
|
||||
|
||||
viewProvider.forceCachedPsi(psiFile);
|
||||
@@ -357,6 +357,7 @@ public class MultiHostRegistrarImpl implements MultiHostRegistrar {
|
||||
result.add(Pair.create(place, psiFile));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static <T extends PsiLanguageInjectionHost> SmartPsiElementPointer<T> createHostSmartPointer(@NotNull T host, @NotNull PsiFile hostPsiFile) {
|
||||
return hostPsiFile.isPhysical()
|
||||
? SmartPointerManager.getInstance(host.getProject()).createSmartPsiElementPointer(host, hostPsiFile)
|
||||
|
||||
@@ -38,4 +38,10 @@ public class Place extends SmartList<PsiLanguageInjectionHost.Shred> {
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public void dispose() {
|
||||
for (PsiLanguageInjectionHost.Shred shred : this) {
|
||||
shred.getHostRangeMarker().dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+20
-8
@@ -65,10 +65,8 @@ import javax.swing.table.TableCellEditor;
|
||||
import java.awt.*;
|
||||
import java.awt.event.FocusAdapter;
|
||||
import java.awt.event.FocusEvent;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.*;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author Konstantin Bulenkov
|
||||
@@ -370,16 +368,30 @@ public abstract class ChangeSignatureDialogBase<P extends ParameterInfo, M exten
|
||||
|
||||
protected JPanel createParametersPanel(boolean hasTabsInDialog) {
|
||||
myParametersTable = new TableView<ParameterTableModelItemBase<P>>(myParametersTableModel) {
|
||||
|
||||
public void removeEditor() {
|
||||
clearEditorListeners();
|
||||
super.removeEditor();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void editingStopped(ChangeEvent e) {
|
||||
super.editingStopped(e);
|
||||
repaint(); // to update disabled cells background
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public TableCellEditor getCellEditor(final int row, final int column) {
|
||||
final TableCellEditor editor = super.getCellEditor(row, column);
|
||||
private void clearEditorListeners() {
|
||||
final TableCellEditor editor = getCellEditor();
|
||||
if (editor instanceof StringTableCellEditor) {
|
||||
final StringTableCellEditor ed = (StringTableCellEditor)editor;
|
||||
ed.clearListeners();
|
||||
}
|
||||
else if (editor instanceof CodeFragmentTableCellEditorBase) {
|
||||
((CodeFragmentTableCellEditorBase)editor).clearListeners();
|
||||
}
|
||||
}
|
||||
|
||||
public Component prepareEditor(final TableCellEditor editor, final int row, final int column) {
|
||||
final DocumentAdapter listener = new DocumentAdapter() {
|
||||
@Override
|
||||
public void documentChanged(DocumentEvent e) {
|
||||
@@ -400,7 +412,7 @@ public abstract class ChangeSignatureDialogBase<P extends ParameterInfo, M exten
|
||||
else if (editor instanceof CodeFragmentTableCellEditorBase) {
|
||||
((CodeFragmentTableCellEditorBase)editor).addDocumentListener(listener);
|
||||
}
|
||||
return editor;
|
||||
return super.prepareEditor(editor, row, column);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
+20
-6
@@ -73,11 +73,22 @@ public class CopyFilesOrDirectoriesHandler extends CopyHandlerDelegateBase {
|
||||
}
|
||||
|
||||
public static void copyAsFiles(PsiElement[] elements, PsiDirectory defaultTargetDirectory, Project project) {
|
||||
CopyFilesOrDirectoriesDialog dialog = new CopyFilesOrDirectoriesDialog(elements, defaultTargetDirectory, project, false);
|
||||
dialog.show();
|
||||
if (dialog.isOK()) {
|
||||
final String newName = elements.length == 1 ? dialog.getNewName() : null;
|
||||
final PsiDirectory targetDirectory = dialog.getTargetDirectory();
|
||||
PsiDirectory targetDirectory = null;
|
||||
String newName = null;
|
||||
|
||||
if (ApplicationManager.getApplication().isUnitTestMode()) {
|
||||
targetDirectory = defaultTargetDirectory;
|
||||
}
|
||||
else {
|
||||
CopyFilesOrDirectoriesDialog dialog = new CopyFilesOrDirectoriesDialog(elements, defaultTargetDirectory, project, false);
|
||||
dialog.show();
|
||||
if (dialog.isOK()) {
|
||||
newName = elements.length == 1 ? dialog.getNewName() : null;
|
||||
targetDirectory = dialog.getTargetDirectory();
|
||||
}
|
||||
}
|
||||
|
||||
if (targetDirectory != null) {
|
||||
try {
|
||||
for (PsiElement element : elements) {
|
||||
PsiFileSystemItem psiElement = (PsiFileSystemItem)element;
|
||||
@@ -155,7 +166,10 @@ public class CopyFilesOrDirectoriesHandler extends CopyHandlerDelegateBase {
|
||||
* @param newName can be not null only if elements.length == 1
|
||||
* @param targetDirectory
|
||||
*/
|
||||
private static void copyImpl(final PsiElement[] elements, final String newName, final PsiDirectory targetDirectory, final boolean doClone) {
|
||||
private static void copyImpl(@NotNull final PsiElement[] elements,
|
||||
@Nullable final String newName,
|
||||
@NotNull final PsiDirectory targetDirectory,
|
||||
final boolean doClone) {
|
||||
if (doClone && elements.length != 1) {
|
||||
throw new IllegalArgumentException("invalid number of elements to clone:" + elements.length);
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user