Merge remote-tracking branch 'origin/master'

This commit is contained in:
Ilya.Kazakevich
2015-02-11 15:42:32 +03:00
67 changed files with 816 additions and 331 deletions
+1
View File
@@ -278,6 +278,7 @@ libraryLicense(name: "json-smart", libraryName: "json-smart-1.1.1.jar", version:
libraryLicense(name: "fxg-utils", libraryName: "fxg-utils", version: "4.9.1", license: "Apache 2.0", url: "http://flex.apache.org", licenseUrl: "http://www.apache.org/licenses/LICENSE-2.0")
libraryLicense(name: "jayatana", libraryName: "jayatana", version: "1.2.4", license: "MIT License", url: "https://code.google.com/p/java-swing-ayatana/", licenseUrl: "http://opensource.org/licenses/mit-license.php")
libraryLicense(name: "ForkJoin", version: "", license: "Creative Commons Public Domain Dedication", url: "http://gee.cs.oswego.edu/dl/concurrency-interest/index.html", licenseUrl: "http://creativecommons.org/publicdomain/zero/1.0/")
libraryLicense(name: "ANTLR 4 Runtime", libraryName: "antlr-runtime-4.1.jar", version: "4.1", license: "BSD", url: "http://www.antlr.org", licenseUrl: "http://www.antlr.org/license.html")
libraryLicense(name: "minlog", libraryName: "minlog-1.2.jar", version: "1.2", license: "BSD", url: "https://github.com/EsotericSoftware/minlog", licenseUrl: "http://opensource.org/licenses/BSD-3-Clause")
libraryLicense(name: "ReflectASM", libraryName: "reflectasm-1.0.7.jar", version: "1.0.7", license: "BSD", url: "https://github.com/EsotericSoftware/reflectasm", licenseUrl: "http://opensource.org/licenses/BSD-3-Clause")
libraryLicense(name: "Objenesis", libraryName: "objenesis-1.2.jar", version: "1.2", license: "Apache 2.0", url: "http://objenesis.org/", licenseUrl: "http://apache.org/licenses/LICENSE-2.0")
+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 ->
@@ -132,7 +132,7 @@ class JavaClassNameInsertHandler implements InsertHandler<JavaPsiClassReferenceE
case FULLY_QUALIFY_NAMES_IF_NOT_IMPORTED:
if (file instanceof PsiJavaFile) {
PsiJavaFile javaFile = ((PsiJavaFile)file);
return !ImportHelper.isAlreadyImported(javaFile, item.getQualifiedName());
return item.getQualifiedName() != null && !ImportHelper.isAlreadyImported(javaFile, item.getQualifiedName());
}
default:
return false;
@@ -454,6 +454,43 @@ class Test {
}
'''
}
public void testNullQualifiedName() {
def text = '''
public class Test {
public static void main(String[] args) {
class Super {
}
/**
* {@link Su<caret>}
*/
Super aSuper = new Super();
}
}
'''
myFixture.configureByText "a.java", text
myFixture.completeBasic()
myFixture.type('\t')
myFixture.checkResult '''
public class Test {
public static void main(String[] args) {
class Super {
}
/**
* {@link Super}
*/
Super aSuper = new Super();
}
}
'''
}
public void testShortNameIfImplicitlyImported() {
javaSettings.CLASS_NAMES_IN_JAVADOC = JavaCodeStyleSettings.FULLY_QUALIFY_NAMES_IF_NOT_IMPORTED
@@ -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;
}
}
}
@@ -1,29 +0,0 @@
/*
* 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.psi.codeStyle;
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;
}
}
@@ -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));
}
}
}
@@ -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) {
@@ -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
@@ -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();
@@ -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;
}
@@ -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.
@@ -127,8 +127,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)/*.setAlpha(1)*/ // alpha disabled because of IDEA-136331
.setMovable(true)
.setDimensionServiceKey(project, FULL_VALUE_POPUP_DIMENSION_KEY, false)
.setRequestFocus(false);
if (callback != null) {
@@ -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() {
@@ -21,6 +21,7 @@ import com.intellij.openapi.util.io.FileUtil;
import com.intellij.testFramework.UsefulTestCase;
import com.intellij.util.Function;
import com.intellij.util.containers.ContainerUtil;
import org.codehaus.groovy.runtime.typehandling.ShortTypeHandling;
import org.gradle.tooling.BuildActionExecuter;
import org.gradle.tooling.GradleConnector;
import org.gradle.tooling.ProjectConnection;
@@ -150,7 +151,8 @@ public abstract class AbstractModelBuilderTest {
// gradle-tooling-extension-api jar
ProjectImportAction.class,
// gradle-tooling-extension-impl jar
ModelBuildScriptClasspathBuilderImpl.class
ModelBuildScriptClasspathBuilderImpl.class,
ShortTypeHandling.class
);
ContainerUtil.addAllNotNull(classes, doGetToolingExtensionClasses());
@@ -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);
}
}
};
@@ -89,18 +89,9 @@ public interface PropertiesFile {
*/
@NotNull PsiElement addPropertyAfter(@NotNull Property property, @Nullable Property anchor) throws IncorrectOperationException;
/**
* delegates call to {@link PropertiesFile#addPropertyLast()} method
*/
@Deprecated
IProperty addProperty(String key, String value);
IProperty addPropertyFirst(String key, String value);
IProperty addPropertyLast(String key, String value);
IProperty addPropertyAfter(String key, String value, Property anchor);
/**
* @return Property key to the property value map.
* Do not modify this map. It's no use anyway.
@@ -116,4 +107,6 @@ public interface PropertiesFile {
Project getProject();
String getText();
boolean isAlphaSorted();
}
@@ -17,7 +17,6 @@ package com.intellij.codeInspection.unsorted;
import com.intellij.codeInspection.*;
import com.intellij.lang.properties.IProperty;
import com.intellij.lang.properties.PropertiesBundle;
import com.intellij.lang.properties.PropertiesImplUtil;
import com.intellij.lang.properties.ResourceBundle;
import com.intellij.lang.properties.psi.PropertiesElementFactory;
@@ -30,11 +29,8 @@ import com.intellij.openapi.util.Comparing;
import com.intellij.psi.PsiElementVisitor;
import com.intellij.psi.PsiFile;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.util.NullableFunction;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.Collections;
@@ -68,7 +64,7 @@ public class AlphaUnsortedPropertiesFileInspection extends LocalInspectionTool {
holder.registerProblem(file, String.format(MESSAGE_TEMPLATE_WHOLE_RESOURCE_BUNDLE, resourceBundleBaseName), ProblemHighlightType.INFO, new PropertiesSorterQuickFix(true, propertiesFile));
return;
}
if (!isAlphaSorted(propertiesFile)) {
if (!propertiesFile.isAlphaSorted()) {
holder.registerProblem(file, "Properties file is unsorted", ProblemHighlightType.INFO, new PropertiesSorterQuickFix(true, propertiesFile));
}
}
@@ -81,32 +77,9 @@ public class AlphaUnsortedPropertiesFileInspection extends LocalInspectionTool {
if (!(file instanceof PropertiesFileImpl)) {
return true;
}
if (!file.equals(exceptedFile)) {
if (!isAlphaSorted(file)) {
return false;
}
}
}
return true;
}
private static boolean isAlphaSorted(final @NotNull PropertiesFile propertiesFile) {
return isAlphaSorted(ContainerUtil.mapNotNull(propertiesFile.getProperties(), new NullableFunction<IProperty, String>() {
@Nullable
@Override
public String fun(IProperty property) {
return property.getKey();
}
}));
}
private static boolean isAlphaSorted(final List<String> keys) {
String prevKey = null;
for (String key : keys) {
if (prevKey != null && prevKey.compareTo(key) > 0) {
if (!file.equals(exceptedFile) && !file.isAlphaSorted()) {
return false;
}
prevKey = key;
}
return true;
}
@@ -137,7 +110,7 @@ public class AlphaUnsortedPropertiesFileInspection extends LocalInspectionTool {
public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
final boolean force = myFilesToSort.length == 1;
for (PropertiesFile file : myFilesToSort) {
if (!force && isAlphaSorted(file)) {
if (!force && file.isAlphaSorted()) {
continue;
}
sortPropertiesFile(file);
@@ -33,10 +33,7 @@ import com.intellij.util.indexing.FileBasedIndex;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.*;
/**
* @author Konstantin Bulenkov
@@ -162,4 +159,19 @@ public class PropertiesImplUtil extends PropertiesUtil {
}
return getResourceBundle(baseName, baseDirectory);
}
public static boolean isAlphaSorted(final Collection<? extends IProperty> properties) {
String previousKey = null;
for (IProperty property : properties) {
final String key = property.getKey();
if (key == null) {
return false;
}
if (previousKey != null && previousKey.compareTo(key) > 0) {
return false;
}
previousKey = key;
}
return true;
}
}
@@ -25,6 +25,7 @@ import com.intellij.lang.properties.parsing.PropertiesElementTypes;
import com.intellij.lang.properties.psi.PropertiesElementFactory;
import com.intellij.lang.properties.psi.PropertiesFile;
import com.intellij.lang.properties.psi.Property;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.fileTypes.FileType;
import com.intellij.psi.FileViewProvider;
import com.intellij.psi.PsiElement;
@@ -44,9 +45,11 @@ import org.jetbrains.annotations.Nullable;
import java.util.*;
public class PropertiesFileImpl extends PsiFileBase implements PropertiesFile {
private static final Logger LOG = Logger.getInstance(PropertiesFileImpl.class);
private static final TokenSet PROPERTIES_LIST_SET = TokenSet.create(PropertiesElementTypes.PROPERTIES_LIST);
private volatile MostlySingularMultiMap<String,IProperty> myPropertiesMap; //guarded by lock
private volatile List<IProperty> myProperties; //guarded by lock
private volatile boolean myAlphaSorted;
private final Object lock = new Object();
public PropertiesFileImpl(FileViewProvider viewProvider) {
@@ -87,10 +90,12 @@ public class PropertiesFileImpl extends PsiFileBase implements PropertiesFile {
propertiesMap.add(key, property);
properties.add(property);
}
final boolean isAlphaSorted = PropertiesImplUtil.isAlphaSorted(properties);
synchronized (lock) {
if (myPropertiesMap != null) return;
myProperties = properties;
myPropertiesMap = propertiesMap;
myAlphaSorted = isAlphaSorted;
}
}
@@ -135,12 +140,30 @@ public class PropertiesFileImpl extends PsiFileBase implements PropertiesFile {
@Override
@NotNull
public PsiElement addProperty(@NotNull IProperty property) throws IncorrectOperationException {
if (haveToAddNewLine()) {
insertLineBreakBefore(null);
final IProperty position = findInsertionPosition(property);
return addPropertyAfter((Property)property, (Property)position);
}
private IProperty findInsertionPosition(@NotNull IProperty property) {
synchronized (lock) {
ensurePropertiesLoaded();
if (myProperties.isEmpty()) {
return null;
}
if (myAlphaSorted) {
final int insertIndex = Collections.binarySearch(myProperties, property, new Comparator<IProperty>() {
@Override
public int compare(IProperty p1, IProperty p2) {
final String k1 = p1.getKey();
final String k2 = p2.getKey();
LOG.assertTrue(k1 != null && k2 != null);
return k1.compareTo(k2);
}
});
return insertIndex == -1 ? null :myProperties.get(insertIndex < 0 ? - insertIndex - 2 : insertIndex);
}
return myProperties.get(myProperties.size() - 1);
}
final TreeElement copy = ChangeUtil.copyToElement(property.getPsiElement());
getPropertiesList().addChild(copy);
return copy.getPsi();
}
@Override
@@ -171,18 +194,6 @@ public class PropertiesFileImpl extends PsiFileBase implements PropertiesFile {
return (IProperty)addProperty(PropertiesElementFactory.createProperty(getProject(), key, value));
}
@NotNull
@Override
public IProperty addPropertyFirst(String key, String value) {
return (IProperty)addPropertyAfter((Property) PropertiesElementFactory.createProperty(getProject(), key, value), null);
}
@NotNull
@Override
public IProperty addPropertyLast(String key, String value) {
return addProperty(key, value);
}
@NotNull
@Override
public IProperty addPropertyAfter(String key, String value, @Nullable Property anchor) {
@@ -208,6 +219,14 @@ public class PropertiesFileImpl extends PsiFileBase implements PropertiesFile {
return result;
}
@Override
public boolean isAlphaSorted() {
synchronized (lock) {
ensurePropertiesLoaded();
return myAlphaSorted;
}
}
@Override
public void clearCaches() {
super.clearCaches();
@@ -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
@@ -120,34 +148,64 @@ public class XmlPropertiesFileImpl extends XmlPropertiesFile {
return null;
}
@Override
public IProperty addPropertyFirst(String key, String value) {
return null;
}
@Override
public IProperty addPropertyLast(String key, String value) {
return null;
}
@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) {
@@ -202,6 +260,11 @@ public class XmlPropertiesFileImpl extends XmlPropertiesFile {
return getContainingFile().getText();
}
@Override
public boolean isAlphaSorted() {
return myInfo.getValue().isSorted();
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
@@ -218,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;
}
}
@@ -65,17 +65,9 @@ public class ResourceBundlePropertiesInsertManagerImpl implements ResourceBundle
}
final PropertiesFile propertiesFile = myResourceBundle.getDefaultPropertiesFile();
if (myAlphaSorted) {
final Pair<IProperty, Integer> propertyAndPosition = findExistedPrevSiblingProperty(key, propertiesFile);
if (propertyAndPosition == null) {
propertiesFile.addPropertyFirst(key, value);
myKeysOrder.add(0, key);
} else {
propertiesFile.addPropertyAfter(key, value, (Property)propertyAndPosition.getFirst());
final Integer position = propertyAndPosition.getSecond();
myKeysOrder.add(position, key);
}
propertiesFile.addProperty(key, value);
} else {
propertiesFile.addPropertyLast(key, value);
insertPropertyLast(key, value, propertiesFile);
if (myOrdered) {
myKeysOrder.add(key);
}
@@ -85,14 +77,14 @@ public class ResourceBundlePropertiesInsertManagerImpl implements ResourceBundle
@Override
public void insertTranslation(String key, String value, final PropertiesFile propertiesFile) {
if (myOrdered) {
final Pair<IProperty, Integer> propertyAndPosition = findExistedPrevSiblingProperty(key, propertiesFile);
if (propertyAndPosition == null) {
propertiesFile.addPropertyFirst(key, value);
} else {
propertiesFile.addPropertyAfter(key, value, (Property)propertyAndPosition.getFirst());
if (myAlphaSorted) {
propertiesFile.addProperty(key, value);
return;
}
final Pair<IProperty, Integer> propertyAndPosition = findExistedPrevSiblingProperty(key, propertiesFile);
propertiesFile.addPropertyAfter(key, value, propertyAndPosition == null ? null :(Property)propertyAndPosition.getFirst());
} else {
propertiesFile.addPropertyLast(key, value);
insertPropertyLast(key, value, propertiesFile);
}
}
@@ -100,13 +92,7 @@ public class ResourceBundlePropertiesInsertManagerImpl implements ResourceBundle
if (myKeysOrder.isEmpty()) {
return null;
}
final int prevPosition;
if (myAlphaSorted) {
final int rawInsertionPosition = Collections.binarySearch(myKeysOrder, key);
prevPosition = rawInsertionPosition < 0 ? - rawInsertionPosition - 2 : rawInsertionPosition - 1;
} else {
prevPosition = myKeysOrder.indexOf(key);
}
final int prevPosition = myKeysOrder.indexOf(key);
for (int i = prevPosition; i >= 0 ; i--) {
final String prevKey = myKeysOrder.get(i);
final IProperty property = file.findPropertyByKey(prevKey);
@@ -117,6 +103,12 @@ public class ResourceBundlePropertiesInsertManagerImpl implements ResourceBundle
return null;
}
public void insertPropertyLast(String key, String value, PropertiesFile propertiesFile) {
final List<IProperty> properties = propertiesFile.getProperties();
final IProperty lastProperty = properties.isEmpty() ? null : properties.get(properties.size() - 1);
propertiesFile.addPropertyAfter(key, value, (Property)lastProperty);
}
@Override
public void reload() {
final List<String> keysOrder = keysOrder(myResourceBundle);
@@ -124,7 +116,7 @@ public class ResourceBundlePropertiesInsertManagerImpl implements ResourceBundle
if (myOrdered) {
Collections.reverse(keysOrder);
myAlphaSorted = isAlphaSorted(keysOrder);
myKeysOrder = keysOrder;
myKeysOrder = myAlphaSorted ? null : keysOrder;
} else {
myKeysOrder = null;
}
+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;
}
@@ -601,6 +601,7 @@ unboxing
unbuffered
uncomment
uncommented
uncommenting
undef
underwave
undoable
@@ -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() {
@@ -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());
+25
View File
@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>
<chapter xml:id="TestDocBook"
version="5.0"
xml:lang="en"
role="strong"
xmlns="http://docbook.org/ns/docbook"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xlink="http://www.w3.org/1999/xlink"
xsi:schemaLocation="
http://docbook.org/ns/docbook http://www.docbook.org/xml/5.0/xsd/docbook.xsd
http://www.w3.org/1999/xlink http://www.docbook.org/xml/5.0/xsd/xlink.xsd
">
<title>A simple Test File</title>
<para xlink:role="ss" role="strong">
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut
labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco
laboris nisi ut aliquip ex ea
<emphasis role="strong">commodo</emphasis>
consequat. Duis aute irure dolor in reprehenderit in
voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat
non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
</para>
</chapter>
@@ -217,7 +217,7 @@ public class ComplexTypeDescriptor extends TypeDescriptor {
// Read-only calculation
private XmlAttributeDescriptor[] doCollectAttributes(@Nullable final XmlElement context) {
final List<XmlAttributeDescriptor> result = new ArrayList<XmlAttributeDescriptor>();
final List<XmlAttributeDescriptorImpl> result = new ArrayList<XmlAttributeDescriptorImpl>();
XmlSchemaTagsProcessor processor = new XmlSchemaTagsProcessor(myDocumentDescriptor, "element") {
@Override
@@ -234,7 +234,7 @@ public class ComplexTypeDescriptor extends TypeDescriptor {
if (use == null) use = tag.getAttributeValue("use");
if (PROHIBITED_ATTR_VALUE.equals(use)) {
removeAttributeDescriptor(result, name);
removeAttributeDescriptor(result, name, null);
}
else {
XmlAttributeDescriptorImpl descriptor = myDocumentDescriptor.createAttributeDescriptor(tag);
@@ -260,18 +260,18 @@ public class ComplexTypeDescriptor extends TypeDescriptor {
result.put(element.getName(),element);
}
private static void removeAttributeDescriptor(List<XmlAttributeDescriptor> result, String name) {
for (Iterator<XmlAttributeDescriptor> iterator = result.iterator(); iterator.hasNext();) {
XmlAttributeDescriptor attributeDescriptor = iterator.next();
private static void removeAttributeDescriptor(List<XmlAttributeDescriptorImpl> result, String name, String referenceName) {
for (Iterator<XmlAttributeDescriptorImpl> iterator = result.iterator(); iterator.hasNext();) {
XmlAttributeDescriptorImpl descriptor = iterator.next();
if (attributeDescriptor.getName().equals(name)) {
if (descriptor.getName().equals(name) && (referenceName == null || referenceName.equals(descriptor.myReferenceName))) {
iterator.remove();
}
}
}
private static void addAttributeDescriptor(List<XmlAttributeDescriptor> result, XmlAttributeDescriptor descriptor) {
removeAttributeDescriptor(result, descriptor.getName());
private static void addAttributeDescriptor(List<XmlAttributeDescriptorImpl> result, XmlAttributeDescriptorImpl descriptor) {
removeAttributeDescriptor(result, descriptor.getName(), descriptor.myReferenceName);
result.add(descriptor);
}