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

This commit is contained in:
Kirill Kalishev
2011-03-28 15:45:50 +04:00
7 changed files with 77 additions and 23 deletions
@@ -145,7 +145,8 @@ public abstract class LanguagePerFileMappings<T> implements PersistentStateCompo
}
protected abstract List<T> getAvailableValues();
@Nullable
protected abstract String serialize(T t);
public Element getState() {
@@ -161,10 +162,13 @@ public abstract class LanguagePerFileMappings<T> implements PersistentStateCompo
});
for (VirtualFile file : files) {
final T dialect = myMappings.get(file);
final Element child = new Element("file");
element.addContent(child);
child.setAttribute("url", file == null ? "PROJECT" : file.getUrl());
child.setAttribute(getValueAttribute(), serialize(dialect));
String value = serialize(dialect);
if (value != null) {
final Element child = new Element("file");
element.addContent(child);
child.setAttribute("url", file == null ? "PROJECT" : file.getUrl());
child.setAttribute(getValueAttribute(), value);
}
}
return element;
}
@@ -184,7 +188,10 @@ public abstract class LanguagePerFileMappings<T> implements PersistentStateCompo
synchronized (myMappings) {
final THashMap<String, T> dialectMap = new THashMap<String, T>();
for (T dialect : getAvailableValues()) {
dialectMap.put(serialize(dialect), dialect);
String key = serialize(dialect);
if (key != null) {
dialectMap.put(key, dialect);
}
}
final List<Element> files = state.getChildren("file");
for (Element fileElement : files) {
@@ -162,7 +162,10 @@ public class TextChangesStorage {
int newChangeStart = change.getStart();
int newChangeEnd = change.getEnd();
int storedChangeStart = getChangeIndex(change.getStart());
int clientShift = 0;
int clientShift = 0; // 'Client text' shift before the given change to store. I.e. this value can be subtracted from the
// given change's start/end offsets in order to get original document range affected by the given change.
int changeDiff = change.getText().length() - (change.getEnd() - change.getStart());
boolean updateClientOffsetOnly = false;
if (storedChangeStart < 0) {
storedChangeStart = -storedChangeStart - 1;
@@ -171,9 +174,6 @@ public class TextChangesStorage {
ChangeEntry changeEntry = myChanges.get(storedChangeStart - 1);
clientShift = changeEntry.clientStartOffset - changeEntry.change.getStart() + changeEntry.change.getDiff();
}
}
if (storedChangeStart >= myChanges.size()) {
myChanges.add(new ChangeEntry(
new TextChangeImpl(change.getText(), change.getStart() - clientShift, change.getEnd() - clientShift),
change.getStart()
@@ -192,6 +192,21 @@ public class TextChangesStorage {
CharSequence storedText = changeEntry.change.getText();
int storedClientEnd = storedClientStart + storedText.length();
// Stored change lays after the new one.
if (!updateClientOffsetOnly && storedClientStart > newChangeEnd) {
if (changeDiff != 0) {
updateClientOffsetOnly = true;
}
else {
break;
}
}
if (updateClientOffsetOnly) {
changeEntry.clientStartOffset += changeDiff;
continue;
}
// Stored change lays before the new one.
if (storedClientEnd <= newChangeStart) {
clientShift += changeEntry.change.getDiff();
@@ -199,9 +214,7 @@ public class TextChangesStorage {
continue;
}
// We know that given change and stored change have intersections if control flow reaches this place.
// Check if given change target sub-range of the stored one
// Check if given change targets sub-range of the stored one.
if (storedClientStart <= newChangeStart && storedClientEnd >= newChangeEnd) {
StringBuilder adjustedText = new StringBuilder();
if (storedClientStart < newChangeStart) {
@@ -215,13 +228,15 @@ public class TextChangesStorage {
if (adjustedText.length() == 0 && changeEntry.change.getStart() == changeEntry.change.getEnd()) {
myChanges.remove(i);
insertionIndex = -1;
break;
updateClientOffsetOnly = true;
continue;
}
TextChangeImpl adjusted = new TextChangeImpl(adjustedText, changeEntry.change.getStart(), changeEntry.change.getEnd());
myChanges.set(i, new ChangeEntry(adjusted, adjusted.getStart()));
insertionIndex = -1;
break;
updateClientOffsetOnly = true;
continue;
}
// Check if given change completely contains stored change range.
@@ -234,7 +249,7 @@ public class TextChangesStorage {
}
// Check if given change intersects stored change range from the left.
if (newChangeStart <= storedClientStart && newChangeEnd < storedClientEnd) {
if (newChangeStart <= storedClientStart && newChangeEnd > storedClientStart) {
int numberOfStoredChangeSymbolsToRemove = newChangeEnd - storedClientStart;
CharSequence adjustedText = storedText.subSequence(numberOfStoredChangeSymbolsToRemove, storedText.length());
changeEntry.change = new TextChangeImpl(adjustedText, changeEntry.change.getStart(), changeEntry.change.getEnd());
@@ -244,7 +259,7 @@ public class TextChangesStorage {
}
// Check if given change intersects stored change range from the right.
if (newChangeStart < storedClientEnd && newChangeEnd > storedClientEnd) {
if (newChangeStart < storedClientEnd && newChangeEnd >= storedClientEnd) {
CharSequence adjustedText = storedText.subSequence(0, newChangeStart - storedClientStart);
TextChangeImpl adjusted = new TextChangeImpl(adjustedText, changeEntry.change.getStart(), changeEntry.change.getEnd());
myChanges.set(i, new ChangeEntry(adjusted, adjusted.getStart()));
@@ -64,6 +64,13 @@ public class TextChangesStorageTest {
checkChanges(c("abc", 2), c("def", 3), c("ghi", 5));
}
@Test
public void disconnectedInsertsFromTailToStart() {
insert("abc", 10);
insert("def", 1);
checkChanges(c("def", 1), c("abc", 10));
}
@Test
public void adjacentInserts() {
insert("abc", 2);
@@ -23,7 +23,6 @@ import com.intellij.openapi.roots.libraries.LibraryTable;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.ArrayUtil;
import com.intellij.util.Function;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
@@ -83,8 +82,22 @@ public abstract class AbstractConfigUtils {
*/
@Nullable
public static String getSDKJarVersion(String jarPath, final String jarRegex, String manifestPath) {
return getSDKJarVersion(jarPath, Pattern.compile(jarRegex), manifestPath);
}
/**
* Return value of Implementation-Version attribute in jar manifest
* <p/>
*
* @param jarPath directory containing jar file
* @param jarPattern filename pattern for jar file
* @param manifestPath path to manifest file in jar file
* @return value of Implementation-Version attribute, null if not found
*/
@Nullable
public static String getSDKJarVersion(String jarPath, final Pattern jarPattern, String manifestPath) {
try {
File[] jars = GroovyUtils.getFilesInDirectoryByPattern(jarPath, jarRegex);
File[] jars = GroovyUtils.getFilesInDirectoryByPattern(jarPath, jarPattern);
if (jars.length != 1) {
return null;
}
@@ -107,7 +120,7 @@ public abstract class AbstractConfigUtils {
return version;
}
final Matcher matcher = Pattern.compile(jarRegex).matcher(jars[0].getName());
final Matcher matcher = jarPattern.matcher(jars[0].getName());
if (matcher.matches() && matcher.groupCount() == 1) {
return matcher.group(1);
}
@@ -42,7 +42,7 @@ public class GroovyHotSwapper extends JavaProgramPatcher {
return true;
}
}
return true;
return false;
}
private static boolean containsGroovyClasses(Project project) {
@@ -23,7 +23,9 @@ import com.intellij.openapi.fileChooser.FileChooserDescriptor;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.options.ConfigurationException;
import com.intellij.openapi.options.SettingsEditor;
import com.intellij.openapi.roots.ui.configuration.ModulesAlphaComparator;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.ui.ComboboxSpeedSearch;
import com.intellij.ui.FieldPanel;
import com.intellij.ui.RawCommandLineEditor;
import org.jetbrains.annotations.NotNull;
@@ -31,6 +33,8 @@ import org.jetbrains.plugins.groovy.GroovyFileType;
import javax.swing.*;
import java.awt.*;
import java.util.*;
import java.util.List;
public class GroovyRunConfigurationEditor extends SettingsEditor<GroovyScriptRunConfiguration> {
private DefaultComboBoxModel myModulesModel;
@@ -84,7 +88,9 @@ public class GroovyRunConfigurationEditor extends SettingsEditor<GroovyScriptRun
myDebugCB.setSelected(configuration.isDebugEnabled());
myModulesModel.removeAllElements();
for (Module module : configuration.getValidModules()) {
List<Module> modules = new ArrayList<Module>(configuration.getValidModules());
Collections.sort(modules, ModulesAlphaComparator.INSTANCE);
for (Module module : modules) {
myModulesModel.addElement(module);
}
myModulesModel.setSelectedItem(configuration.getModule());
@@ -118,6 +124,12 @@ public class GroovyRunConfigurationEditor extends SettingsEditor<GroovyScriptRun
}
}
});
new ComboboxSpeedSearch(myModulesBox) {
@Override
protected String getElementText(Object element) {
return element instanceof Module ? ((Module)element).getName() : "";
}
};
return myMainPanel;
}
@@ -60,7 +60,7 @@ public class XmlUnwrapDescriptor implements UnwrapDescriptor {
PsiElement tag = PsiTreeUtil.getParentOfType(e, XmlTag.class);
while (tag != null) {
if (XmlChildRole.START_TAG_END_FINDER.findChild(tag.getNode()) != null) { // Exclude implicit tags suck as 'jsp:root'
if (XmlChildRole.START_TAG_NAME_FINDER.findChild(tag.getNode()) != null) { // Exclude implicit tags suck as 'jsp:root'
result.add(new Pair<PsiElement, Unwrapper>(tag, new XmlEnclosingTagUnwrapper()));
}
tag = PsiTreeUtil.getParentOfType(tag, XmlTag.class);