Merge branch 'origin/master'

This commit is contained in:
Elizaveta Shashkova
2015-02-11 18:57:37 +03:00
102 changed files with 1419 additions and 421 deletions
+21 -22
View File
@@ -272,7 +272,9 @@ binding.setVariable("classPathLibs", [
binding.setVariable("platformApiModules", [
"analysis-api",
"built-in-server-api",
"core-api",
"diff-api",
"dvcs-api",
"editor-ui-api",
"external-system-api",
@@ -280,60 +282,57 @@ binding.setVariable("platformApiModules", [
"jps-model-api",
"lang-api",
"lvcs-api",
"projectModel-api",
"platform-api",
"projectModel-api",
"remote-servers-agent-rt",
"remote-servers-api",
"structure-view-api",
"usageView",
"diff-api",
"vcs-api",
"vcs-api-core",
"vcs-api",
"vcs-log-api",
"vcs-log-graph-api",
"xdebugger-api",
"remote-servers-api",
"remote-servers-agent-rt",
"xml-analysis-api",
"xml-openapi",
"xml-psi-api",
"xml-structure-view-api",
"built-in-server-api"
"xml-structure-view-api"
])
binding.setVariable("platformImplementationModules", [
"analysis-impl",
"built-in-server",
"core-impl",
"diff-impl",
"dvcs-impl",
"editor-ui-ex",
"images",
"indexing-impl",
"jps-model-impl",
"jps-model-serialization",
"json",
"lang-impl",
"lvcs-impl",
"projectModel-impl",
"platform-impl",
"projectModel-impl",
"protocol-reader-runtime",
"RegExpSupport",
"relaxng",
"remote-servers-impl",
"script-debugger-backend",
"script-debugger-ui",
"smRunner",
"spellchecker",
"structure-view-impl",
"diff-impl",
"testRunner",
"vcs-impl",
"vcs-log-graph",
"vcs-log-impl",
"testRunner",
"smRunner",
"relaxng",
"RegExpSupport",
"spellchecker",
"xdebugger-impl",
"remote-servers-impl",
"xml",
"xml-analysis-impl",
"xml-psi-impl",
"xml-structure-view-impl",
"json",
"protocol-reader-runtime",
"script-debugger-backend",
"script-debugger-ui",
"built-in-server"
"xml"
])
binding.setVariable("layoutMacApp", { String path, String ch, Map args ->
@@ -225,9 +225,8 @@ public class NewProjectUtil {
if (version != null) {
LanguageLevel maxLevel = version.getMaxLanguageLevel();
LanguageLevelProjectExtension extension = LanguageLevelProjectExtension.getInstance(ProjectManager.getInstance().getDefaultProject());
Boolean aDefault = extension.isDefault();
LanguageLevelProjectExtension ext = LanguageLevelProjectExtension.getInstance(project);
if (aDefault != null && aDefault || maxLevel.compareTo(ext.getLanguageLevel()) < 0) {
if (extension.isDefault() || maxLevel.compareTo(ext.getLanguageLevel()) < 0) {
ext.setLanguageLevel(maxLevel);
}
}
@@ -17,6 +17,7 @@ package com.intellij.openapi.roots.ui.configuration;
import com.intellij.openapi.options.ConfigurationException;
import com.intellij.openapi.roots.LanguageLevelModuleExtensionImpl;
import com.intellij.openapi.roots.LanguageLevelProjectExtension;
import javax.swing.*;
import java.awt.*;
@@ -52,6 +53,7 @@ public class ContentEntriesEditor extends JavaContentEntriesEditor {
return getModel().getModuleExtension(LanguageLevelModuleExtensionImpl.class);
}
};
myLanguageLevelConfigurable.addProjectDefault(LanguageLevelProjectExtension.getInstance(myProject).getLanguageLevel());
mainPanel.add(myLanguageLevelConfigurable.createComponent(), BorderLayout.NORTH);
myLanguageLevelConfigurable.reset();
}
@@ -16,16 +16,18 @@
package com.intellij.openapi.roots.ui.configuration;
import com.intellij.core.JavaCoreBundle;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ProjectBundle;
import com.intellij.openapi.projectRoots.JavaSdk;
import com.intellij.openapi.projectRoots.JavaSdkVersion;
import com.intellij.openapi.projectRoots.Sdk;
import com.intellij.openapi.roots.ex.ProjectRootManagerEx;
import com.intellij.ui.ListCellRendererWrapper;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ProjectBundle;
import com.intellij.openapi.roots.LanguageLevelProjectExtension;
import com.intellij.openapi.roots.ex.ProjectRootManagerEx;
import com.intellij.openapi.ui.ComboBox;
import com.intellij.openapi.util.Pair;
import com.intellij.pom.java.LanguageLevel;
import com.intellij.ui.ColoredListCellRendererWrapper;
import com.intellij.ui.SimpleTextAttributes;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
@@ -33,24 +35,30 @@ import javax.swing.*;
/**
* @author ven
*/
@SuppressWarnings("unchecked")
public class LanguageLevelCombo extends ComboBox {
public static final String USE_PROJECT_LANGUAGE_LEVEL = ProjectBundle.message("project.language.level.combo.item");
/** Default from current SDK */
@Nullable
private LanguageLevel myDefaultLevel;
private Pair<String, String> myProjectDefault;
public LanguageLevelCombo() {
for (LanguageLevel level : LanguageLevel.values()) {
addItem(level);
}
setRenderer(new ListCellRendererWrapper() {
setRenderer(new ColoredListCellRendererWrapper() {
@Override
public void customize(final JList list, final Object value, final int index, final boolean selected, final boolean hasFocus) {
protected void doCustomize(JList list, Object value, int index, boolean selected, boolean hasFocus) {
if (value instanceof LanguageLevel) {
setText(((LanguageLevel)value).getPresentableText());
append(((LanguageLevel)value).getPresentableText());
}
else if (value instanceof String) {
setText((String)value);
else if (value instanceof Pair) {
Pair<String, String> pair = (Pair<String, String>)value;
append(pair.first);
if (pair.second != null) {
append(" (" + pair.second + ")", SimpleTextAttributes.GRAYED_ATTRIBUTES);
}
}
}
});
@@ -69,20 +77,19 @@ public class LanguageLevelCombo extends ComboBox {
myDefaultLevel = version.getMaxLanguageLevel();
}
}
String item = null;
Pair<String, String> item = null;
if (myDefaultLevel != null) {
item = JavaCoreBundle.message("default.jdk.level.description", myDefaultLevel.getPresentableText());
item = Pair.create(JavaCoreBundle.message("default.language.level.description"), myDefaultLevel.getPresentableText());
addItem(item);
}
else if (project.isDefault()) {
item = JavaCoreBundle.message("default.language.level.description");
item = Pair.create(JavaCoreBundle.message("default.language.level.description"), null);
addItem(item);
myDefaultLevel = LanguageLevelProjectExtension.getInstance(project).getLanguageLevel();
}
LanguageLevelProjectExtension extension = LanguageLevelProjectExtension.getInstance(project);
Boolean aDefault = extension.isDefault();
if (item != null && aDefault != null && aDefault) {
if (item != null && extension.isDefault()) {
setSelectedItem(item);
}
else {
@@ -102,9 +109,11 @@ public class LanguageLevelCombo extends ComboBox {
@Override
public void setSelectedItem(Object anObject) {
if (anObject == null) {
anObject = USE_PROJECT_LANGUAGE_LEVEL;
}
super.setSelectedItem(anObject);
super.setSelectedItem(anObject == null ? myProjectDefault : anObject);
}
void addProjectDefault(String projectLevel) {
myProjectDefault = Pair.create(ProjectBundle.message("project.language.level.combo.item"), projectLevel);
insertItemAt(myProjectDefault, 0);
}
}
@@ -21,6 +21,7 @@ import com.intellij.openapi.options.UnnamedConfigurable;
import com.intellij.openapi.project.ProjectBundle;
import com.intellij.openapi.roots.LanguageLevelModuleExtensionImpl;
import com.intellij.pom.java.LanguageLevel;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import java.awt.*;
@@ -44,7 +45,6 @@ public abstract class LanguageLevelConfigurable implements UnnamedConfigurable {
getLanguageLevelExtension().setLanguageLevel(languageLevel instanceof LanguageLevel ? (LanguageLevel)languageLevel : null);
}
});
myLanguageLevelCombo.insertItemAt(LanguageLevelCombo.USE_PROJECT_LANGUAGE_LEVEL, 0);
JLabel label = new JLabel(ProjectBundle.message("module.module.language.level"));
label.setLabelFor(myLanguageLevelCombo);
@@ -54,6 +54,7 @@ public abstract class LanguageLevelConfigurable implements UnnamedConfigurable {
new GridBagConstraints(1, 0, 1, 1, 1, 0, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(6, 6, 12, 0), 0, 0));
}
@NotNull
@Override
public JComponent createComponent() {
return myPanel;
@@ -81,4 +82,8 @@ public abstract class LanguageLevelConfigurable implements UnnamedConfigurable {
}
public abstract LanguageLevelModuleExtensionImpl getLanguageLevelExtension();
public void addProjectDefault(LanguageLevel projectDefault) {
myLanguageLevelCombo.addProjectDefault(projectDefault.getPresentableText());
}
}
@@ -22,6 +22,9 @@ package com.intellij.openapi.roots.impl;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.projectRoots.JavaSdk;
import com.intellij.openapi.projectRoots.JavaSdkVersion;
import com.intellij.openapi.projectRoots.Sdk;
import com.intellij.openapi.roots.LanguageLevelProjectExtension;
import com.intellij.openapi.roots.ProjectExtension;
import com.intellij.openapi.util.InvalidDataException;
@@ -30,6 +33,7 @@ import com.intellij.pom.java.LanguageLevel;
import org.jdom.Element;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class LanguageLevelProjectExtensionImpl extends LanguageLevelProjectExtension {
private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.roots.impl.LanguageLevelProjectExtensionImpl");
@@ -76,7 +80,7 @@ import org.jetbrains.annotations.NotNull;
private void writeExternal(final Element element) {
element.setAttribute(LANGUAGE_LEVEL, myLanguageLevel.name());
Boolean aBoolean = isDefault();
Boolean aBoolean = getDefault();
if (aBoolean != null) {
element.setAttribute(DEFAULT_ATTRIBUTE, Boolean.toString(aBoolean));
}
@@ -116,21 +120,35 @@ import org.jetbrains.annotations.NotNull;
LOG.warn("Calling deprecated LanguageLevelProjectExtensionImpl.reloadProjectOnLanguageLevelChange, while project reloading is not needed on language level changes");
}
private void projectSdkChanged(@Nullable Sdk sdk) {
if (isDefault() && sdk != null) {
JavaSdkVersion version = JavaSdk.getInstance().getVersion(sdk);
if (version != null) {
setLanguageLevel(version.getMaxLanguageLevel());
}
}
}
public static class MyProjectExtension extends ProjectExtension {
private final Project myProject;
private final LanguageLevelProjectExtensionImpl myInstance;
public MyProjectExtension(final Project project) {
myProject = project;
myInstance = ((LanguageLevelProjectExtensionImpl)getInstance(project));
}
@Override
public void readExternal(final Element element) throws InvalidDataException {
((LanguageLevelProjectExtensionImpl)getInstance(myProject)).readExternal(element);
myInstance.readExternal(element);
}
@Override
public void writeExternal(final Element element) throws WriteExternalException {
((LanguageLevelProjectExtensionImpl)getInstance(myProject)).writeExternal(element);
myInstance.writeExternal(element);
}
@Override
public void projectSdkChanged(@Nullable Sdk sdk) {
myInstance.projectSdkChanged(sdk);
}
}
}
}
@@ -42,7 +42,7 @@ public abstract class LanguageLevelProjectExtension {
* @return null if the property is not set yet (e.g. after migration).
*/
@Nullable
public Boolean isDefault() {
public Boolean getDefault() {
return myDefault;
}
@@ -50,6 +50,10 @@ public abstract class LanguageLevelProjectExtension {
myDefault = value;
}
public boolean isDefault() {
return myDefault != null && myDefault;
}
public abstract void languageLevelsChanged();
/**
@@ -1,7 +1,6 @@
psi.error.attempt.to.edit.class.file=Cannot modify compiled element
default.language.level.description=JDK default
default.jdk.level.description=JDK default ({0})
default.language.level.description=SDK default
jdk.1.3.language.level.description=1.3 - Plain old Java
jdk.1.4.language.level.description=1.4 - 'assert' keyword
jdk.1.5.language.level.description=5.0 - 'enum' keyword, generics, autoboxing etc.
@@ -155,7 +155,7 @@ public class JavaModuleBuilder extends ModuleBuilder implements SourcePathsBuild
@Override
public List<Module> commit(@NotNull Project project, ModifiableModuleModel model, ModulesProvider modulesProvider) {
LanguageLevelProjectExtension extension = LanguageLevelProjectExtension.getInstance(ProjectManager.getInstance().getDefaultProject());
Boolean aDefault = extension.isDefault();
Boolean aDefault = extension.getDefault();
LanguageLevelProjectExtension instance = LanguageLevelProjectExtension.getInstance(project);
if (aDefault != null && !aDefault) {
instance.setLanguageLevel(extension.getLanguageLevel());
@@ -1453,7 +1453,7 @@ public class JavaMatchingVisitor extends JavaElementVisitor {
if (myMatchingVisitor.getResult()) {
final PsiTypeElement checkType = instanceOf.getCheckType();
if (checkType != null) {
myMatchingVisitor.setResult(matchType(checkType, instanceOf2.getCheckType()));
myMatchingVisitor.setResult(myMatchingVisitor.match(checkType, instanceOf2.getCheckType()));
}
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
* Copyright 2000-2015 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.
@@ -83,7 +83,7 @@ public class DaemonProgressIndicator extends AbstractProgressIndicatorBase imple
}
@TestOnly
static void setDebug(boolean debug) {
public static void setDebug(boolean debug) {
DaemonProgressIndicator.debug = debug;
}
@@ -200,6 +200,7 @@ public class SmartPointerManagerImpl extends SmartPointerManager {
if (!file.isValid()) {
LOG.error("Invalid element:" + file);
}
processQueue();
SmartPsiFileRangePointerImpl pointer = new SmartPsiFileRangePointerImpl(file, ProperTextRange.create(range));
initPointer(pointer, file.getViewProvider().getVirtualFile());
@@ -24,10 +24,7 @@ import org.jetbrains.annotations.Nullable;
import java.io.*;
import java.lang.reflect.Modifier;
import java.lang.reflect.Proxy;
import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.*;
/**
* This class provides a generic graph infrastructure with ability to store particular data. The main purpose is to
@@ -48,6 +45,7 @@ public class DataNode<T> implements Serializable {
private static final Logger LOG = Logger.getInstance(DataNode.class);
@NotNull private final List<DataNode<?>> myChildren = ContainerUtilRt.newArrayList();
@NotNull private final List<DataNode<?>> myChildrenView = Collections.unmodifiableList(myChildren);
@NotNull private final Key<T> myKey;
private transient T myData;
@@ -73,18 +71,6 @@ public class DataNode<T> implements Serializable {
return result;
}
@NotNull
public <T> DataNode<T> createOrReplaceChild(@NotNull Key<T> key, @NotNull T data) {
for (Iterator<DataNode<?>> iterator = myChildren.iterator(); iterator.hasNext(); ) {
DataNode<?> child = iterator.next();
if (child.getKey().equals(key)) {
iterator.remove();
break;
}
}
return createChild(key, data);
}
@NotNull
public Key<T> getKey() {
return myKey;
@@ -237,7 +223,7 @@ public class DataNode<T> implements Serializable {
@NotNull
public Collection<DataNode<?>> getChildren() {
return myChildren;
return myChildrenView;
}
private void writeObject(ObjectOutputStream out) throws IOException {
@@ -304,7 +290,7 @@ public class DataNode<T> implements Serializable {
public void clear(boolean removeFromGraph) {
if (removeFromGraph && myParent != null) {
for (Iterator<DataNode<?>> iterator = myParent.getChildren().iterator(); iterator.hasNext(); ) {
for (Iterator<DataNode<?>> iterator = myParent.myChildren.iterator(); iterator.hasNext(); ) {
DataNode<?> dataNode = iterator.next();
if (System.identityHashCode(dataNode) == System.identityHashCode(this)) {
iterator.remove();
@@ -316,4 +302,17 @@ public class DataNode<T> implements Serializable {
myRawData = null;
myChildren.clear();
}
public DataNode<T> graphCopy() {
return nodeCopy(this, null);
}
private static <T> DataNode<T> nodeCopy(@NotNull DataNode<T> dataNode, @Nullable DataNode<?> newParent) {
DataNode<T> copy = new DataNode<T>(dataNode.myKey, dataNode.myData, newParent);
copy.myRawData = dataNode.myRawData;
for (DataNode<?> child : dataNode.myChildren) {
copy.addChild(nodeCopy(child, copy));
}
return copy;
}
}
@@ -138,7 +138,7 @@ public class ExternalProjectsDataStorage implements SettingsSavingComponent {
InternalExternalProjectInfo merged = new InternalExternalProjectInfo(
projectSystemId,
projectPath,
externalProjectStructure
externalProjectStructure != null ? externalProjectStructure.graphCopy() : null
);
merged.setLastImportTimestamp(lastImportTimestamp);
merged.setLastSuccessfulImportTimestamp(lastSuccessfulImportTimestamp);
@@ -15,53 +15,33 @@
*/
package com.intellij.psi.codeStyle;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.util.Collections;
import javax.swing.Icon;
import java.util.List;
public class EditorNotificationInfo {
private String myTitle;
private Icon myIcon;
private List<LabelWithAction> myLabelsWithActions = ContainerUtil.newArrayList();
public EditorNotificationInfo(@NotNull String title,
@NotNull LabelWithAction firstLabel,
@Nullable LabelWithAction... otherLabels)
{
myTitle = title;
myLabelsWithActions.add(firstLabel);
if (otherLabels != null) {
Collections.addAll(myLabelsWithActions, otherLabels);
}
}
public EditorNotificationInfo(@NotNull String title,
@NotNull Icon icon,
@NotNull LabelWithAction firstLabel,
@Nullable LabelWithAction... otherLabels)
{
this(title, firstLabel, otherLabels);
myIcon = icon;
}
public abstract class EditorNotificationInfo {
@NotNull
public List<LabelWithAction> getLabelAndActions() {
return myLabelsWithActions;
}
public abstract List<ActionLabelData> getLabelAndActions();
@NotNull
public abstract String getTitle();
@Nullable
public Icon getIcon() {
return myIcon;
return null;
}
@NotNull
public String getTitle() {
return myTitle;
public static class ActionLabelData {
public final String label;
public final Runnable action;
public ActionLabelData(@NotNull String label, @NotNull Runnable action) {
this.label = label;
this.action = action;
}
}
}
@@ -429,7 +429,7 @@ public class DaemonListeners implements Disposable {
@Override
public void beforeWriteActionStart(Object action) {
myDaemonWasRunning = myDaemonCodeAnalyzer.isRunning();
if (!myDaemonWasRunning || isUnderIgnoredAction(action)) return; // we'll restart in writeActionFinished()
if (!myDaemonWasRunning) return; // we'll restart in writeActionFinished()
stopDaemon(true, "Write action start");
}
@@ -242,7 +242,7 @@ public class FileStructurePopup implements Disposable {
public void show() {
//final long time = System.currentTimeMillis();
JComponent panel = createCenterPanel();
new MnemonicHelper().register(panel);
MnemonicHelper.init(panel);
boolean shouldSetWidth = DimensionService.getInstance().getSize(getDimensionServiceKey(), myProject) == null;
myPopup = JBPopupFactory.getInstance().createComponentPopupBuilder(panel, null)
.setTitle(myTitle)
@@ -897,7 +897,7 @@ public abstract class ChooseByNameBase {
myTextPopup.setSize(bounds.getSize());
myTextPopup.setLocation(bounds.getLocation());
new MnemonicHelper().register(myTextFieldPanel);
MnemonicHelper.init(myTextFieldPanel);
if (myProject != null && !myProject.isDefault()) {
DaemonCodeAnalyzer.getInstance(myProject).disableUpdateByTimer(myTextPopup);
}
@@ -0,0 +1,122 @@
/*
* Copyright 2000-2015 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.internal.statistic.editor;
import com.intellij.codeInsight.CodeInsightSettings;
import com.intellij.codeInsight.editorActions.SmartBackspaceMode;
import com.intellij.internal.statistic.CollectUsagesException;
import com.intellij.internal.statistic.UsagesCollector;
import com.intellij.internal.statistic.beans.GroupDescriptor;
import com.intellij.internal.statistic.beans.UsageDescriptor;
import com.intellij.openapi.editor.ex.EditorSettingsExternalizable;
import com.intellij.openapi.editor.impl.softwrap.SoftWrapAppliancePlaces;
import com.intellij.openapi.editor.richcopy.settings.RichCopySettings;
import com.intellij.openapi.util.Comparing;
import org.jetbrains.annotations.NotNull;
import java.util.HashSet;
import java.util.Set;
class EditorSettingsStatisticsCollector extends UsagesCollector {
@NotNull
@Override
public GroupDescriptor getGroupId() {
return GroupDescriptor.create("Editor");
}
@NotNull
@Override
public Set<UsageDescriptor> getUsages() throws CollectUsagesException {
Set<UsageDescriptor> set = new HashSet<UsageDescriptor>();
EditorSettingsExternalizable es = EditorSettingsExternalizable.getInstance();
addIfDiffers(set, es.isVirtualSpace(), false, "caretAfterLineEnd");
addIfDiffers(set, es.isCaretInsideTabs(), false, "caretInsideTabs");
addIfDiffers(set, es.isAdditionalPageAtBottom(), false, "virtualSpaceAtFileBottom");
addIfDiffers(set, es.isUseSoftWraps(SoftWrapAppliancePlaces.MAIN_EDITOR), false, "softWraps");
addIfDiffers(set, es.isUseSoftWraps(SoftWrapAppliancePlaces.CONSOLE), false, "softWraps.console");
addIfDiffers(set, es.isUseCustomSoftWrapIndent(), false, "softWraps.relativeIndent");
addIfDiffers(set, es.isAllSoftWrapsShown(), false, "softWraps.showAll");
addIfDiffers(set, es.getStripTrailingSpaces(), EditorSettingsExternalizable.STRIP_TRAILING_SPACES_CHANGED, "stripTrailingSpaces");
addIfDiffers(set, es.isEnsureNewLineAtEOF(), false, "ensureNewlineAtEOF");
addIfDiffers(set, es.isShowQuickDocOnMouseOverElement(), false, "quickDocOnMouseHover");
addIfDiffers(set, es.isBlinkCaret(), true, "nonBlinkingCaret");
addIfDiffers(set, es.isBlockCursor(), false, "blockCaret");
addIfDiffers(set, es.isRightMarginShown(), true, "noRightMargin");
addIfDiffers(set, es.isLineNumbersShown(), false, "lineNumbers");
addIfDiffers(set, es.isFoldingOutlineShown(), true, "noFoldingOutline");
addIfDiffers(set, es.isWhitespacesShown() && es.isLeadingWhitespacesShown(), false, "showLeadingWhitespace");
addIfDiffers(set, es.isWhitespacesShown() && es.isInnerWhitespacesShown(), false, "showInnerWhitespace");
addIfDiffers(set, es.isWhitespacesShown() && es.isTrailingWhitespacesShown(), false, "showTrailingWhitespace");
addIfDiffers(set, es.isIndentGuidesShown(), true, "noIndentGuides");
addIfDiffers(set, es.isSmoothScrolling(), true, "noAnimatedScroll");
addIfDiffers(set, es.isDndEnabled(), false, "dragNDrop");
addIfDiffers(set, es.isWheelFontChangeEnabled(), false, "wheelZoom");
addIfDiffers(set, es.isMouseClickSelectionHonorsCamelWords(), true, "mouseNoCamel");
addIfDiffers(set, es.isVariableInplaceRenameEnabled(), true, "noInplaceRename");
addIfDiffers(set, es.isPreselectRename(), true, "noPreselectOnRename");
addIfDiffers(set, es.isShowInlineLocalDialog(), true, "noInlineDialog");
addIfDiffers(set, es.isRefrainFromScrolling(), false, "minimizeScrolling");
addIfDiffers(set, es.getOptions().SHOW_REFORMAT_DIALOG, true, "noReformatDialog");
addIfDiffers(set, es.getOptions().SHOW_OPIMIZE_IMPORTS_DIALOG, true, "noOptimizeImportsDialog");
addIfDiffers(set, es.isSmartHome(), true, "noSmartHome");
addIfDiffers(set, es.isCamelWords(), false, "camelWords");
RichCopySettings rcs = RichCopySettings.getInstance();
addIfDiffers(set, rcs.isEnabled(), true, "noRichCopy");
CodeInsightSettings cis = CodeInsightSettings.getInstance();
addIfDiffers(set, cis.AUTO_POPUP_PARAMETER_INFO, true, "noParameterAutoPopup");
addIfDiffers(set, cis.AUTO_POPUP_JAVADOC_INFO, false, "javadocAutoPopup");
addIfDiffers(set, cis.AUTO_POPUP_COMPLETION_LOOKUP, true, "noCompletionAutoPopup");
addIfDiffers(set, cis.COMPLETION_CASE_SENSITIVE, CodeInsightSettings.FIRST_LETTER, "completionCaseSensitivity");
addIfDiffers(set, cis.SELECT_AUTOPOPUP_SUGGESTIONS_BY_CHARS, false, "autoPopupCharComplete");
addIfDiffers(set, cis.AUTOCOMPLETE_ON_CODE_COMPLETION, true, "noAutoCompleteBasic");
addIfDiffers(set, cis.AUTOCOMPLETE_ON_SMART_TYPE_COMPLETION, true, "noAutoCompleteSmart");
addIfDiffers(set, cis.SHOW_FULL_SIGNATURES_IN_PARAMETER_INFO, false, "parameterInfoFullSignature");
addIfDiffers(set, cis.getBackspaceMode(), SmartBackspaceMode.AUTOINDENT, "smartBackspace");
addIfDiffers(set, cis.SMART_INDENT_ON_ENTER, true, "noIndentOnEnter");
addIfDiffers(set, cis.INSERT_BRACE_ON_ENTER, true, "noBraceOnEnter");
addIfDiffers(set, cis.JAVADOC_STUB_ON_ENTER, true, "noJavadocOnEnter");
addIfDiffers(set, cis.SMART_END_ACTION, true, "noSmartEnd");
addIfDiffers(set, cis.JAVADOC_GENERATE_CLOSING_TAG, true, "noAutoCloseJavadocTags");
addIfDiffers(set, cis.SURROUND_SELECTION_ON_QUOTE_TYPED, false, "surroundByQuoteOrBrace");
addIfDiffers(set, cis.AUTOINSERT_PAIR_BRACKET, true, "noPairBracketAutoInsert");
addIfDiffers(set, cis.AUTOINSERT_PAIR_QUOTE, true, "noPairQuoteAutoInsert");
addIfDiffers(set, cis.REFORMAT_BLOCK_ON_RBRACE, true, "noReformatOnRBrace");
addIfDiffers(set, cis.REFORMAT_ON_PASTE, CodeInsightSettings.INDENT_EACH_LINE, "reformatOnPaste");
addIfDiffers(set, cis.ADD_IMPORTS_ON_PASTE, CodeInsightSettings.ASK, "importsOnPaste");
addIfDiffers(set, cis.HIGHLIGHT_BRACES, true, "noBracesHighlight");
addIfDiffers(set, cis.HIGHLIGHT_SCOPE, false, "scopeHighlight");
addIfDiffers(set, cis.HIGHLIGHT_IDENTIFIER_UNDER_CARET, true, "noIdentifierUnderCaretHighlight");
addIfDiffers(set, cis.OPTIMIZE_IMPORTS_ON_THE_FLY, false, "autoOptimizeImports");
addIfDiffers(set, cis.ADD_UNAMBIGIOUS_IMPORTS_ON_THE_FLY, false, "autoAddImports");
return set;
}
private static void addIfDiffers(Set<UsageDescriptor> set, boolean value, boolean defaultValue, String featureId) {
if (value != defaultValue) {
set.add(new UsageDescriptor(featureId, 1));
}
}
private static void addIfDiffers(Set<UsageDescriptor> set, Object value, Object defaultValue, String featureIdPrefix) {
if (!Comparing.equal(value, defaultValue)) {
set.add(new UsageDescriptor(featureIdPrefix + "." + value, 1));
}
}
}
@@ -77,7 +77,12 @@ public abstract class ProfilesConfigurableComboBox extends JPanel {
mySaveListener.setDelegate(inputValidator);
mySubmitNameComponent.setText(initialValue);
myCardLayout.show(myComboBoxPanel, EDIT_CARD);
mySubmitNameComponent.requestFocus();
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
mySubmitNameComponent.requestFocus();
}
});
}
public void reset(final Collection<Profile> profiles) {
@@ -27,7 +27,7 @@ import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiFile;
import com.intellij.psi.codeStyle.*;
import com.intellij.testFramework.LightVirtualFile;
import com.intellij.ui.EditorNotifications;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.WeakList;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -35,6 +35,8 @@ import org.jetbrains.annotations.TestOnly;
import java.util.List;
import static com.intellij.psi.codeStyle.EditorNotificationInfo.*;
/**
* @author Rustam Vishnyakov
*/
@@ -82,22 +84,21 @@ public class DetectableIndentOptionsProvider extends FileIndentOptionsProvider {
@NotNull CommonCodeStyleSettings.IndentOptions userOptions,
@NotNull CommonCodeStyleSettings.IndentOptions detectedOptions)
{
NotificationLabels labels = getNotificationLabels(userOptions, detectedOptions);
final NotificationLabels labels = getNotificationLabels(userOptions, detectedOptions);
final Editor editor = fileEditor instanceof TextEditor ? ((TextEditor)fileEditor).getEditor() : null;
if (labels == null || editor == null) return null;
LabelWithAction okAction = new LabelWithAction(
ActionLabelData okAction = new ActionLabelData(
ApplicationBundle.message("code.style.indents.detector.accept"),
new Runnable() {
@Override
public void run() {
setAccepted(file);
EditorNotifications.getInstance(project).updateAllNotifications();
}
}
);
LabelWithAction disableForSingleFile = new LabelWithAction(
ActionLabelData disableForSingleFile = new ActionLabelData(
labels.revertToOldSettingsLabel,
new Runnable() {
@Override
@@ -106,24 +107,35 @@ public class DetectableIndentOptionsProvider extends FileIndentOptionsProvider {
if (editor instanceof EditorEx) {
((EditorEx)editor).reinitSettings();
}
EditorNotifications.getInstance(project).updateAllNotifications();
}
}
);
LabelWithAction showSettings = new LabelWithAction(
ActionLabelData showSettings = new ActionLabelData(
ApplicationBundle.message("code.style.indents.detector.show.settings"),
new Runnable() {
@Override
public void run() {
ShowSettingsUtilImpl.showSettingsDialog(project, "preferences.sourceCode",
ApplicationBundle.message("settings.code.style.general.autodetect.indents"));
EditorNotifications.getInstance(project).updateAllNotifications();
}
}
);
return new EditorNotificationInfo(labels.title, okAction, disableForSingleFile, showSettings);
final List<ActionLabelData> actions = ContainerUtil.newArrayList(okAction, disableForSingleFile, showSettings);
return new EditorNotificationInfo() {
@NotNull
@Override
public List<ActionLabelData> getLabelAndActions() {
return actions;
}
@NotNull
@Override
public String getTitle() {
return labels.title;
}
};
}
@Nullable
@@ -32,6 +32,8 @@ import com.intellij.util.Processor;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import static com.intellij.psi.codeStyle.EditorNotificationInfo.*;
/**
* @author Rustam Vishnyakov
*/
@@ -77,8 +79,15 @@ public class DetectedIndentOptionsNotificationProvider extends EditorNotificatio
if (info.getIcon() != null) {
panel.icon(info.getIcon());
}
for (LabelWithAction action : info.getLabelAndActions()) {
panel.createActionLabel(action.label, action.action);
for (final ActionLabelData actionLabelData : info.getLabelAndActions()) {
Runnable onClickAction = new Runnable() {
@Override
public void run() {
actionLabelData.action.run();
EditorNotifications.getInstance(project).updateAllNotifications();
}
};
panel.createActionLabel(actionLabelData.label, onClickAction);
}
return panel;
}
@@ -0,0 +1,79 @@
/*
* Copyright 2000-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.openapi;
import javax.swing.CellRendererPane;
import java.awt.*;
import java.awt.event.ContainerEvent;
import java.awt.event.ContainerListener;
/**
* @author Sergey.Malenkov
*/
final class MnemonicContainerListener implements ContainerListener {
void addTo(Component component) {
if (component == null || component instanceof CellRendererPane) {
return;
}
if (component instanceof Container) {
addTo((Container)component);
}
MnemonicWrapper.getWrapper(component);
}
void removeFrom(Component component) {
if (component instanceof Container) {
removeFrom((Container)component);
}
}
@Override
public void componentAdded(ContainerEvent event) {
addTo(event.getChild());
}
@Override
public void componentRemoved(ContainerEvent event) {
removeFrom(event.getChild());
}
private void addTo(Container container) {
if (!isAddedTo(container)) {
container.addContainerListener(this);
for (Component component : container.getComponents()) {
addTo(component);
}
}
}
private void removeFrom(Container container) {
if (isAddedTo(container)) {
container.removeContainerListener(this);
for (Component component : container.getComponents()) {
removeFrom(component);
}
}
}
private boolean isAddedTo(Container container) {
for (ContainerListener listener : container.getContainerListeners()) {
if (listener == this) {
return true;
}
}
return false;
}
}
@@ -42,6 +42,7 @@ import java.util.Map;
* @since 5.1
*/
public class MnemonicHelper extends ComponentTreeWatcher {
private static final MnemonicContainerListener LISTENER = new MnemonicContainerListener();
private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.MnemonicHelper");
private Map<Integer, String> myMnemonics = null;
@@ -57,6 +58,11 @@ public class MnemonicHelper extends ComponentTreeWatcher {
};
@NonNls public static final String TEXT_CHANGED_PROPERTY = "text";
/**
* @see #init(Component)
* @deprecated do not use this object as a tree watcher
*/
@Deprecated
public MnemonicHelper() {
super(ArrayUtil.EMPTY_CLASS_ARRAY);
}
@@ -143,4 +149,18 @@ public class MnemonicHelper extends ComponentTreeWatcher {
"alt pressed " + mnemonic;
return CustomShortcutSet.fromString(shortcut);
}
/**
* Initializes mnemonics support for the specified component and for its children if needed.
*
* @param component the root component of the hierarchy
*/
public static void init(Component component) {
if (Registry.is("ide.mnemonic.helper.old") || Registry.is("ide.checkDuplicateMnemonics")) {
new MnemonicHelper().register(component);
}
else {
LISTENER.addTo(component);
}
}
}
@@ -1242,7 +1242,7 @@ public abstract class DialogWrapper {
southSection.add(south, BorderLayout.SOUTH);
}
new MnemonicHelper().register(root);
MnemonicHelper.init(root);
if (!postponeValidation()) {
startTrackingValidation();
}
@@ -30,7 +30,7 @@ public class AuthenticationDialog extends DialogWrapper {
super(component, true);
setTitle(title);
new MnemonicHelper().register(getContentPane());
MnemonicHelper.init(getContentPane());
panel = new AuthenticationPanel(description, login, password, rememberPassword);
final Window window = getWindow();
@@ -45,7 +45,7 @@ public class AuthenticationDialog extends DialogWrapper {
super(JOptionPane.getRootFrame(), true);
setTitle(title);
new MnemonicHelper().register(getContentPane());
MnemonicHelper.init(getContentPane());
panel = new AuthenticationPanel(description, login, password, rememberPassword);
final Window window = getWindow();
@@ -57,7 +57,7 @@ public class ImportOldConfigsPanel extends JDialog {
}
private void init() {
new MnemonicHelper().register(getContentPane());
MnemonicHelper.init(getContentPane());
ButtonGroup group = new ButtonGroup();
group.add(myRbDoNotImport);
@@ -198,9 +198,13 @@ public class EditorActionUtil {
}
}
int newSpacesEnd = lineStart + buf.length();
if (newCaretOffset >= spacesEnd) {
newCaretOffset += buf.length() - (spacesEnd - lineStart);
}
else if (newCaretOffset >= lineStart && newCaretOffset < spacesEnd && newCaretOffset > newSpacesEnd) {
newCaretOffset = newSpacesEnd;
}
if (buf.length() > 0) {
if (spacesEnd > lineStart) {
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
* Copyright 2000-2015 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.
@@ -46,6 +46,7 @@ import com.intellij.util.ArrayUtil;
import com.intellij.util.Consumer;
import com.intellij.util.IconUtil;
import com.intellij.util.containers.HashMap;
import com.intellij.util.ui.JBUI;
import com.intellij.util.ui.UIUtil;
import com.intellij.util.ui.update.MergingUpdateQueue;
import com.intellij.util.ui.update.UiNotifyConnector;
@@ -55,7 +56,6 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
import javax.swing.event.TreeExpansionEvent;
import javax.swing.event.TreeExpansionListener;
import javax.swing.event.TreeSelectionEvent;
@@ -286,7 +286,7 @@ public class FileChooserDialogImpl extends DialogWrapper implements FileChooserD
final JLabel label = new JLabel(description);
label.setBorder(BorderFactory.createCompoundBorder(
new SideBorder(UIUtil.getPanelBackground().darker(), SideBorder.BOTTOM),
BorderFactory.createEmptyBorder(0, 5, 10, 5)));
JBUI.Borders.empty(0, 5, 10, 5)));
return label;
}
@@ -297,7 +297,7 @@ public class FileChooserDialogImpl extends DialogWrapper implements FileChooserD
Disposer.register(myDisposable, myUiUpdater);
new UiNotifyConnector(panel, myUiUpdater);
panel.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0));
panel.setBorder(JBUI.Borders.empty());
createTree();
@@ -316,7 +316,7 @@ public class FileChooserDialogImpl extends DialogWrapper implements FileChooserD
toolbarPanel.add(myTextFieldAction, BorderLayout.EAST);
myPathTextFieldWrapper = new JPanel(new BorderLayout());
myPathTextFieldWrapper.setBorder(new EmptyBorder(0, 0, 2, 0));
myPathTextFieldWrapper.setBorder(JBUI.Borders.emptyBottom(2));
myPathTextField = new FileTextFieldImpl.Vfs(
FileChooserFactoryImpl.getMacroMap(), getDisposable(),
new LocalFsFinder.FileChooserFilter(myChooserDescriptor, myFileSystemTree)) {
@@ -344,7 +344,7 @@ public class FileChooserDialogImpl extends DialogWrapper implements FileChooserD
JScrollPane scrollPane = ScrollPaneFactory.createScrollPane(myFileSystemTree.getTree());
//scrollPane.setBorder(BorderFactory.createLineBorder(new Color(148, 154, 156)));
panel.add(scrollPane, BorderLayout.CENTER);
panel.setPreferredSize(new Dimension(400, 400));
panel.setPreferredSize(JBUI.size(400));
panel.add(new JLabel(
@@ -566,7 +566,7 @@ public final class UpdateChecker {
String bundledJdk = "";
String jdkMacRedist = System.getProperty("idea.java.redist");
if (jdkMacRedist != null && jdkMacRedist.lastIndexOf("jdk-bundled") >= 0 ){
if (jdkMacRedist != null && jdkMacRedist.lastIndexOf("jdk-bundled") >= 0) {
bundledJdk = "jdk-bundled".equals(jdkMacRedist) ? "-jdk-bundled" : "-custom-jdk-bundled";
}
@@ -66,7 +66,7 @@ public final class FloatingDecorator extends JDialog {
FloatingDecorator(final IdeFrameImpl owner,final WindowInfoImpl info,final InternalDecorator internalDecorator){
super(owner,internalDecorator.getToolWindow().getId());
new MnemonicHelper().register(getContentPane());
MnemonicHelper.init(getContentPane());
myInternalDecorator=internalDecorator;
setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE);
@@ -109,7 +109,7 @@ public class IdeFrameImpl extends JFrame implements IdeFrameEx, DataProvider {
setFocusTraversalPolicy(layoutFocusTraversalPolicy);
setupCloseAction();
new MnemonicHelper().register(this);
MnemonicHelper.init(this);
myBalloonLayout = new BalloonLayoutImpl(myRootPane, new Insets(8, 8, 8, 8));
@@ -21,6 +21,7 @@ import com.intellij.openapi.actionSystem.ToggleAction;
import com.intellij.openapi.project.DumbAware;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ProjectManager;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.wm.WindowManager;
import com.intellij.util.BitUtil;
import org.jetbrains.annotations.NotNull;
@@ -121,6 +122,12 @@ public class ProjectWindowAction extends ToggleAction implements DumbAware {
}
final JFrame projectFrame = WindowManager.getInstance().getFrame(project);
final int frameState = projectFrame.getExtendedState();
if (SystemInfo.isMac && (projectFrame.getExtendedState() & Frame.ICONIFIED) != 0) {
// On Mac minimized window should not be restored this way
return;
}
if (BitUtil.isSet(frameState, Frame.ICONIFIED)) {
// restore the frame if it is minimized
projectFrame.setExtendedState(frameState ^ Frame.ICONIFIED);
@@ -113,7 +113,7 @@ public class FlatWelcomeFrame extends JFrame implements IdeFrame {
myBalloonLayout = new BalloonLayoutImpl(rootPane, new JBInsets(8, 8, 8, 8));
WelcomeFrame.setupCloseAction(this);
new MnemonicHelper().register(this);
MnemonicHelper.init(this);
Disposer.register(ApplicationManager.getApplication(), new Disposable() {
@Override
public void dispose() {
@@ -80,7 +80,7 @@ public class WelcomeFrame extends JFrame implements IdeFrame {
myScreen = screen;
setupCloseAction(this);
new MnemonicHelper().register(this);
MnemonicHelper.init(this);
myScreen.setupFrame(this);
Disposer.register(ApplicationManager.getApplication(), new Disposable() {
@Override
@@ -32,6 +32,8 @@ html.inspections.check.image.width.fix.message=Set width value to {0}
html.inspections.check.image.height.message=Original image height is {0}
html.inspections.check.image.height.fix.message=Set height value to {0}
html.inspections.check.deprecated.tag=Deprecated HTML tag
html.intentions.insert.image.size=Insert background-image size
html.intentions.update.image.size=Update background-image size
unwrap.enclosing.tag.name.action.name=Remove Enclosing Tag {0}
jsp.inspections.group.name=JSP Inspections
# color dialog
@@ -218,7 +220,7 @@ select.xsd.schema.dialog.title=Select XSD Schema
emmet.title=Emmet
emmet.update.tag.title=Update tag with Emmet
emmet.configuration.title=Emmet
emmet.enable.label=&Enable XML Emmet
emmet.enable.label=&Enable XML/HTML Emmet
emmet.filters.enabled.by.default=Filters enabled by default
emmet.enable.preview=Enable &abbreviation preview
emmet.expand.abbreviation.with=Expand &abbreviation with
@@ -813,6 +813,7 @@
<statistics.usagesCollector implementation="com.intellij.execution.impl.statistics.RunConfigurationTypeUsagesCollector"/>
<statistics.usagesCollector implementation="com.intellij.execution.impl.statistics.TemporaryRunConfigurationTypeUsagesCollector"/>
<statistics.usagesCollector implementation="com.intellij.openapi.fileTypes.FileTypeUsagesCollector"/>
<statistics.usagesCollector implementation="com.intellij.internal.statistic.editor.EditorSettingsStatisticsCollector"/>
<renamePsiElementProcessor implementation="com.intellij.refactoring.rename.RenamePsiFileProcessor" order="last"/>
<renameInputValidator implementation="com.intellij.refactoring.rename.RenameToIgnoredDirectoryFileInputValidator" order="last"/>
@@ -22,6 +22,7 @@ import com.intellij.openapi.editor.ex.EditorEx;
import com.intellij.openapi.editor.impl.AbstractEditorTest;
import com.intellij.openapi.ide.CopyPasteManager;
import com.intellij.testFramework.EditorTestUtil;
import com.intellij.testFramework.LightPlatformCodeInsightTestCase;
import com.intellij.testFramework.TestFileType;
import java.awt.datatransfer.StringSelection;
@@ -187,4 +188,10 @@ public class EditorActionTest extends AbstractEditorTest {
"blah <selection>blah\n" +
"blah bl<caret></selection>ah");
}
public void testCaretComesBeforeTextOnUnindent() throws IOException {
initText(" <caret> text");
unindent();
checkResultByText(" <caret>text");
}
}
@@ -55,7 +55,9 @@ public class ProgressIndicatorTest extends LightPlatformTestCase {
}
catch(ProcessCanceledException ex) {
boolean isInternal = SystemProperties.getBooleanProperty("idea.is.internal", false);
assertTrue("Should have no stackframe", isInternal ? ex.getStackTrace().length != 0 : ex.getStackTrace().length == 0);
boolean isTest = SystemProperties.getBooleanProperty("idea.is.unit.test", false);
boolean hasStackFrame = ex.getStackTrace().length != 0;
assertTrue("Should have no stackframe", (isInternal || isTest) == hasStackFrame);
}
}
@@ -112,7 +114,7 @@ public class ProgressIndicatorTest extends LightPlatformTestCase {
}, "", false, getProject(), null, "");
long averageDelay = PlatformTestUtil.averageAmongMedians(times.toNativeArray(), 5);
System.out.println("averageDelay = " + averageDelay);
assertTrue(averageDelay < ProgressManagerImpl.CHECK_CANCELED_DELAY_MILLIS*3);
assertTrue(averageDelay < CoreProgressManager.CHECK_CANCELED_DELAY_MILLIS *3);
}
public void testProgressIndicatorUtilsScheduleWithWriteActionPriority() throws Throwable {
@@ -133,7 +135,7 @@ public class ProgressIndicatorTest extends LightPlatformTestCase {
});
UIUtil.dispatchAllInvocationEvents();
while (!insideReadAction.get()) {
;
}
ApplicationManager.getApplication().runWriteAction(new Runnable() {
@Override
@@ -316,11 +318,11 @@ public class ProgressIndicatorTest extends LightPlatformTestCase {
ProgressManager.getInstance().executeProcessUnderProgress(new Runnable() {
@Override
public void run() {
assertFalse(ProgressManagerImpl.threadsUnderCanceledIndicator.contains(Thread.currentThread()));
assertFalse(CoreProgressManager.threadsUnderCanceledIndicator.contains(Thread.currentThread()));
ProgressIndicator indicator = ProgressIndicatorProvider.getGlobalProgressIndicator();
assertTrue(indicator != null && !indicator.isCanceled());
indicator.cancel();
assertTrue(ProgressManagerImpl.threadsUnderCanceledIndicator.contains(Thread.currentThread()));
assertTrue(CoreProgressManager.threadsUnderCanceledIndicator.contains(Thread.currentThread()));
assertTrue(indicator.isCanceled());
final ProgressIndicatorEx nested = new ProgressIndicatorBase();
nested.addStateDelegate(new ProgressIndicatorStub() {
@@ -332,7 +334,7 @@ public class ProgressIndicatorTest extends LightPlatformTestCase {
ProgressManager.getInstance().executeProcessUnderProgress(new Runnable() {
@Override
public void run() {
assertFalse(ProgressManagerImpl.threadsUnderCanceledIndicator.contains(Thread.currentThread()));
assertFalse(CoreProgressManager.threadsUnderCanceledIndicator.contains(Thread.currentThread()));
ProgressIndicator indicator2 = ProgressIndicatorProvider.getGlobalProgressIndicator();
assertTrue(indicator2 != null && !indicator2.isCanceled());
assertSame(indicator2, nested);
@@ -343,7 +345,7 @@ public class ProgressIndicatorTest extends LightPlatformTestCase {
ProgressIndicator indicator3 = ProgressIndicatorProvider.getGlobalProgressIndicator();
assertSame(indicator, indicator3);
assertTrue(ProgressManagerImpl.threadsUnderCanceledIndicator.contains(Thread.currentThread()));
assertTrue(CoreProgressManager.threadsUnderCanceledIndicator.contains(Thread.currentThread()));
}
}, new EmptyProgressIndicator());
assertFalse(checkCanceledCalled);
@@ -386,10 +388,10 @@ public class ProgressIndicatorTest extends LightPlatformTestCase {
ProgressManager.getInstance().executeProcessUnderProgress(new Runnable() {
@Override
public void run() {
assertFalse(ProgressManagerImpl.threadsUnderCanceledIndicator.contains(Thread.currentThread()));
assertFalse(CoreProgressManager.threadsUnderCanceledIndicator.contains(Thread.currentThread()));
assertTrue(!progress.isCanceled());
progress.cancel();
assertTrue(ProgressManagerImpl.threadsUnderCanceledIndicator.contains(Thread.currentThread()));
assertTrue(CoreProgressManager.threadsUnderCanceledIndicator.contains(Thread.currentThread()));
assertTrue(progress.isCanceled());
while (true) { // wait for PCE
ProgressManager.checkCanceled();
@@ -37,7 +37,10 @@ public abstract class ProjectRootManagerEx extends ProjectRootManager {
public abstract void clearScopesCachesForModules();
/**
* @see ProjectRootManagerEx#addProjectJdkListener(ProjectJdkListener)
* @see ProjectRootManagerEx#removeProjectJdkListener(ProjectJdkListener)
*/
public interface ProjectJdkListener extends EventListener {
void projectJdkChanged();
}
@@ -504,7 +504,7 @@ public abstract class ModuleManagerImpl extends ModuleManager implements Project
return myModuleModel.getModules();
}
private Module[] myCachedSortedModules = null;
private volatile Module[] myCachedSortedModules = null;
@Override
@NotNull
@@ -523,7 +523,7 @@ public abstract class ModuleManagerImpl extends ModuleManager implements Project
return myModuleModel.findModuleByName(name);
}
private Comparator<Module> myCachedModuleComparator = null;
private volatile Comparator<Module> myCachedModuleComparator = null;
@Override
@NotNull
@@ -602,7 +602,7 @@ public abstract class ModuleManagerImpl extends ModuleManager implements Project
class ModuleModelImpl implements ModifiableModuleModel {
final Map<String, Module> myPathToModule = new LinkedHashMap<String, Module>(new EqualityPolicy.ByHashingStrategy<String>(FilePathHashingStrategy.create()));
private Module[] myModulesCache;
private volatile Module[] myModulesCache;
private final List<Module> myModulesToDispose = new ArrayList<Module>();
private final Map<Module, String> myModuleToNewName = new HashMap<Module, String>();
@@ -21,8 +21,12 @@
package com.intellij.openapi.roots;
import com.intellij.openapi.extensions.ExtensionPointName;
import com.intellij.openapi.projectRoots.Sdk;
import com.intellij.openapi.util.JDOMExternalizable;
import org.jetbrains.annotations.Nullable;
public abstract class ProjectExtension implements JDOMExternalizable{
public static final ExtensionPointName<ProjectExtension> EP_NAME = ExtensionPointName.create("com.intellij.projectExtension");
public void projectSdkChanged(@Nullable Sdk sdk) {}
}
@@ -231,12 +231,20 @@ public class ProjectRootManagerImpl extends ProjectRootManagerEx implements Proj
myProjectSdkName = sdk.getName();
myProjectSdkType = sdk.getSdkType().getName();
}
projectJdkChanged();
}
private void projectJdkChanged() {
mergeRootsChangesDuring(new Runnable() {
@Override
public void run() {
myProjectJdkEventDispatcher.getMulticaster().projectJdkChanged();
}
});
Sdk sdk = getProjectSdk();
for (ProjectExtension extension : Extensions.getExtensions(ProjectExtension.EP_NAME, myProject)) {
extension.projectSdkChanged(sdk);
}
}
@Override
@@ -244,12 +252,7 @@ public class ProjectRootManagerImpl extends ProjectRootManagerEx implements Proj
ApplicationManager.getApplication().assertWriteAccessAllowed();
myProjectSdkName = name;
mergeRootsChangesDuring(new Runnable() {
@Override
public void run() {
myProjectJdkEventDispatcher.getMulticaster().projectJdkChanged();
}
});
projectJdkChanged();
}
@Override
@@ -246,7 +246,7 @@ libraries.node.text.module=Libraries contain classes that add up various functio
\
To attach a library to a module, select that module, click the Dependencies tab, click Add and specify the library location.
jdks.node.display.name=SDKs
project.language.level.combo.item=<Use project language level>
project.language.level.combo.item=Project default
add.action.name=Add new ...
add.new.jdk.text=Add New SDK
add.new.global.library.text=New Global Library
@@ -2476,6 +2476,14 @@ public class StructuralSearchTest extends StructuralSearchTestCase {
"@Deprecated\n" +
"package one.two;";
assertEquals("Find annotation on package statement", 1, findMatchesCount(source4, "@'_Annotation", true));
final String source5 ="class A {" +
" boolean a(Object o) {" +
" return o instanceof @HH String;" +
" }" +
"}";
assertEquals("Find annotation on instanceof expression", 1, findMatchesCount(source5, "'_a instanceof @HH String"));
assertEquals("Match annotation correctly on instanceof expression", 0, findMatchesCount(source5, "'_a instanceof @GG String"));
}
public void testBoxingAndUnboxing() {
@@ -1624,7 +1624,7 @@ public class CodeInsightTestFixtureImpl extends BaseFixture implements CodeInsig
DaemonCodeAnalyzerImpl codeAnalyzer = (DaemonCodeAnalyzerImpl)DaemonCodeAnalyzer.getInstance(project);
TextEditor textEditor = TextEditorProvider.getInstance().getTextEditor(editor);
ProcessCanceledException exception = null;
for (int i = 0; i < 100; i++) {
for (int i = 0; i < 1000; i++) {
try {
List<HighlightInfo> infos = codeAnalyzer.runPasses(file, editor.getDocument(), textEditor, toIgnore, canChangeDocument, null);
infos.addAll(DaemonCodeAnalyzerEx.getInstanceEx(project).getFileLevelHighlights(project, file));
@@ -54,6 +54,9 @@ ide.popup.resizable.border.sensitivity=4
ide.consumeKnownToolkitBugs=true
ide.highlight.match.in.selected.only=true
ide.lazyIconLoading=true
ide.mnemonic.helper.old=true
ide.mnemonic.helper.old.restartRequired=true
ide.mnemonic.helper.old.description=Use new algorithm of mnemonics processing
ide.checkDuplicateMnemonics=false
ide.checkDuplicateMnemonics.description=Check for duplicate mnemonics.
ide.dnd.textHints=false
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
* Copyright 2000-2015 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.
@@ -18,7 +18,7 @@ package com.intellij.openapi.progress;
import com.intellij.util.SystemProperties;
public class ProcessCanceledException extends RuntimeException {
private static final boolean ourHasStackTraces = SystemProperties.getBooleanProperty("idea.is.internal", false);
private static final boolean ourHasStackTraces = SystemProperties.getBooleanProperty("idea.is.internal", false) || SystemProperties.getBooleanProperty("idea.is.unit.test", false);
public ProcessCanceledException() {
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
* Copyright 2000-2015 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 Restarter {
public static boolean isSupported() {
if (getRestartCode() != 0) return true;
if (SystemInfo.isWindows) return true;
if (SystemInfo.isWindows) return new File(PathManager.getBinPath(), "restarter.exe").exists();
if (SystemInfo.isMac) return PathManager.getHomePath().contains(".app");
return false;
}
@@ -29,6 +29,4 @@ public interface PrintElementGenerator {
@NotNull
PrintElementWithGraphElement toPrintElementWithGraphElement(@NotNull PrintElement printElement);
void invalidate();
}
@@ -142,8 +142,12 @@ public class VisibleGraphImpl<CommitId> implements VisibleGraph<CommitId> {
targetId = edge.getTargetId();
}
if (edge.getType().isNormalEdge()) {
if (printElementType == DOWN_ARROW) targetId = convertToNodeId(edge.getDownNodeIndex());
else targetId = convertToNodeId(edge.getUpNodeIndex());
if (printElementType == DOWN_ARROW) {
targetId = convertToNodeId(edge.getDownNodeIndex());
}
else {
targetId = convertToNodeId(edge.getUpNodeIndex());
}
}
if (targetId == null) return null;
@@ -198,7 +202,14 @@ public class VisibleGraphImpl<CommitId> implements VisibleGraph<CommitId> {
CommitId commitToJump = null;
Integer nodeId = answer.getCommitToJump();
if (nodeId != null) commitToJump = myPermanentGraph.getPermanentCommitsInfo().getCommitId(nodeId);
return new GraphAnswerImpl<CommitId>(answer.getCursorToSet(), commitToJump, answer.getGraphUpdater());
final Runnable graphUpdater = answer.getGraphUpdater();
return new GraphAnswerImpl<CommitId>(answer.getCursorToSet(), commitToJump, graphUpdater == null ? null : new Runnable() {
@Override
public void run() {
graphUpdater.run();
updatePrintElementGenerator();
}
});
}
}
@@ -203,12 +203,6 @@ public class PrintElementGeneratorImpl extends AbstractPrintElementGenerator {
result.add(new SimpleRowElement(edge, SimplePrintElement.Type.UP_ARROW, position));
}
@Override
public void invalidate() {
myEdgesInRowGenerator.invalidate();
cache.clear();
}
private boolean edgeIsVisibleInRow(@NotNull GraphEdge edge, int visibleRowIndex) {
Pair<Integer, Integer> normalEdge = LinearGraphUtils.asNormalEdge(edge);
if (normalEdge == null) // e.d. edge is special. See addSpecialEdges
@@ -17,19 +17,15 @@ import com.intellij.vcs.log.data.VcsLogFilterer;
import com.intellij.vcs.log.data.VcsLogUiProperties;
import com.intellij.vcs.log.data.VisiblePack;
import com.intellij.vcs.log.graph.PermanentGraph;
import com.intellij.vcs.log.graph.VisibleGraph;
import com.intellij.vcs.log.graph.actions.GraphAction;
import com.intellij.vcs.log.graph.actions.GraphAnswer;
import com.intellij.vcs.log.impl.VcsLogImpl;
import com.intellij.vcs.log.ui.frame.MainFrame;
import com.intellij.vcs.log.ui.frame.VcsLogGraphTable;
import com.intellij.vcs.log.ui.tables.GraphTableModel;
import gnu.trove.TIntHashSet;
import gnu.trove.TIntProcedure;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.TableModel;
import java.awt.*;
import java.util.ArrayList;
@@ -79,7 +75,7 @@ public class VcsLogUiImpl implements VcsLogUi, Disposable {
ApplicationManager.getApplication().assertIsDispatchThread();
PermanentGraph<Integer> previousPermGraph = myVisiblePack.getPermanentGraph();
TIntHashSet previouslySelected = getSelectedCommits();
VcsLogGraphTable.Selection previousSelection = getTable().getSelection();
myVisiblePack = pack;
boolean permGraphChanged = previousPermGraph != myVisiblePack.getPermanentGraph();
@@ -90,7 +86,7 @@ public class VcsLogUiImpl implements VcsLogUi, Disposable {
}
else {
currentModel.setVisiblePack(myVisiblePack);
restoreSelection(currentModel, myVisiblePack.getVisibleGraph(), previouslySelected, getTable());
previousSelection.restore(myVisiblePack.getVisibleGraph());
}
getTable().setPaintBusy(false);
@@ -105,42 +101,6 @@ public class VcsLogUiImpl implements VcsLogUi, Disposable {
return myMainFrame;
}
private static void restoreSelection(@NotNull GraphTableModel newModel,
@NotNull VisibleGraph<Integer> newVisibleGraph,
@NotNull TIntHashSet previouslySelectedCommits,
@NotNull final VcsLogGraphTable table) {
TIntHashSet rowsToSelect = findNewRowsToSelect(newModel, newVisibleGraph, previouslySelectedCommits);
rowsToSelect.forEach(new TIntProcedure() {
@Override
public boolean execute(int row) {
table.addRowSelectionInterval(row, row);
return true;
}
});
}
@NotNull
private static TIntHashSet findNewRowsToSelect(@NotNull GraphTableModel newModel,
@NotNull VisibleGraph<Integer> visibleGraph,
@NotNull TIntHashSet selectedHashes) {
TIntHashSet rowsToSelect = new TIntHashSet();
if (newModel.getRowCount() == 0) {
// this should have been covered by facade.getVisibleCommitCount,
// but if the table is empty (no commits match the filter), the GraphFacade is not updated, because it can't handle it
// => it has previous values set.
return rowsToSelect;
}
for (int row = 0;
row < visibleGraph.getVisibleCommitCount() && rowsToSelect.size() < selectedHashes.size();
row++) { //stop iterating if found all hashes
int commit = visibleGraph.getRowInfo(row).getCommit();
if (selectedHashes.contains(commit)) {
rowsToSelect.add(row);
}
}
return rowsToSelect;
}
public void repaintUI() {
myMainFrame.getGraphTable().repaint();
}
@@ -156,7 +116,7 @@ public class VcsLogUiImpl implements VcsLogUi, Disposable {
public void run() {
assert updater != null : "Action:" + title + "\nController: " + myVisiblePack.getVisibleGraph().getActionController() + "\nAnswer:" + answer;
updater.run();
handleAnswer(answer, true);
getTable().handleAnswer(answer, true, null);
}
});
}
@@ -226,31 +186,6 @@ public class VcsLogUiImpl implements VcsLogUi, Disposable {
return future;
}
public void handleAnswer(@Nullable GraphAnswer<Integer> answer, boolean dataCouldChange) {
if (dataCouldChange) {
((AbstractTableModel)(getTable().getModel())).fireTableDataChanged();
}
repaintUI();
if (answer == null) {
return;
}
if (answer.getCursorToSet() != null) {
myMainFrame.getGraphTable().setCursor(answer.getCursorToSet());
}
if (answer.getCommitToJump() != null) {
int row = myVisiblePack.getVisibleGraph().getVisibleRowIndex(answer.getCommitToJump());
if (row >= 0) {
myMainFrame.getGraphTable().jumpToRow(row);
}
else {
// TODO wait for the full log and then jump
}
}
}
private <T> void jumpTo(@NotNull final T commitId,
@NotNull final PairFunction<GraphTableModel, T, Integer> rowGetter,
@NotNull final SettableFuture<Boolean> future) {
@@ -327,23 +262,6 @@ public class VcsLogUiImpl implements VcsLogUi, Disposable {
return myColorManager;
}
@NotNull
public TIntHashSet getSelectedCommits() {
int[] selectedRows = getTable().getSelectedRows();
return getCommitsAtRows(myVisiblePack.getVisibleGraph(), selectedRows);
}
@NotNull
private static TIntHashSet getCommitsAtRows(@NotNull VisibleGraph<Integer> graph, int[] rows) {
TIntHashSet commits = new TIntHashSet();
for (int row : rows) {
if (row < graph.getVisibleCommitCount()) {
commits.add(graph.getRowInfo(row).getCommit());
}
}
return commits;
}
public void applyFiltersAndUpdateUi() {
VcsLogFilterCollection filters = myMainFrame.getFilterUi().getFilters();
myFilterer.onFiltersChange(filters);
@@ -38,10 +38,7 @@ import com.intellij.vcs.log.VcsFullCommitDetails;
import com.intellij.vcs.log.VcsLogHighlighter;
import com.intellij.vcs.log.data.VcsLogDataHolder;
import com.intellij.vcs.log.data.VisiblePack;
import com.intellij.vcs.log.graph.ColorGenerator;
import com.intellij.vcs.log.graph.PrintElement;
import com.intellij.vcs.log.graph.RowInfo;
import com.intellij.vcs.log.graph.RowType;
import com.intellij.vcs.log.graph.*;
import com.intellij.vcs.log.graph.actions.GraphAction;
import com.intellij.vcs.log.graph.actions.GraphAnswer;
import com.intellij.vcs.log.printer.idea.GraphCellPainter;
@@ -52,11 +49,14 @@ import com.intellij.vcs.log.ui.VcsLogUiImpl;
import com.intellij.vcs.log.ui.render.GraphCommitCell;
import com.intellij.vcs.log.ui.render.GraphCommitCellRender;
import com.intellij.vcs.log.ui.tables.GraphTableModel;
import gnu.trove.TIntHashSet;
import gnu.trove.TIntProcedure;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import sun.swing.table.DefaultTableCellHeaderRenderer;
import javax.swing.*;
import javax.swing.event.CellEditorListener;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.event.TableModelEvent;
@@ -65,9 +65,7 @@ import java.awt.*;
import java.awt.datatransfer.StringSelection;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.*;
import java.util.List;
import static com.intellij.vcs.log.printer.idea.PrintParameters.HEIGHT_CELL;
@@ -85,6 +83,7 @@ public class VcsLogGraphTable extends JBTable implements TypeSafeDataProvider, C
@NotNull private final VcsLogUiImpl myUI;
private final VcsLogDataHolder myLogDataHolder;
private final GraphCommitCellRender myGraphCommitCellRender;
private final MyDummyTableCellEditor myDummyEditor = new MyDummyTableCellEditor();
private boolean myColumnsSizeInitialized = false;
@@ -364,6 +363,103 @@ public class VcsLogGraphTable extends JBTable implements TypeSafeDataProvider, C
});
}
public void handleAnswer(@Nullable GraphAnswer<Integer> answer, boolean dataCouldChange, @Nullable Selection previousSelection) {
if (dataCouldChange) {
GraphTableModel graphTableModel = (GraphTableModel)getModel();
graphTableModel.fireTableDataChanged();
// since fireTableDataChanged clears selection we restore it here
if (previousSelection != null) {
previousSelection.restore(myDataPack.getVisibleGraph());
}
}
myUI.repaintUI(); // in case of repaintUI doing something more than just repainting this table in some distant future
if (answer == null) {
return;
}
if (answer.getCursorToSet() != null) {
setCursor(answer.getCursorToSet());
}
if (answer.getCommitToJump() != null) {
Integer row = myDataPack.getVisibleGraph().getVisibleRowIndex(answer.getCommitToJump());
if (row != null && row >= 0) {
jumpToRow(row);
}
// TODO wait for the full log and then jump
}
}
private GraphTableModel getGraphTableModel() {
return (GraphTableModel)getModel();
}
@NotNull
public Selection getSelection() {
return new Selection();
}
public class Selection {
private final TIntHashSet myCommits;
public Selection() {
myCommits = getCommitsAtRows(myDataPack.getVisibleGraph(), getSelectedRows());
}
public void restore(@NotNull VisibleGraph<Integer> newVisibleGraph) {
TIntHashSet rowsToSelect = findNewRowsToSelect(getGraphTableModel(), newVisibleGraph, myCommits);
if (!rowsToSelect.isEmpty()) {
rowsToSelect.forEach(new TIntProcedure() {
@Override
public boolean execute(int row) {
addRowSelectionInterval(row, row);
return true;
}
});
}
// sometimes commits that were selected are now collapsed
// currently in this case selection disappears
// in the future we need to create a method in LinearGraphController that allows to calculate visible commit for our commit
// or answer from collapse action could return a map that gives us some information about what commits were collapsed and where
}
@NotNull
private TIntHashSet findNewRowsToSelect(@NotNull GraphTableModel newModel,
@NotNull VisibleGraph<Integer> visibleGraph,
@NotNull TIntHashSet selectedHashes) {
TIntHashSet rowsToSelect = new TIntHashSet();
if (newModel.getRowCount() == 0) {
// this should have been covered by facade.getVisibleCommitCount,
// but if the table is empty (no commits match the filter), the GraphFacade is not updated, because it can't handle it
// => it has previous values set.
return rowsToSelect;
}
for (int row = 0;
row < visibleGraph.getVisibleCommitCount() && rowsToSelect.size() < selectedHashes.size();
row++) { //stop iterating if found all hashes
int commit = visibleGraph.getRowInfo(row).getCommit();
if (selectedHashes.contains(commit)) {
rowsToSelect.add(row);
}
}
return rowsToSelect;
}
@NotNull
private TIntHashSet getCommitsAtRows(@NotNull VisibleGraph<Integer> graph, int[] rows) {
TIntHashSet commits = new TIntHashSet();
for (int row : rows) {
if (row < graph.getVisibleCommitCount()) {
commits.add(graph.getRowInfo(row).getCommit());
}
}
return commits;
}
}
private class MyHeaderMouseAdapter extends MouseAdapter {
@Override
public void mouseMoved(MouseEvent e) {
@@ -423,11 +519,13 @@ public class VcsLogGraphTable extends JBTable implements TypeSafeDataProvider, C
Collection<? extends PrintElement> printElements = myDataPack.getVisibleGraph().getRowInfo(row).getPrintElements();
PrintElement printElement = myGraphCellPainter.mouseOver(printElements, point.x, point.y);
Selection previousSelection = getSelection();
GraphAnswer<Integer> answer =
myDataPack.getVisibleGraph().getActionController().performAction(new GraphAction.GraphActionImpl(printElement, actionType));
myUI.handleAnswer(answer, actionType == GraphAction.Type.MOUSE_CLICK && printElement != null);
handleAnswer(answer, actionType == GraphAction.Type.MOUSE_CLICK && printElement != null, previousSelection);
}
private boolean isAboveLink(MouseEvent e) {
return myLinkListener.getTagAt(e) != null;
}
@@ -532,6 +630,13 @@ public class VcsLogGraphTable extends JBTable implements TypeSafeDataProvider, C
}
}
@Override
public TableCellEditor getCellEditor() {
// this fixes selection problems by prohibiting selection when user clicks on graph (CellEditor does that)
// what is fun about this code is that if you set cell editor in constructor with setCellEditor method it would not work
return myDummyEditor;
}
private class StringCellRenderer extends ColoredTableCellRenderer {
@Override
protected void customizeCellRenderer(JTable table, Object value, boolean selected, boolean hasFocus, int row, int column) {
@@ -577,4 +682,55 @@ public class VcsLogGraphTable extends JBTable implements TypeSafeDataProvider, C
}
}
private class MyDummyTableCellEditor implements TableCellEditor {
@Override
public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
return null;
}
@Override
public Object getCellEditorValue() {
return null;
}
@Override
public boolean isCellEditable(EventObject anEvent) {
return false;
}
@Override
public boolean shouldSelectCell(EventObject anEvent) {
if (!(anEvent instanceof MouseEvent)) return true;
MouseEvent e = (MouseEvent)anEvent;
int row = PositionUtil.getRowIndex(e.getPoint());
if (row > getRowCount() - 1) {
return false;
}
Point point = calcPoint4Graph(e.getPoint());
Collection<? extends PrintElement> printElements = myDataPack.getVisibleGraph().getRowInfo(row).getPrintElements();
PrintElement printElement = myGraphCellPainter.mouseOver(printElements, point.x, point.y);
return printElement == null;
}
@Override
public boolean stopCellEditing() {
return false;
}
@Override
public void cancelCellEditing() {
}
@Override
public void addCellEditorListener(CellEditorListener l) {
}
@Override
public void removeCellEditorListener(CellEditorListener l) {
}
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
* Copyright 2000-2015 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.
@@ -36,7 +36,7 @@ public interface XValueNode extends Obsolescent {
* If value text exceeds this constant it's recommended to truncate it and use {@link #setFullValueEvaluator(XFullValueEvaluator)} method
* to provide full value
*/
int MAX_VALUE_LENGTH = 100;
int MAX_VALUE_LENGTH = 1000;
/**
* Setup presentation of the value
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2013 JetBrains s.r.o.
* Copyright 2000-2015 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.
@@ -40,6 +40,7 @@ import com.intellij.xdebugger.frame.XFullValueEvaluator;
import com.intellij.xdebugger.impl.breakpoints.XBreakpointBase;
import com.intellij.xdebugger.impl.breakpoints.ui.BreakpointsDialogFactory;
import com.intellij.xdebugger.impl.breakpoints.ui.XLightBreakpointPropertiesPanel;
import com.intellij.xdebugger.impl.ui.tree.nodes.XValueNodeImpl;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -127,8 +128,8 @@ public class DebuggerUIUtil {
JComponent component,
@Nullable final FullValueEvaluationCallbackImpl callback) {
ComponentPopupBuilder builder = JBPopupFactory.getInstance().createComponentPopupBuilder(component, null);
builder.setResizable(true).setAlpha(1)
.setMovable(true)
builder.setResizable(true)
.setMovable(true)
.setDimensionServiceKey(project, FULL_VALUE_POPUP_DIMENSION_KEY, false)
.setRequestFocus(false);
if (callback != null) {
@@ -328,4 +329,14 @@ public class DebuggerUIUtil {
return myObsolete.get();
}
}
@Nullable
public static String getNodeRawValue(@NotNull XValueNodeImpl valueNode) {
if (valueNode.getValueContainer() instanceof XValueTextProvider) {
return ((XValueTextProvider)valueNode.getValueContainer()).getValueText();
}
else {
return valueNode.getRawValue();
}
}
}
@@ -15,18 +15,24 @@
*/
package com.intellij.xdebugger.impl.ui.tree;
import com.intellij.openapi.project.Project;
import com.intellij.ui.AbstractExpandableItemsHandler;
import com.intellij.ui.ColoredTreeCellRenderer;
import com.intellij.ui.SimpleTextAttributes;
import com.intellij.util.ui.JBInsets;
import com.intellij.xdebugger.XDebuggerBundle;
import com.intellij.xdebugger.frame.ImmediateFullValueEvaluator;
import com.intellij.xdebugger.frame.XDebuggerTreeNodeHyperlink;
import com.intellij.xdebugger.impl.ui.DebuggerUIUtil;
import com.intellij.xdebugger.impl.ui.tree.nodes.XDebuggerTreeNode;
import com.intellij.xdebugger.impl.ui.tree.nodes.XValueNodeImpl;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import javax.swing.tree.TreePath;
import java.awt.*;
import java.awt.event.MouseEvent;
/**
* @author nik
@@ -37,6 +43,8 @@ class XDebuggerTreeRenderer extends ColoredTreeCellRenderer {
private int myLinkOffset;
private int myLinkWidth;
private final MyLongTextHyperlink myLongTextLink = new MyLongTextHyperlink();
public XDebuggerTreeRenderer() {
Insets myLinkIpad = myLink.getIpad();
myLink.setIpad(new JBInsets(myLinkIpad.top, 0, myLinkIpad.bottom, myLinkIpad.right));
@@ -56,18 +64,38 @@ class XDebuggerTreeRenderer extends ColoredTreeCellRenderer {
XDebuggerTreeNode node = (XDebuggerTreeNode)value;
node.appendToComponent(this);
setIcon(node.getIcon());
Rectangle treeVisibleRect = tree.getVisibleRect();
TreePath path = tree.getPathForRow(row);
int rowX = path != null ? ((XDebuggerTree.LinkTreeUI)tree.getUI()).getRowX(row, path.getPathCount() - 1) : 0;
if (myHaveLink) {
Dimension linkSize = myLink.getPreferredSize();
myLinkWidth = linkSize.width;
myLink.setBounds(0, 0, linkSize.width, linkSize.height);
Rectangle treeVisibleRect = tree.getVisibleRect();
TreePath path = tree.getPathForRow(row);
int rowX = path != null ? ((XDebuggerTree.LinkTreeUI)tree.getUI()).getRowX(row, path.getPathCount() - 1) : 0;
myLinkOffset = Math.min(super.getPreferredSize().width, treeVisibleRect.x + treeVisibleRect.width - myLinkWidth - rowX);
setupLinkDimensions(treeVisibleRect, rowX);
}
else {
if (rowX + super.getPreferredSize().width > treeVisibleRect.x + treeVisibleRect.width) {
// text does not fit visible area - show link
if (node instanceof XValueNodeImpl) {
final String rawValue = DebuggerUIUtil.getNodeRawValue((XValueNodeImpl)node);
if (rawValue != null) {
myLongTextLink.setupComponent(rawValue, ((XDebuggerTree)tree).getProject());
append(myLongTextLink.getLinkText(), myLongTextLink.getTextAttributes(), myLongTextLink);
setupLinkDimensions(treeVisibleRect, rowX);
myLinkWidth = 0;
}
}
}
}
putClientProperty(AbstractExpandableItemsHandler.DISABLE_EXPANDABLE_HANDLER, myHaveLink ? true : null);
}
private void setupLinkDimensions(Rectangle treeVisibleRect, int rowX) {
Dimension linkSize = myLink.getPreferredSize();
myLinkWidth = linkSize.width;
myLink.setBounds(0, 0, linkSize.width, linkSize.height);
myLinkOffset = Math.min(super.getPreferredSize().width, treeVisibleRect.x + treeVisibleRect.width - myLinkWidth - rowX);
}
@Override
public void append(@NotNull String fragment, @NotNull SimpleTextAttributes attributes, Object tag) {
if (tag instanceof XDebuggerTreeNodeHyperlink && ((XDebuggerTreeNodeHyperlink)tag).alwaysOnScreen()) {
@@ -131,4 +159,29 @@ class XDebuggerTreeRenderer extends ColoredTreeCellRenderer {
super.doPaint(g);
}
}
private static class MyLongTextHyperlink extends XDebuggerTreeNodeHyperlink {
private String myText;
private Project myProject;
public MyLongTextHyperlink() {
super(XDebuggerBundle.message("node.test.show.full.value"));
}
public void setupComponent(String text, Project project) {
myText = text;
myProject = project;
}
@Override
public boolean alwaysOnScreen() {
return true;
}
@Override
public void onClick(MouseEvent event) {
DebuggerUIUtil.showValuePopup(new ImmediateFullValueEvaluator(myText), event, myProject, null);
event.consume();
}
}
}
@@ -23,7 +23,7 @@ import com.intellij.openapi.util.text.StringUtil;
import com.intellij.ui.AppUIUtil;
import com.intellij.util.SmartList;
import com.intellij.xdebugger.frame.XFullValueEvaluator;
import com.intellij.xdebugger.impl.ui.XValueTextProvider;
import com.intellij.xdebugger.impl.ui.DebuggerUIUtil;
import com.intellij.xdebugger.impl.ui.tree.XDebuggerTree;
import com.intellij.xdebugger.impl.ui.tree.nodes.HeadlessValueEvaluationCallback;
import com.intellij.xdebugger.impl.ui.tree.nodes.WatchMessageNode;
@@ -76,14 +76,7 @@ public abstract class XFetchValueActionBase extends AnAction {
XValueNodeImpl valueNode = (XValueNodeImpl)node;
XFullValueEvaluator fullValueEvaluator = valueNode.getFullValueEvaluator();
if (fullValueEvaluator == null || !fullValueEvaluator.isShowValuePopup()) {
String rawValue;
if (valueNode.getValueContainer() instanceof XValueTextProvider) {
rawValue = ((XValueTextProvider)valueNode.getValueContainer()).getValueText();
}
else {
rawValue = valueNode.getRawValue();
}
valueCollector.add(StringUtil.notNullize(rawValue));
valueCollector.add(StringUtil.notNullize(DebuggerUIUtil.getNodeRawValue(valueNode)));
}
else {
new CopyValueEvaluationCallback(valueNode, valueCollector).startFetchingValue(fullValueEvaluator);
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
* Copyright 2000-2015 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,8 +17,10 @@ package com.siyeh.ipp.modifiers;
import com.intellij.codeInsight.intention.LowPriorityAction;
import com.intellij.openapi.application.AccessToken;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.psi.*;
import com.intellij.psi.codeStyle.CodeStyleManager;
import com.intellij.psi.impl.source.resolve.JavaResolveUtil;
import com.intellij.psi.search.searches.OverridingMethodsSearch;
import com.intellij.psi.search.searches.ReferencesSearch;
@@ -60,11 +62,12 @@ abstract class ModifierIntention extends Intention implements LowPriorityAction
return;
}
final MultiMap<PsiElement, String> conflicts = checkForConflicts(member);
final Project project = member.getProject();
final boolean conflictsDialogOK;
if (conflicts.isEmpty()) {
conflictsDialogOK = true;
} else {
final ConflictsDialog conflictsDialog = new ConflictsDialog(member.getProject(), conflicts, new Runnable() {
final ConflictsDialog conflictsDialog = new ConflictsDialog(project, conflicts, new Runnable() {
@Override
public void run() {
final AccessToken token = start();
@@ -80,6 +83,13 @@ abstract class ModifierIntention extends Intention implements LowPriorityAction
}
if (conflictsDialogOK) {
modifierList.setModifierProperty(getModifier(), true);
final PsiElement whitespace = PsiParserFacade.SERVICE.getInstance(project).createWhiteSpaceFromText(" ");
final PsiElement sibling = modifierList.getNextSibling();
if (sibling instanceof PsiWhiteSpace) {
sibling.replace(whitespace);
CodeStyleManager.getInstance(project).reformatRange(member, modifierList.getTextOffset() + 1,
modifierList.getNextSibling().getTextOffset());
}
}
}
@@ -0,0 +1,5 @@
class AnnotatedMember {
@SuppressWarnings("ALL")
String <caret>s;
}
@@ -0,0 +1,5 @@
class AnnotatedMember {
@SuppressWarnings("ALL")
private String s;
}
@@ -27,6 +27,7 @@ public class MakePrivateIntentionTest extends IPPTestCase {
public void testMyClass() { assertIntentionNotAvailable(); }
public void testMyInterface() { assertIntentionNotAvailable(); }
public void testMethod() { doTest(); }
public void testAnnotatedMember() { doTest(); }
@Override
protected String getRelativePath() {
@@ -701,6 +701,7 @@ public class GroovyTypeCheckVisitor extends BaseInspectionVisitor {
}
private void registerCannotApplyError(@NotNull String invokedText, @NotNull CallInfo info) {
if (info.getArgumentTypes() == null) return;
final String typesString = buildArgTypesList(info.getArgumentTypes());
registerError(
info.getElementToHighlight(),
@@ -839,12 +840,14 @@ public class GroovyTypeCheckVisitor extends BaseInspectionVisitor {
public void visitCastExpression(GrTypeCastExpression expression) {
super.visitCastExpression(expression);
if (expression.getCastTypeElement() == null) return;
final PsiType expectedType = expression.getCastTypeElement().getType();
final GrExpression operand = expression.getOperand();
if (operand == null) return;
final PsiType actualType = operand.getType();
if (actualType == null) return;
if (expression.getCastTypeElement() == null) return;
final PsiType expectedType = expression.getCastTypeElement().getType();
final ConversionResult result = TypesUtil.canCast(expectedType, actualType, expression);
if (result == ConversionResult.OK) return;
final ProblemHighlightType highlightType = result == ConversionResult.ERROR
@@ -16,6 +16,7 @@
package org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.groovy.lang.psi.api.types.GrTypeElement;
import org.jetbrains.annotations.NotNull;
import com.intellij.psi.PsiElement;
@@ -26,6 +27,7 @@ import com.intellij.psi.PsiElement;
public interface GrTypeCastExpression extends GrExpression {
GrTypeElement getCastTypeElement();
@Nullable
GrExpression getOperand();
@NotNull
@@ -20,6 +20,7 @@ import com.intellij.lang.ASTNode;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiType;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes;
import org.jetbrains.plugins.groovy.lang.psi.GroovyElementVisitor;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
@@ -58,6 +59,7 @@ public class GrTypeCastExpressionImpl extends GrExpressionImpl implements GrType
}
@Override
@Nullable
public GrExpression getOperand() {
return findExpressionChild(this);
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2013 JetBrains s.r.o.
* Copyright 2000-2015 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.
@@ -50,12 +50,11 @@ public class TypeCustomizerInspection extends BaseInspection {
return new BaseInspectionVisitor() {
@Override
public void visitFile(GroovyFileBase file) {
if (!CompilerConfiguration.getInstance(file.getProject()).isResourceFile(file.getVirtualFile())) {
if (fileSeemsToBeTypeCustomizer(file)) {
final LocalQuickFix[] fixes = {new AddToResourceFix(file)};
final String message = GroovyInspectionBundle.message("type.customizer.is.not.marked.as.a.resource.file");
registerError(file, message, fixes, ProblemHighlightType.GENERIC_ERROR_OR_WARNING);
}
CompilerConfiguration configuration = CompilerConfiguration.getInstance(file.getProject());
if (configuration != null && !configuration.isResourceFile(file.getVirtualFile()) && fileSeemsToBeTypeCustomizer(file)) {
final LocalQuickFix[] fixes = {new AddToResourceFix(file)};
final String message = GroovyInspectionBundle.message("type.customizer.is.not.marked.as.a.resource.file");
registerError(file, message, fixes, ProblemHighlightType.GENERIC_ERROR_OR_WARNING);
}
}
};
@@ -33,7 +33,10 @@ import com.intellij.psi.util.CachedValuesManager;
import com.intellij.psi.xml.XmlFile;
import com.intellij.psi.xml.XmlTag;
import com.intellij.reference.SoftLazyValue;
import com.intellij.util.Function;
import com.intellij.util.IncorrectOperationException;
import com.intellij.util.SmartList;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.MultiMap;
import gnu.trove.THashMap;
import org.jetbrains.annotations.NonNls;
@@ -47,29 +50,54 @@ import java.util.*;
* Date: 7/26/11
*/
public class XmlPropertiesFileImpl extends XmlPropertiesFile {
private static final Key<CachedValue<PropertiesFile>> KEY = Key.create("xml properties file");
private final XmlFile myFile;
private final SoftLazyValue<MultiMap<String, IProperty>> myPropertiesMap = new SoftLazyValue<MultiMap<String, IProperty>>() {
private final SoftLazyValue<Info> myInfo = new SoftLazyValue<Info>() {
@NotNull
@Override
protected MultiMap<String, IProperty> compute() {
XmlTag rootTag = myFile.getRootTag();
if (rootTag == null) {
return MultiMap.emptyInstance();
}
XmlTag[] entries = rootTag.findSubTags("entry");
MultiMap<String, IProperty> map = new MultiMap<String, IProperty>();
for (XmlTag entry : entries) {
XmlProperty property = new XmlProperty(entry, XmlPropertiesFileImpl.this);
map.putValue(property.getKey(), property);
}
return map;
protected Info compute() {
return new Info();
}
};
private class Info {
private final MultiMap<String, IProperty> myPropertiesMap = MultiMap.create();
private List<IProperty> myPropertiesOrder;
private boolean mySorted;
public Info() {
XmlTag rootTag = myFile.getRootTag();
final List<IProperty> propertiesOrder = new ArrayList<IProperty>();
if (rootTag != null) {
XmlTag[] entries = rootTag.findSubTags("entry");
for (XmlTag entry : entries) {
XmlProperty property = new XmlProperty(entry, XmlPropertiesFileImpl.this);
propertiesOrder.add(property);
myPropertiesMap.putValue(property.getKey(), property);
}
}
mySorted = PropertiesImplUtil.isAlphaSorted(propertiesOrder);
myPropertiesOrder = mySorted ? propertiesOrder : null;
}
public void setSorted(boolean sorted) {
mySorted = sorted;
myPropertiesOrder = null;
}
public MultiMap<String, IProperty> getPropertiesMap() {
return myPropertiesMap;
}
public List<IProperty> getPropertiesOrder() {
return myPropertiesOrder;
}
public boolean isSorted() {
return mySorted;
}
}
private XmlPropertiesFileImpl(XmlFile file) {
myFile = file;
}
@@ -83,19 +111,19 @@ public class XmlPropertiesFileImpl extends XmlPropertiesFile {
@NotNull
@Override
public List<IProperty> getProperties() {
return new ArrayList<IProperty>(myPropertiesMap.getValue().values());
return new ArrayList<IProperty>(myInfo.getValue().getPropertiesMap().values());
}
@Override
public IProperty findPropertyByKey(@NotNull @NonNls String key) {
Collection<IProperty> properties = myPropertiesMap.getValue().get(key);
Collection<IProperty> properties = myInfo.getValue().getPropertiesMap().get(key);
return properties.isEmpty() ? null : properties.iterator().next();
}
@NotNull
@Override
public List<IProperty> findPropertiesByKey(@NotNull @NonNls String key) {
return new ArrayList<IProperty>(myPropertiesMap.getValue().get(key));
return new ArrayList<IProperty>(myInfo.getValue().getPropertiesMap().get(key));
}
@NotNull
@@ -122,22 +150,62 @@ public class XmlPropertiesFileImpl extends XmlPropertiesFile {
@Override
public IProperty addPropertyAfter(String key, String value, Property anchor) {
return null;
return addPropertyAfterAndCheckAlphaSorting(key, value, anchor, true, true);
}
@NotNull
public IProperty addPropertyAfterAndCheckAlphaSorting(String key, String value, @Nullable IProperty anchor, boolean addToEnd, boolean checkAlphaSorting) {
final XmlTag anchorTag = anchor == null ? null : (XmlTag)anchor.getPsiElement();
final XmlTag rootTag = myFile.getRootTag();
final XmlTag entry = createPropertyTag(key, value);
final XmlTag addedEntry = (XmlTag) (anchorTag == null ? myFile.getRootTag().addSubTag(entry, !addToEnd) : rootTag.addAfter(entry, anchorTag));
final XmlProperty property = new XmlProperty(addedEntry, this);
myInfo.getValue().getPropertiesMap().putValue(key, property);
if (checkAlphaSorting) {
checkAlphaSorting(property);
}
return property;
}
@NotNull
@Override
public IProperty addProperty(String key, String value) {
final XmlTag entry = createPropertyTag(key, value);
if (myInfo.getValue().isSorted()) {
final XmlProperty dummyProperty = new XmlProperty(entry, this);
final int insertIndex = Collections.binarySearch(myInfo.getValue().getPropertiesOrder(), dummyProperty, new Comparator<IProperty>() {
@Override
public int compare(IProperty p1, IProperty p2) {
final String k1 = p1.getKey();
final String k2 = p2.getKey();
return k1.compareTo(k2);
}
});
final IProperty insertPosition;
final IProperty inserted;
if (insertIndex == -1) {
inserted = addPropertyAfterAndCheckAlphaSorting(key, value, null, false, false);
myInfo.getValue().getPropertiesOrder().add(0, inserted);
}
else {
final int position = insertIndex < 0 ? -insertIndex - 2 : insertIndex;
insertPosition = myInfo.getValue().getPropertiesOrder().get(position);
inserted = addPropertyAfterAndCheckAlphaSorting(key, value, insertPosition, false, false);
myInfo.getValue().getPropertiesOrder().add(position + 1, inserted);
}
return inserted;
} else {
return addPropertyAfterAndCheckAlphaSorting(key, value, null, true, false);
}
}
private XmlTag createPropertyTag(final String key, final String value) {
XmlTag rootTag = myFile.getRootTag();
XmlTag entry = rootTag.createChildTag("entry", "", value, false);
entry.setAttribute("key", key);
rootTag.addSubTag(entry, false);
final XmlProperty property = new XmlProperty(entry, this);
myPropertiesMap.getValue().putValue(key, property);
return property;
return entry;
}
public static PropertiesFile getPropertiesFile(final PsiFile file) {
CachedValuesManager manager = CachedValuesManager.getManager(file.getProject());
if (file instanceof XmlFile) {
@@ -194,7 +262,7 @@ public class XmlPropertiesFileImpl extends XmlPropertiesFile {
@Override
public boolean isAlphaSorted() {
return PropertiesImplUtil.isAlphaSorted(getProperties());
return myInfo.getValue().isSorted();
}
@Override
@@ -213,4 +281,29 @@ public class XmlPropertiesFileImpl extends XmlPropertiesFile {
public int hashCode() {
return myFile.hashCode();
}
private void checkAlphaSorting(final IProperty property) {
if (myInfo.getValue().isSorted()) {
final String key = property.getKey();
final XmlTag prev = getSibling((XmlTag)property.getPsiElement(), true);
final String prevKey = prev == null ? null : new XmlProperty(prev, this).getKey();
if (prevKey != null && key != null && prevKey.compareTo(key) > 0) {
myInfo.getValue().setSorted(false);
} else {
final XmlTag next = getSibling((XmlTag)property.getPsiElement(), false);
final String nextKey = next == null ? null : new XmlProperty(next, this).getKey();
if (nextKey != null && key != null && nextKey.compareTo(key) < 0) {
myInfo.getValue().setSorted(false);
}
}
}
}
private static XmlTag getSibling(final XmlTag entry, final boolean prev) {
XmlTag sibling = (XmlTag)(prev ? entry.getPrevSibling() : entry.getNextSibling());
while (sibling != null && !"entry".equals(sibling.getName())) {
sibling = (XmlTag)(prev ? sibling.getPrevSibling() : sibling.getNextSibling());
}
return sibling;
}
}
+7
View File
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties>
<comment>Hi</comment>
<entry key="c">bar</entry>
<entry key="m">baz</entry>
</properties>
@@ -22,6 +22,7 @@ import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.command.WriteCommandAction;
import com.intellij.testFramework.LightPlatformTestCase;
import com.intellij.testFramework.PlatformTestCase;
import com.intellij.testFramework.fixtures.LightPlatformCodeInsightFixtureTestCase;
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.NonNls;
@@ -30,16 +31,13 @@ import java.util.List;
/**
* @author max
*/
public class PropertiesFileTest extends LightPlatformTestCase {
public class PropertiesFileTest extends LightPlatformCodeInsightFixtureTestCase {
private Property myPropertyToAdd;
public PropertiesFileTest() {
PlatformTestCase.initPlatformLangPrefix();
}
@Override
protected void setUp() throws Exception {
super.setUp();
PlatformTestCase.initPlatformLangPrefix();
myPropertyToAdd = (Property)PropertiesElementFactory.createProperty(getProject(), "kkk", "vvv");
}
@@ -73,8 +71,8 @@ public class PropertiesFileTest extends LightPlatformTestCase {
List<IProperty> properties = propertiesFile.getProperties();
assertEquals(2, properties.size());
assertPropertyEquals(properties.get(0), "xxx", "yyy");
assertPropertyEquals(properties.get(1), myPropertyToAdd.getName(), myPropertyToAdd.getValue());
assertPropertyEquals(properties.get(1), "xxx", "yyy");
assertPropertyEquals(properties.get(0), myPropertyToAdd.getName(), myPropertyToAdd.getValue());
}
public void testDeleteProperty() throws Exception {
PropertiesFile propertiesFile = PropertiesElementFactory.createPropertiesFile(getProject(), "xxx=yyy\n#s\nzzz=ttt\n\n");
@@ -9,6 +9,8 @@ import com.intellij.openapi.command.WriteCommandAction;
import com.intellij.psi.PsiFile;
import com.intellij.testFramework.PlatformTestCase;
import com.intellij.testFramework.fixtures.LightPlatformCodeInsightFixtureTestCase;
import com.intellij.util.Function;
import com.intellij.util.containers.ContainerUtil;
import java.util.List;
@@ -81,6 +83,23 @@ public class XmlPropertiesTest extends LightPlatformCodeInsightFixtureTestCase {
assertEquals("vvv", property2.getValue());
}
public void testAddPropertyInAlphaOrder() {
final PsiFile psiFile = myFixture.configureByFile("bar.xml");
final PropertiesFile propertiesFile = PropertiesImplUtil.getPropertiesFile(psiFile);
assertNotNull(propertiesFile);
WriteCommandAction.runWriteCommandAction(getProject(), new Runnable() {
public void run() {
propertiesFile.addProperty("d", "vvv");
propertiesFile.addProperty("a", "vvv");
propertiesFile.addProperty("l", "vvv");
propertiesFile.addProperty("v", "vvv");
}
});
assertTrue(propertiesFile.isAlphaSorted());
assertTrue(PropertiesImplUtil.getPropertiesFile(psiFile).isAlphaSorted());
}
@Override
protected String getTestDataPath() {
return PluginPathManager.getPluginHomePath("properties") + "/testData/xml/";
@@ -377,5 +377,6 @@ private layoutMac(Map _args, String target) {
args.help_id = "PY"
args."idea.properties.path" = "${paths.distAll}/bin/idea.properties"
args."idea.properties" = ["idea.no.jre.check": true, "ide.mac.useNativeClipboard": "false"];
args.executable = "pycharm"
layoutMacApp(target, ch, args)
}
@@ -6,6 +6,8 @@ import com.intellij.openapi.project.Project;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.File;
public class PyStudyLanguageManager implements StudyLanguageManager {
@Nullable
@Override
@@ -28,6 +30,17 @@ public class PyStudyLanguageManager implements StudyLanguageManager {
return getInternalTemplateByName(project, "tests.py");
}
@Override
public boolean packFile(File pathname) {
String name = pathname.getName();
return !name.contains("__pycache__") && !name.contains(".pyc");
}
@Override
public String[] getAdditionalFilesToPack() {
return new String[]{"test_helper.py"};
}
private static FileTemplate getInternalTemplateByName(@NotNull final Project project, String name) {
return FileTemplateManager.getInstance(project).getInternalTemplate(name);
}
@@ -25,6 +25,8 @@ import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.io.FileUtilRt;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.VirtualFileManager;
import com.intellij.util.xmlb.XmlSerializer;
@@ -184,11 +186,13 @@ public class CCProjectService implements PersistentStateComponent<Element> {
return Integer.parseInt(fullName.substring(logicalName.length())) - 1;
}
public static String getRealTaskFileName(String name) {
if (!name.contains(".answer")) {
String nameWithoutExtension = FileUtil.getNameWithoutExtension(name);
String extension = FileUtilRt.getExtension(name);
if (!nameWithoutExtension.endsWith(".answer")) {
return null;
}
int nameEnd = name.indexOf(".answer");
return name.substring(0, nameEnd) + ".py";
return name.substring(0, nameEnd) + "." + extension;
}
public static boolean setCCActionAvailable(@NotNull AnActionEvent e) {
@@ -1,6 +1,7 @@
package com.jetbrains.edu.coursecreator;
import com.intellij.ide.projectView.actions.MarkRootActionBase;
import com.intellij.lang.Language;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.Presentation;
import com.intellij.openapi.application.ApplicationManager;
@@ -12,7 +13,9 @@ import com.intellij.openapi.roots.ContentEntry;
import com.intellij.openapi.roots.ModifiableRootModel;
import com.intellij.openapi.roots.ModuleRootManager;
import com.intellij.openapi.vfs.VirtualFile;
import com.jetbrains.edu.coursecreator.format.Course;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class CCUtils {
private static final Logger LOG = Logger.getInstance(CCUtils.class.getName());
@@ -56,4 +59,10 @@ public class CCUtils {
return -1;
}
}
@Nullable
public static StudyLanguageManager getStudyLanguageManager(@NotNull final Course course) {
Language language = Language.findLanguageByID(course.getLanguage());
return language == null ? null : StudyLanguageManager.INSTANCE.forLanguage(language);
}
}
@@ -6,6 +6,8 @@ import com.intellij.openapi.project.Project;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.File;
public interface StudyLanguageManager {
LanguageExtension<StudyLanguageManager> INSTANCE = new LanguageExtension<StudyLanguageManager>("Edu.StudyLanguageManager");
@@ -17,4 +19,8 @@ public interface StudyLanguageManager {
@Nullable
FileTemplate getTestsTemplate(@NotNull final Project project);
boolean packFile(File pathname);
String[] getAdditionalFilesToPack();
}
@@ -21,6 +21,8 @@ import com.intellij.openapi.vfs.VirtualFileManager;
import com.intellij.util.io.ZipUtil;
import com.jetbrains.edu.coursecreator.CCDocumentListener;
import com.jetbrains.edu.coursecreator.CCProjectService;
import com.jetbrains.edu.coursecreator.CCUtils;
import com.jetbrains.edu.coursecreator.StudyLanguageManager;
import com.jetbrains.edu.coursecreator.format.*;
import com.jetbrains.edu.coursecreator.ui.CreateCourseArchiveDialog;
import org.jetbrains.annotations.NotNull;
@@ -92,7 +94,7 @@ public class CCCreateCourseArchive extends DumbAwareAction {
}
}
generateJson(project);
packCourse(baseDir, lessons);
packCourse(baseDir, lessons, course);
resetTaskFiles(taskFiles);
synchronize(project);
}
@@ -204,11 +206,11 @@ public class CCCreateCourseArchive extends DumbAwareAction {
}
}
private void packCourse(@NotNull final VirtualFile baseDir, @NotNull final Map<String, Lesson> lessons) {
private void packCourse(@NotNull final VirtualFile baseDir, @NotNull final Map<String, Lesson> lessons, @NotNull final Course course) {
try {
File zipFile = new File(myLocationDir, myZipName + ".zip");
ZipOutputStream zos = new ZipOutputStream(new BufferedOutputStream(new FileOutputStream(zipFile)));
final StudyLanguageManager manager = CCUtils.getStudyLanguageManager(course);
for (Map.Entry<String, Lesson> entry : lessons.entrySet()) {
final VirtualFile lessonDir = baseDir.findChild(entry.getKey());
if (lessonDir == null) continue;
@@ -217,13 +219,21 @@ public class CCCreateCourseArchive extends DumbAwareAction {
public boolean accept(File pathname) {
String name = pathname.getName();
String nameWithoutExtension = FileUtil.getNameWithoutExtension(pathname);
return !nameWithoutExtension.endsWith(".answer") && !name.contains("__pycache__") && !name.contains("_windows") && !name.contains(".pyc");
if (nameWithoutExtension.endsWith(".answer") || name.contains("_windows")) {
return false;
}
return manager == null || manager.packFile(pathname);
}
}, null);
}
ZipUtil.addFileOrDirRecursively(zos, null, new File(baseDir.getPath(), "hints"), "hints", null, null);
ZipUtil.addFileOrDirRecursively(zos, null, new File(baseDir.getPath(), "course.json"), "course.json", null, null);
ZipUtil.addFileOrDirRecursively(zos, null, new File(baseDir.getPath(), "test_helper.py"), "test_helper.py", null, null);
packFile("hints", zos, baseDir);
packFile("course.json", zos, baseDir);
if (manager != null) {
String[] additionalFilesToPack = manager.getAdditionalFilesToPack();
for (String filename: additionalFilesToPack) {
packFile(filename, zos, baseDir);
}
}
zos.close();
Messages.showInfoMessage("Course archive was saved to " + zipFile.getPath(), "Course Archive Was Created Successfully");
}
@@ -271,4 +281,19 @@ public class CCCreateCourseArchive extends DumbAwareAction {
return true;
}
}
private static void packFile(@NotNull final String filename,
@NotNull final ZipOutputStream zipOutputStream,
@NotNull final VirtualFile baseDir) {
try {
File file = new File(baseDir.getPath(), filename);
if (!file.exists()) {
return;
}
ZipUtil.addFileOrDirRecursively(zipOutputStream, null, file, filename, null, null);
}
catch (IOException e) {
LOG.error(e);
}
}
}
@@ -18,6 +18,7 @@ import com.intellij.openapi.fileEditor.FileEditorManager;
import com.intellij.openapi.project.DumbAwareAction;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiDirectory;
import com.intellij.psi.PsiElement;
@@ -80,25 +81,23 @@ public class CCCreateTask extends DumbAwareAction {
final StudyLanguageManager studyLanguageManager = StudyLanguageManager.INSTANCE.forLanguage(language);
CCUtils.markDirAsSourceRoot(taskDirectory.getVirtualFile(), project);
final Task task = new Task(taskName);
task.setIndex(size + 1);
lesson.addTask(task, taskDirectory);
createFromTemplateAndOpen(taskDirectory, studyLanguageManager.getTestsTemplate(project), view);
createFromTemplateAndOpen(taskDirectory, FileTemplateManager.getInstance(project).getInternalTemplate("task.html"), view);
String defaultExtension = studyLanguageManager.getDefaultTaskFileExtension();
String taskFileName = null;
if (defaultExtension != null) {
FileTemplate taskFileTemplate = studyLanguageManager.getTaskFileTemplateForExtension(project,
defaultExtension);
createFromTemplateAndOpen(taskDirectory, taskFileTemplate, view);
if (taskFileTemplate != null) {
taskFileName = taskFileTemplate.getName();
String taskFileName = FileUtil.getNameWithoutExtension(taskFileTemplate.getName());
task.addTaskFile(taskFileName + "." + defaultExtension, size + 1);
}
}
final Task task = new Task(taskName);
task.setIndex(size + 1);
lesson.addTask(task, taskDirectory);
if (taskFileName != null) {
task.addTaskFile(taskFileName, size + 1);
}
ApplicationManager.getApplication().invokeLater(new Runnable() {
@Override
public void run() {
@@ -7,7 +7,6 @@ import com.intellij.ide.fileTemplates.FileTemplateUtil;
import com.intellij.ide.projectView.ProjectView;
import com.intellij.ide.util.DirectoryChooserUtil;
import com.intellij.ide.util.EditorHelper;
import com.intellij.lang.Language;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.CommonDataKeys;
import com.intellij.openapi.actionSystem.LangDataKeys;
@@ -21,6 +20,7 @@ import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiDirectory;
import com.intellij.psi.PsiElement;
import com.jetbrains.edu.coursecreator.CCProjectService;
import com.jetbrains.edu.coursecreator.CCUtils;
import com.jetbrains.edu.coursecreator.StudyLanguageManager;
import com.jetbrains.edu.coursecreator.format.Course;
import com.jetbrains.edu.coursecreator.format.Lesson;
@@ -57,7 +57,7 @@ public class CCCreateTaskFile extends DumbAwareAction {
final int index = task.getTaskFiles().size() + 1;
String generatedName = "file" + index;
CreateTaskFileDialog dialog = new CreateTaskFileDialog(project, generatedName);
CreateTaskFileDialog dialog = new CreateTaskFileDialog(project, generatedName, course);
dialog.show();
if (dialog.getExitCode() != OK_EXIT_CODE) {
return;
@@ -68,11 +68,10 @@ public class CCCreateTaskFile extends DumbAwareAction {
if (type == null) {
return;
}
Language language = Language.findLanguageByID(course.getLanguage());
if (language == null) {
final StudyLanguageManager studyLanguageManager = CCUtils.getStudyLanguageManager(course);
if (studyLanguageManager == null) {
return;
}
final StudyLanguageManager studyLanguageManager = StudyLanguageManager.INSTANCE.forLanguage(language);
final String extension = type.getDefaultExtension();
ApplicationManager.getApplication().runWriteAction(new Runnable() {
@Override
@@ -18,6 +18,7 @@ package com.jetbrains.edu.coursecreator.actions;
import com.intellij.execution.Location;
import com.intellij.execution.actions.ConfigurationContext;
import com.intellij.icons.AllIcons;
import com.intellij.ide.fileTemplates.FileTemplate;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.Presentation;
@@ -34,6 +35,8 @@ import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.util.containers.HashMap;
import com.jetbrains.edu.coursecreator.CCProjectService;
import com.jetbrains.edu.coursecreator.CCUtils;
import com.jetbrains.edu.coursecreator.StudyLanguageManager;
import com.jetbrains.edu.coursecreator.format.*;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -130,8 +133,16 @@ public abstract class CCRunTestsAction extends AnAction {
clearTestEnvironment(taskDir, project);
for (final Map.Entry<String, TaskFile> entry : task.getTaskFiles().entrySet()) {
final String name = entry.getKey();
StudyLanguageManager manager = CCUtils.getStudyLanguageManager(course);
if (manager == null) {
return;
}
createTestEnvironment(taskDir, name, entry.getValue(), project);
VirtualFile testFile = taskDir.findChild("tests.py");
FileTemplate testsTemplate = manager.getTestsTemplate(project);
if (testsTemplate == null) {
return;
}
VirtualFile testFile = taskDir.findChild(testsTemplate.getName());
if (testFile == null) {
return;
}
@@ -30,7 +30,6 @@ import com.intellij.openapi.project.DumbAwareAction;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.FrameWrapper;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiDirectory;
import com.intellij.psi.PsiFile;
@@ -92,6 +91,9 @@ public class CCShowPreview extends DumbAwareAction {
Lesson lesson = course.getLesson(lessonDir.getName());
Task task = lesson.getTask(taskDir.getName());
TaskFile taskFile = task.getTaskFile(file.getName());
if (taskFile == null) {
return;
}
final Map<TaskFile, TaskFile> taskFilesCopy = new HashMap<TaskFile, TaskFile>();
for (final Map.Entry<String, TaskFile> entry : task.getTaskFiles().entrySet()) {
if (entry.getValue() == taskFile) {
@@ -103,7 +105,10 @@ public class CCShowPreview extends DumbAwareAction {
});
}
}
String userFileName = FileUtil.getNameWithoutExtension(file.getName()) + ".py";
String userFileName = CCProjectService.getRealTaskFileName(file.getName());
if (userFileName == null) {
return;
}
VirtualFile userFile = taskDir.getVirtualFile().findChild(userFileName);
if (userFile == null) {
LOG.info("Generated file " + userFileName + "was not found");
@@ -8,21 +8,25 @@ import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.ui.DoubleClickListener;
import com.intellij.ui.ListScrollingUtil;
import com.intellij.ui.components.JBList;
import com.jetbrains.edu.coursecreator.CCUtils;
import com.jetbrains.edu.coursecreator.StudyLanguageManager;
import com.jetbrains.edu.coursecreator.format.Course;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import java.awt.event.MouseEvent;
public class CreateTaskFileDialog extends DialogWrapper {
private final Course myCourse;
private JPanel myPanel;
private JBList myList;
private JTextField myTextField;
@SuppressWarnings("unchecked")
public CreateTaskFileDialog(@Nullable Project project, String generatedFileName) {
public CreateTaskFileDialog(@Nullable Project project, String generatedFileName, @NotNull final Course course) {
super(project);
myCourse = course;
FileType[] fileTypes = FileTypeManager.getInstance().getRegisteredFileTypes();
DefaultListModel model = new DefaultListModel();
@@ -51,16 +55,11 @@ public class CreateTaskFileDialog extends DialogWrapper {
}
}.installOn(myList);
myList.getSelectionModel().addListSelectionListener(
new ListSelectionListener() {
@Override
public void valueChanged(ListSelectionEvent e) {
//TODO: do smth to check validness
}
}
);
ListScrollingUtil.selectItem(myList, FileTypeManager.getInstance().getFileTypeByExtension("py"));
StudyLanguageManager manager = CCUtils.getStudyLanguageManager(myCourse);
if (manager != null) {
String extension = manager.getDefaultTaskFileExtension();
ListScrollingUtil.selectItem(myList, FileTypeManager.getInstance().getFileTypeByExtension(extension != null ? extension : "txt"));
}
return myPanel;
}
@@ -24,17 +24,26 @@ def report_data(dumper):
command = utility.fetch_command(command_name)
assert isinstance(command, BaseCommand)
dumper.start_command(command_name=command_name,
command_help_text=str(command.usage("").replace("%prog", command_name)), # TODO: support subcommands
command_help_text=str(command.usage("").replace("%prog", command_name)),
# TODO: support subcommands
command_args_text=str(command.args))
for opt in command.option_list:
opt_type = opt.type if opt.type in Option.TYPES else "" # Empty for unknown
num_of_args = int(opt.nargs) if opt.nargs else 0
opt_type = None
if num_of_args > 0:
# If option accepts arg, we need to determine its type. It could be int, choices, or something other
# See https://docs.python.org/2/library/optparse.html#standard-option-types
if opt.type in ["int", "long"]:
opt_type = "int"
elif opt.choices:
assert isinstance(opt.choices, list), "Choices should be list"
opt_type = opt.choices
# There is no official way to access this field, so I use protected one. At least it is public API.
# noinspection PyProtectedMember
dumper.add_command_option(
opt_type=opt_type,
choices=opt.choices,
long_opt_names=opt._long_opts,
short_opt_names=opt._short_opts,
help_text=opt.help,
num_of_args=opt.nargs)
argument_info=(num_of_args, opt_type) if num_of_args else None)
dumper.close_command()
@@ -6,13 +6,17 @@ It does not have schema (yet!) but here is XML format it uses.
<commandInfo-array> -- root
<commandInfo args="args description" help="human readable text" name="command name"> -- info about command
<option help="option help" numberOfArgs="number of values (nargs)" type="option type: Option.TYPES"> -- one entry for each option
<option help="option help" numberOfArgs="number of values (nargs)" type="option_type (see below)"> -- one entry for each option
<longNames>--each-for-one-long-opt-name</longNames>
<shortNames>-each-for-one-short-name</shortNames>
<choices>--each-for-one-available-value</choices>
</option>
</commandInfo>
</commandInfo-array>
"option_type" is only set if "numberOfArgs" > 0, and it can be: "int" (means integer),
"choices" (means opt can have one of the values, provided in choices) or "str" that means "string" (option may have any value)
Classes like DjangoCommandsInfo is used on Java side.
"""
@@ -77,35 +81,45 @@ class XmlDumper(object):
self.__command_element.setAttribute("args", command_args_text)
self.__root.appendChild(self.__command_element)
def add_command_option(self, opt_type, choices, long_opt_names, short_opt_names, help_text, num_of_args):
def add_command_option(self, long_opt_names, short_opt_names, help_text, argument_info):
"""
Adds command option
:param opt_type: "string", "int", "long", "float", "complex", "choice"
:param choices: list of choices for "choice" type
:param argument_info: None if option does not accept any arguments or tuple of (num_of_args, type_info) \
where num_of_args is int > 0 and type_info is str, representing type (only "int" and "string" are supported) \
or list of available types in case of choices
:param long_opt_names: list of long opt names
:param short_opt_names: list of short opt names
:param help_text: help text
:param num_of_args: number of arguments
:type opt_type str
:type choices list of string
:type long_opt_names list of str
:type short_opt_names list of str
:type help_text str
:type num_of_args int
:type argument_info tuple
"""
assert isinstance(self.__command_element, Element), "Add option in command only"
option = self.__document.createElement("option")
option.setAttribute("type", opt_type)
if choices:
self.__create_text_array(option, "choices", choices)
option = self.__document.createElement("option")
opt_type_to_report = None
num_of_args = 0
if argument_info:
(num_of_args, type_info) = argument_info
if isinstance(type_info, list):
self.__create_text_array(option, "choices", type_info)
opt_type_to_report = "choices"
else:
opt_type_to_report = "int" if str(type_info) == "int" else "str"
if long_opt_names:
self.__create_text_array(option, "longNames", long_opt_names)
if short_opt_names:
self.__create_text_array(option, "shortNames", short_opt_names)
if opt_type_to_report:
option.setAttribute("type", opt_type_to_report)
option.setAttribute("help", help_text)
if num_of_args:
option.setAttribute("numberOfArgs", str(num_of_args))
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.jetbrains.python.commandInterface.commandBasedChunkDriver;
package com.jetbrains.python.commandInterface.command;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.jetbrains.python.commandInterface.commandBasedChunkDriver;
package com.jetbrains.python.commandInterface.command;
import com.intellij.openapi.util.Pair;
import org.jetbrains.annotations.Nullable;
@@ -13,15 +13,17 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.jetbrains.python.commandInterface.commandBasedChunkDriver;
package com.jetbrains.python.commandInterface.command;
import com.intellij.openapi.module.Module;
import com.jetbrains.python.commandLineParser.CommandLineParseResult;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.List;
/**
* Command with arguments
* Command with arguments and options
*
* @author Ilya.Kazakevich
*/
@@ -47,6 +49,12 @@ public interface Command {
@NotNull
ArgumentsInfo getArgumentsInfo();
/**
* @return command options
*/
@NotNull
List<Option> getOptions();
/**
* Execute command
*
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.jetbrains.python.commandInterface.commandBasedChunkDriver;
package com.jetbrains.python.commandInterface.command;
import com.google.common.base.Preconditions;
import com.intellij.openapi.util.Pair;
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.jetbrains.python.commandInterface.commandBasedChunkDriver;
package com.jetbrains.python.commandInterface.command;
import com.intellij.openapi.util.Pair;
import org.jetbrains.annotations.Nullable;
@@ -0,0 +1,92 @@
/*
* Copyright 2000-2015 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.jetbrains.python.commandInterface.command;
import com.google.common.base.Preconditions;
import com.intellij.openapi.util.Pair;
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;
/**
* Command option
* @author Ilya.Kazakevich
*/
public final class Option {
@NotNull
private final List<String> myLongNames = new ArrayList<String>();
@NotNull
private final List<String> myShortNames = new ArrayList<String>();
@Nullable
private final Pair<Integer, OptionArgumentInfo> myArgumentAndQuantity;
@NotNull
private final String myHelp;
/**
*
* @param argumentAndQuantity if option accepts argument, there should be pair of [argument_quantity, its_type_info]
* @param help option help
* @param shortNames option short names
* @param longNames option long names
*/
public Option(@Nullable final Pair<Integer, OptionArgumentInfo> argumentAndQuantity,
@NotNull final String help,
@NotNull final Collection<String> shortNames,
@NotNull final Collection<String> longNames) {
Preconditions.checkArgument(argumentAndQuantity == null || argumentAndQuantity.first > 0, "Illegal args and quantity: " + argumentAndQuantity);
myArgumentAndQuantity = argumentAndQuantity;
myShortNames.addAll(shortNames);
myLongNames.addAll(longNames);
myHelp = help;
}
/**
* @return Option long names
*/
@NotNull
public List<String> getLongNames() {
return Collections.unmodifiableList(myLongNames);
}
/**
* @return Option short names
*/
@NotNull
public List<String> getShortNames() {
return Collections.unmodifiableList(myShortNames);
}
/**
*
* @return if option accepts argument -- pair of [argument_quantity, its_type_info]. Null otherwise.
*/
@Nullable
Pair<Integer, OptionArgumentInfo> getArgumentAndQuantity() {
return myArgumentAndQuantity;
}
/**
* @return Option help
*/
@NotNull
public String getHelp() {
return myHelp;
}
}
@@ -0,0 +1,42 @@
/*
* Copyright 2000-2015 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.jetbrains.python.commandInterface.command;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.List;
/**
* Information about option argument
*
* @author Ilya.Kazakevich
*/
public interface OptionArgumentInfo {
/**
* Validates argument value
*
* @param value value to validate
* @return true if valid
*/
boolean isValid(@NotNull String value);
/**
* @return list of available values (if argument is based on list of choices), or null if any value is accepted (but should be validated)
*/
@Nullable
List<String> getAvailableValues();
}
@@ -13,17 +13,19 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.psi.codeStyle;
package com.jetbrains.python.commandInterface.command;
import org.jetbrains.annotations.NotNull;
public class LabelWithAction {
public final String label;
public final Runnable action;
public LabelWithAction(@NotNull String label, @NotNull Runnable action) {
this.label = label;
this.action = action;
}
/**
* Argument type to be used with {@link OptionTypedArgumentInfo}
* @author Ilya.Kazakevich
*/
public enum OptionArgumentType {
/**
* String (actually, anything)
*/
STRING,
/**
* Integer or long
*/
INTEGER
}
@@ -0,0 +1,51 @@
/*
* Copyright 2000-2015 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.jetbrains.python.commandInterface.command;
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;
/**
* For options, whose argument is based on list of choices
* @author Ilya.Kazakevich
*/
public final class OptionChoiceBasedArgumentInfo implements OptionArgumentInfo {
@NotNull
private final List<String> myChoices = new ArrayList<String>();
/**
* @param choices available choices
*/
public OptionChoiceBasedArgumentInfo(@NotNull final Collection<String> choices) {
myChoices.addAll(choices);
}
@Override
public boolean isValid(@NotNull final String value) {
return myChoices.contains(value);
}
@Nullable
@Override
public List<String> getAvailableValues() {
return Collections.unmodifiableList(myChoices);
}
}
@@ -0,0 +1,61 @@
/*
* Copyright 2000-2015 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.jetbrains.python.commandInterface.command;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.List;
/**
* For options, whose argument is based on certain type.
*
* @author Ilya.Kazakevich
* @see com.jetbrains.python.commandInterface.command.OptionArgumentType
*/
public final class OptionTypedArgumentInfo implements OptionArgumentInfo {
@NotNull
private final OptionArgumentType myType;
/**
* @param type type argument(s) of this option may have
*/
public OptionTypedArgumentInfo(@NotNull final OptionArgumentType type) {
myType = type;
}
@Override
public boolean isValid(@NotNull final String value) {
// We only check integer for now
if (myType == OptionArgumentType.INTEGER) {
try {
// We just parse it to get exception
//noinspection ResultOfMethodCallIgnored
Integer.parseInt(value);
}
catch (final NumberFormatException ignored) {
return false;
}
}
return true;
}
@Nullable
@Override
public List<String> getAvailableValues() {
return null;
}
}
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.jetbrains.python.commandInterface.commandBasedChunkDriver;
package com.jetbrains.python.commandInterface.command;
import com.intellij.openapi.util.Pair;
import org.jetbrains.annotations.NotNull;
@@ -0,0 +1,23 @@
/*
* Copyright 2000-2015 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.
*/
/**
* Command with arguments and options.
* Each {@link com.jetbrains.python.commandInterface.command.Command} may have one or more positional {@link com.jetbrains.python.commandInterface.command.Argument arguments}
* and several {@link com.jetbrains.python.commandInterface.command.Option options}.
* @author Ilya.Kazakevich
*/
package com.jetbrains.python.commandInterface.command;
@@ -23,6 +23,9 @@ import com.jetbrains.python.commandInterface.chunkDriverBasedPresenter.ChunkDriv
import com.jetbrains.python.commandInterface.chunkDriverBasedPresenter.ChunkInfo;
import com.jetbrains.python.commandInterface.chunkDriverBasedPresenter.ParseInfo;
import com.jetbrains.python.commandInterface.chunkDriverBasedPresenter.SuggestionInfo;
import com.jetbrains.python.commandInterface.command.Argument;
import com.jetbrains.python.commandInterface.command.ArgumentsInfo;
import com.jetbrains.python.commandInterface.command.Command;
import com.jetbrains.python.commandLineParser.CommandLineParseResult;
import com.jetbrains.python.commandLineParser.CommandLineParser;
import com.jetbrains.python.commandLineParser.CommandLinePartType;
@@ -16,12 +16,14 @@
/**
* {@link com.jetbrains.python.commandInterface.chunkDriverBasedPresenter.ChunkDriver} implementation based on idea of
* {@link com.jetbrains.python.commandInterface.commandBasedChunkDriver.Command command} and its {@link com.jetbrains.python.commandInterface.commandBasedChunkDriver.Argument arguments}.
* {@link com.jetbrains.python.commandInterface.command command, option and argument}.
*
* See {@link com.jetbrains.python.commandInterface.commandBasedChunkDriver.CommandBasedChunkDriver} as entry point.
* It parses command line using {@link com.jetbrains.python.commandLineParser.CommandLineParser} and finds matching command and arguments
* provided by user
*
* @see com.jetbrains.python.commandInterface.command
* @see com.jetbrains.python.commandInterface.command.Command
* @author Ilya.Kazakevich
*/
package com.jetbrains.python.commandInterface.commandBasedChunkDriver;
@@ -102,7 +102,7 @@ public class DomFileEditor<T extends BasicDomElementComponent> extends Perspecti
@Override
@NotNull
protected JComponent createCustomComponent() {
new MnemonicHelper().register(getComponent());
MnemonicHelper.init(getComponent());
myComponent = myComponentFactory.create();
DomUIFactory.getDomUIFactory().setupErrorOutdatingUserActivityWatcher(this, getDomElement());
DomManager.getDomManager(getProject()).addDomEventListener(new DomEventListener() {
@@ -145,7 +145,7 @@ public class XmlEmmetConfigurable implements SearchableConfigurable, Disposable,
@Nls
@Override
public String getDisplayName() {
return "XML";
return "HTML";
}
@Nullable
@@ -1574,6 +1574,17 @@ public class XmlHighlightingTest extends DaemonAnalyzerTestCase {
);
}
public void testDocBookRole() throws Exception {
doTestWithLocations(
new String[][] {
{"http://docbook.org/ns/docbook", "DocBookV5.xsd"},
{"http://www.w3.org/1999/xlink", "xlink.xsd"},
{"http://www.w3.org/XML/1998/namespace", "xml.xsd"}
},
"xml"
);
}
public void testCorrectGeneratedDtdUpdate() throws Exception {
configureByFile(BASE_PATH + getTestName(false) + ".xml");
Collection<HighlightInfo> infos = filterInfos(doHighlighting());

Some files were not shown because too many files have changed in this diff Show More