mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Merge remote-tracking branch 'origin/master'
This commit is contained in:
@@ -21,7 +21,7 @@
|
||||
|
||||
<intentionAction>
|
||||
<className>org.intellij.lang.regexp.intention.CheckRegExpIntentionAction</className>
|
||||
<category>Declaration</category>
|
||||
<category>RegExp/Declaration</category>
|
||||
</intentionAction>
|
||||
</extensions>
|
||||
</idea-plugin>
|
||||
|
||||
@@ -27,6 +27,7 @@ import com.intellij.openapi.fileEditor.OpenFileDescriptor;
|
||||
import com.intellij.openapi.ide.CopyPasteManager;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.codeStyle.CodeStyleManager;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
@@ -128,7 +129,8 @@ public class JavaFilePasteProvider implements PasteProvider {
|
||||
private static PsiJavaFile createJavaFileFromClipboardContent(final Project project) {
|
||||
String text = CopyPasteManager.getInstance().getContents(DataFlavor.stringFlavor);
|
||||
if (text == null) return null;
|
||||
PsiFile psiFile = PsiFileFactory.getInstance(project).createFileFromText("A.java", JavaLanguage.INSTANCE, text);
|
||||
PsiFile psiFile = PsiFileFactory.getInstance(project).createFileFromText("A.java", JavaLanguage.INSTANCE,
|
||||
StringUtil.convertLineSeparators(text));
|
||||
return psiFile instanceof PsiJavaFile ? (PsiJavaFile)psiFile : null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -72,7 +72,6 @@ public class JavaLanguageCodeStyleSettingsProvider extends LanguageCodeStyleSett
|
||||
}
|
||||
else if (settingsType == SettingsType.WRAPPING_AND_BRACES_SETTINGS) {
|
||||
consumer.showStandardOptions("RIGHT_MARGIN",
|
||||
"WRAP_ON_TYPING",
|
||||
"KEEP_CONTROL_STATEMENT_IN_ONE_LINE",
|
||||
"LINE_COMMENT_AT_FIRST_COLUMN",
|
||||
"BLOCK_COMMENT_AT_FIRST_COLUMN",
|
||||
|
||||
@@ -412,7 +412,7 @@ public class ImportHelper{
|
||||
useOnDemand = false;
|
||||
}
|
||||
// name of class we try to import is the same as of the class defined in this file
|
||||
if (curRefClass != null) {
|
||||
if (containsInCurrentFile(file, curRefClass)) {
|
||||
useOnDemand = true;
|
||||
}
|
||||
// check conflicts
|
||||
@@ -428,10 +428,9 @@ public class ImportHelper{
|
||||
}
|
||||
|
||||
if (useOnDemand &&
|
||||
curRefClass != null &&
|
||||
refClass.getContainingClass() != null &&
|
||||
mySettings.INSERT_INNER_CLASS_IMPORTS &&
|
||||
"java.lang".equals(StringUtil.getPackageName(curRefClass.getQualifiedName()))) {
|
||||
containsInCurrentFile(file, curRefClass)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -465,6 +464,17 @@ public class ImportHelper{
|
||||
return true;
|
||||
}
|
||||
|
||||
private static boolean containsInCurrentFile(@NotNull PsiJavaFile file, PsiClass curRefClass) {
|
||||
if (curRefClass != null) {
|
||||
final String curRefClassQualifiedName = curRefClass.getQualifiedName();
|
||||
if (curRefClassQualifiedName != null &&
|
||||
ArrayUtil.find(file.getImplicitlyImportedPackages(), StringUtil.getPackageName(curRefClassQualifiedName)) < 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static void calcClassesToReimport(PsiJavaFile file, JavaPsiFacade facade, PsiResolveHelper helper, String packageName, List<PsiClass> classesToReimport,
|
||||
Collection<String> onDemandRefs) {
|
||||
if (onDemandRefs.isEmpty()) {
|
||||
|
||||
+18
-12
@@ -81,7 +81,7 @@ public class AllClassesSearchExecutor implements QueryExecutor<PsiClass, AllClas
|
||||
final PsiShortNamesCache cache = PsiShortNamesCache.getInstance(project);
|
||||
for (final String name : names) {
|
||||
ProgressIndicatorProvider.checkCanceled();
|
||||
final PsiClass[] classes = ApplicationManager.getApplication().runReadAction(new Computable<PsiClass[]>() {
|
||||
final PsiClass[] classes = MethodUsagesSearcher.resolveInReadAction(project, new Computable<PsiClass[]>() {
|
||||
@Override
|
||||
public PsiClass[] compute() {
|
||||
return cache.getClassesByName(name, scope);
|
||||
@@ -97,21 +97,27 @@ public class AllClassesSearchExecutor implements QueryExecutor<PsiClass, AllClas
|
||||
return true;
|
||||
}
|
||||
|
||||
public static Project processClassNames(Project project, GlobalSearchScope scope, final Consumer<String> consumer) {
|
||||
public static Project processClassNames(final Project project, final GlobalSearchScope scope, final Consumer<String> consumer) {
|
||||
final ProgressIndicator indicator = ProgressIndicatorProvider.getGlobalProgressIndicator();
|
||||
|
||||
PsiShortNamesCache.getInstance(project).processAllClassNames(new Processor<String>() {
|
||||
int i = 0;
|
||||
|
||||
MethodUsagesSearcher.resolveInReadAction(project, new Computable<Void>() {
|
||||
@Override
|
||||
public boolean process(String s) {
|
||||
if (indicator != null && i++ % 512 == 0) {
|
||||
indicator.checkCanceled();
|
||||
}
|
||||
consumer.consume(s);
|
||||
return true;
|
||||
public Void compute() {
|
||||
PsiShortNamesCache.getInstance(project).processAllClassNames(new Processor<String>() {
|
||||
int i = 0;
|
||||
|
||||
@Override
|
||||
public boolean process(String s) {
|
||||
if (indicator != null && i++ % 512 == 0) {
|
||||
indicator.checkCanceled();
|
||||
}
|
||||
consumer.consume(s);
|
||||
return true;
|
||||
}
|
||||
}, scope, IdFilter.getProjectIdFilter(project, true));
|
||||
return null;
|
||||
}
|
||||
}, scope, IdFilter.getProjectIdFilter(project, true));
|
||||
});
|
||||
|
||||
if (indicator != null) {
|
||||
indicator.checkCanceled();
|
||||
|
||||
@@ -1262,13 +1262,12 @@ class ControlFlowAnalyzer extends JavaElementVisitor {
|
||||
myStartStatementStack.pushStatement(expression.getRExpression() == null ? expression : expression.getRExpression(), false);
|
||||
myEndStatementStack.pushStatement(expression.getRExpression() == null ? expression : expression.getRExpression(), false);
|
||||
|
||||
PsiExpression rExpr = expression.getRExpression();
|
||||
if (rExpr != null) {
|
||||
rExpr.accept(this);
|
||||
}
|
||||
|
||||
PsiExpression lExpr = PsiUtil.skipParenthesizedExprDown(expression.getLExpression());
|
||||
if (lExpr instanceof PsiReferenceExpression) {
|
||||
PsiExpression rExpr = expression.getRExpression();
|
||||
if (rExpr != null) {
|
||||
rExpr.accept(this);
|
||||
}
|
||||
final PsiReferenceExpression referenceExpression = (PsiReferenceExpression)lExpr;
|
||||
PsiExpression qualifierExpression = referenceExpression.getQualifierExpression();
|
||||
PsiVariable variable = getUsedVariable(referenceExpression);
|
||||
@@ -1293,6 +1292,10 @@ class ControlFlowAnalyzer extends JavaElementVisitor {
|
||||
}
|
||||
else if (lExpr != null) {
|
||||
lExpr.accept(this);
|
||||
PsiExpression rExpr = expression.getRExpression();
|
||||
if (rExpr != null) {
|
||||
rExpr.accept(this);
|
||||
}
|
||||
}
|
||||
|
||||
myStartStatementStack.popStatement();
|
||||
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
class Test {
|
||||
public static void main(String[] args) {
|
||||
int i;
|
||||
int[] iA = {10,20};
|
||||
iA[<error descr="Variable 'i' might not have been initialized">i</error>] = i = 30;
|
||||
}
|
||||
}
|
||||
+4
@@ -63,4 +63,8 @@ public class LightAdvHighlightingJdk6Test extends LightDaemonAnalyzerTestCase {
|
||||
public void testAgentPremain() {
|
||||
doTest(false, false);
|
||||
}
|
||||
|
||||
public void testInitializedBeforeUsed() throws Exception {
|
||||
doTest(false, false);
|
||||
}
|
||||
}
|
||||
|
||||
+4
-1
@@ -17,8 +17,11 @@ package com.intellij.codeInsight.intention
|
||||
|
||||
import com.intellij.lang.java.JavaLanguage;
|
||||
import com.intellij.pom.java.LanguageLevel
|
||||
import com.intellij.psi.PsiClass
|
||||
import com.intellij.psi.PsiFile
|
||||
import com.intellij.psi.codeStyle.CodeStyleSettings
|
||||
import com.intellij.psi.codeStyle.CodeStyleSettingsManager
|
||||
import com.intellij.psi.impl.source.codeStyle.ImportHelper
|
||||
import com.intellij.testFramework.IdeaTestUtil
|
||||
import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase
|
||||
|
||||
@@ -74,7 +77,7 @@ public class Foo {
|
||||
}
|
||||
'''
|
||||
importClass()
|
||||
myFixture.checkResult '''import foo.*;
|
||||
myFixture.checkResult '''import foo.StringValue;
|
||||
|
||||
public class Foo {
|
||||
String<caret>Value sv;
|
||||
|
||||
@@ -462,25 +462,7 @@ public class FindManagerTest extends DaemonAnalyzerTestCase {
|
||||
}
|
||||
|
||||
public void testReplaceWithRegExp() {
|
||||
FindModel findModel = new FindModel();
|
||||
findModel.setStringToFind("(?<!^) ");
|
||||
findModel.setStringToReplace(" ");
|
||||
findModel.setWholeWordsOnly(false);
|
||||
findModel.setRegularExpressions(true);
|
||||
findModel.setFromCursor(false);
|
||||
findModel.setGlobal(true);
|
||||
findModel.setMultipleFiles(false);
|
||||
findModel.setProjectScope(false);
|
||||
findModel.setPromptOnReplace(false);
|
||||
|
||||
myFindManager.setFindNextModel(null);
|
||||
myFindManager.getFindInFileModel().copyFrom(findModel);
|
||||
|
||||
String text = "# Base";
|
||||
configureByText(PlainTextFileType.INSTANCE, text);
|
||||
assertTrue(FindUtil.replace(getProject(), getEditor(), 0, findModel));
|
||||
|
||||
assertEquals("# Base", getEditor().getDocument().getText());
|
||||
doTestRegexpReplace("# Base", "(?<!^) ", " ", "# Base");
|
||||
}
|
||||
|
||||
private void initProject(String folderName, final String... sourceDirs) {
|
||||
|
||||
@@ -9,15 +9,15 @@
|
||||
<conversion.rule implementation="com.intellij.refactoring.typeMigration.rules.ThreadLocalConversionRule"/>
|
||||
<intentionAction>
|
||||
<className>com.intellij.refactoring.typeMigration.intentions.ConvertFieldToAtomicIntention</className>
|
||||
<category>Concurrency</category>
|
||||
<category>Java/Concurrency</category>
|
||||
</intentionAction>
|
||||
<intentionAction>
|
||||
<className>com.intellij.refactoring.typeMigration.intentions.ConvertFieldToThreadLocalIntention</className>
|
||||
<category>Concurrency</category>
|
||||
<category>Java/Concurrency</category>
|
||||
</intentionAction>
|
||||
<intentionAction>
|
||||
<className>com.intellij.refactoring.typeMigration.intentions.ChangeClassParametersIntention</className>
|
||||
<category>Declaration</category>
|
||||
<category>Java/Declaration</category>
|
||||
</intentionAction>
|
||||
</extensions>
|
||||
</idea-plugin>
|
||||
|
||||
@@ -37,29 +37,14 @@ public class FileTypeAssocTable<T> {
|
||||
private final Map<CharSequence, T> myExtensionMappings;
|
||||
private final Map<CharSequence, T> myExactFileNameMappings;
|
||||
private final Map<CharSequence, T> myExactFileNameAnyCaseMappings;
|
||||
private boolean myHasAnyCaseExactMappings;
|
||||
private final List<Pair<FileNameMatcher, T>> myMatchingMappings;
|
||||
|
||||
private FileTypeAssocTable(Map<CharSequence, T> extensionMappings, Map<CharSequence, T> exactFileNameMappings, Map<CharSequence, T> exactFileNameAnyCaseMappings, List<Pair<FileNameMatcher, T>> matchingMappings) {
|
||||
private FileTypeAssocTable(@NotNull Map<CharSequence, T> extensionMappings, @NotNull Map<CharSequence, T> exactFileNameMappings, @NotNull Map<CharSequence, T> exactFileNameAnyCaseMappings, List<Pair<FileNameMatcher, T>> matchingMappings) {
|
||||
myExtensionMappings = new THashMap<CharSequence, T>(extensionMappings, CharSequenceHashingStrategy.CASE_INSENSITIVE);
|
||||
|
||||
myExactFileNameMappings = new THashMap<CharSequence, T>(exactFileNameMappings, CharSequenceHashingStrategy.CASE_SENSITIVE);
|
||||
|
||||
myExactFileNameAnyCaseMappings = new THashMap<CharSequence, T>(exactFileNameAnyCaseMappings, CharSequenceHashingStrategy.CASE_INSENSITIVE) {
|
||||
@Override
|
||||
public T remove(Object key) {
|
||||
T removed = super.remove(key);
|
||||
myHasAnyCaseExactMappings = size() > 0;
|
||||
return removed;
|
||||
}
|
||||
myExactFileNameAnyCaseMappings = new THashMap<CharSequence, T>(exactFileNameAnyCaseMappings, CharSequenceHashingStrategy.CASE_INSENSITIVE);
|
||||
|
||||
@Override
|
||||
public T put(CharSequence key, T value) {
|
||||
T result = super.put(key, value);
|
||||
myHasAnyCaseExactMappings = true;
|
||||
return result;
|
||||
}
|
||||
};
|
||||
myMatchingMappings = new ArrayList<Pair<FileNameMatcher, T>>(matchingMappings);
|
||||
}
|
||||
|
||||
@@ -67,7 +52,7 @@ public class FileTypeAssocTable<T> {
|
||||
this(Collections.<CharSequence, T>emptyMap(), Collections.<CharSequence, T>emptyMap(), Collections.<CharSequence, T>emptyMap(), Collections.<Pair<FileNameMatcher, T>>emptyList());
|
||||
}
|
||||
|
||||
public boolean isAssociatedWith(T type, FileNameMatcher matcher) {
|
||||
public boolean isAssociatedWith(@NotNull T type, @NotNull FileNameMatcher matcher) {
|
||||
if (matcher instanceof ExtensionFileNameMatcher || matcher instanceof ExactFileNameMatcher) {
|
||||
return findAssociatedFileType(matcher) == type;
|
||||
}
|
||||
@@ -86,17 +71,15 @@ public class FileTypeAssocTable<T> {
|
||||
else if (matcher instanceof ExactFileNameMatcher) {
|
||||
final ExactFileNameMatcher exactFileNameMatcher = (ExactFileNameMatcher)matcher;
|
||||
|
||||
if (exactFileNameMatcher.isIgnoreCase()) {
|
||||
myExactFileNameAnyCaseMappings.put(exactFileNameMatcher.getFileName(), type);
|
||||
} else {
|
||||
myExactFileNameMappings.put(exactFileNameMatcher.getFileName(), type);
|
||||
}
|
||||
} else {
|
||||
Map<CharSequence, T> mapToUse = exactFileNameMatcher.isIgnoreCase() ? myExactFileNameAnyCaseMappings : myExactFileNameMappings;
|
||||
mapToUse.put(exactFileNameMatcher.getFileName(), type);
|
||||
}
|
||||
else {
|
||||
myMatchingMappings.add(Pair.create(matcher, type));
|
||||
}
|
||||
}
|
||||
|
||||
public boolean removeAssociation(FileNameMatcher matcher, T type) {
|
||||
boolean removeAssociation(@NotNull FileNameMatcher matcher, @NotNull T type) {
|
||||
if (matcher instanceof ExtensionFileNameMatcher) {
|
||||
String extension = ((ExtensionFileNameMatcher)matcher).getExtension();
|
||||
if (myExtensionMappings.get(extension) == type) {
|
||||
@@ -108,14 +91,9 @@ public class FileTypeAssocTable<T> {
|
||||
|
||||
if (matcher instanceof ExactFileNameMatcher) {
|
||||
final ExactFileNameMatcher exactFileNameMatcher = (ExactFileNameMatcher)matcher;
|
||||
final Map<CharSequence, T> mapToUse;
|
||||
String fileName = exactFileNameMatcher.getFileName();
|
||||
|
||||
if (exactFileNameMatcher.isIgnoreCase()) {
|
||||
mapToUse = myExactFileNameAnyCaseMappings;
|
||||
} else {
|
||||
mapToUse = myExactFileNameMappings;
|
||||
}
|
||||
final Map<CharSequence, T> mapToUse = exactFileNameMatcher.isIgnoreCase() ? myExactFileNameAnyCaseMappings : myExactFileNameMappings;
|
||||
if(mapToUse.get(fileName) == type) {
|
||||
mapToUse.remove(fileName);
|
||||
return true;
|
||||
@@ -134,7 +112,7 @@ public class FileTypeAssocTable<T> {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean removeAllAssociations(T type) {
|
||||
boolean removeAllAssociations(@NotNull T type) {
|
||||
boolean changed = removeAssociationsFromMap(myExtensionMappings, type, false);
|
||||
|
||||
changed = removeAssociationsFromMap(myExactFileNameAnyCaseMappings, type, changed);
|
||||
@@ -151,7 +129,7 @@ public class FileTypeAssocTable<T> {
|
||||
return changed;
|
||||
}
|
||||
|
||||
private boolean removeAssociationsFromMap(Map<CharSequence, T> extensionMappings, T type, boolean changed) {
|
||||
private boolean removeAssociationsFromMap(@NotNull Map<CharSequence, T> extensionMappings, @NotNull T type, boolean changed) {
|
||||
Set<CharSequence> exts = extensionMappings.keySet();
|
||||
CharSequence[] extsStrings = exts.toArray(new CharSequence[exts.size()]);
|
||||
for (CharSequence s : extsStrings) {
|
||||
@@ -165,16 +143,18 @@ public class FileTypeAssocTable<T> {
|
||||
|
||||
@Nullable
|
||||
public T findAssociatedFileType(@NotNull @NonNls CharSequence fileName) {
|
||||
T t = myExactFileNameMappings.get(fileName);
|
||||
if (t != null) return t;
|
||||
if (!myExactFileNameMappings.isEmpty()) {
|
||||
T t = myExactFileNameMappings.get(fileName);
|
||||
if (t != null) return t;
|
||||
}
|
||||
|
||||
if (myHasAnyCaseExactMappings) { // even hash lookup with case insensitive hasher is costly for isIgnored checks during compile
|
||||
t = myExactFileNameAnyCaseMappings.get(fileName);
|
||||
if (!myExactFileNameAnyCaseMappings.isEmpty()) { // even hash lookup with case insensitive hasher is costly for isIgnored checks during compile
|
||||
T t = myExactFileNameAnyCaseMappings.get(fileName);
|
||||
if (t != null) return t;
|
||||
}
|
||||
|
||||
//noinspection ForLoopReplaceableByForEach
|
||||
for (int i = 0, n = myMatchingMappings.size(); i < n; i++) {
|
||||
for (int i = 0; i < myMatchingMappings.size(); i++) {
|
||||
final Pair<FileNameMatcher, T> mapping = myMatchingMappings.get(i);
|
||||
if (FileNameMatcherEx.acceptsCharSequence(mapping.getFirst(), fileName)) return mapping.getSecond();
|
||||
}
|
||||
@@ -183,7 +163,7 @@ public class FileTypeAssocTable<T> {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public T findAssociatedFileType(final FileNameMatcher matcher) {
|
||||
public T findAssociatedFileType(@NotNull FileNameMatcher matcher) {
|
||||
if (matcher instanceof ExtensionFileNameMatcher) {
|
||||
return myExtensionMappings.get(((ExtensionFileNameMatcher)matcher).getExtension());
|
||||
}
|
||||
@@ -191,11 +171,8 @@ public class FileTypeAssocTable<T> {
|
||||
if (matcher instanceof ExactFileNameMatcher) {
|
||||
final ExactFileNameMatcher exactFileNameMatcher = (ExactFileNameMatcher)matcher;
|
||||
|
||||
if (exactFileNameMatcher.isIgnoreCase()) {
|
||||
return myExactFileNameAnyCaseMappings.get(exactFileNameMatcher.getFileName());
|
||||
} else {
|
||||
return myExactFileNameMappings.get(exactFileNameMatcher.getFileName());
|
||||
}
|
||||
Map<CharSequence, T> mapToUse = exactFileNameMatcher.isIgnoreCase() ? myExactFileNameAnyCaseMappings : myExactFileNameMappings;
|
||||
return mapToUse.get(exactFileNameMatcher.getFileName());
|
||||
}
|
||||
|
||||
for (Pair<FileNameMatcher, T> mapping : myMatchingMappings) {
|
||||
@@ -207,13 +184,13 @@ public class FileTypeAssocTable<T> {
|
||||
|
||||
@Deprecated
|
||||
@NotNull
|
||||
public String[] getAssociatedExtensions(T type) {
|
||||
public String[] getAssociatedExtensions(@NotNull T type) {
|
||||
Map<CharSequence, T> extMap = myExtensionMappings;
|
||||
|
||||
List<String> exts = new ArrayList<String>();
|
||||
for (CharSequence ext : extMap.keySet()) {
|
||||
if (extMap.get(ext) == type) {
|
||||
exts.add(ext.toString());
|
||||
for (Map.Entry<CharSequence, T> entry : extMap.entrySet()) {
|
||||
if (entry.getValue() == type) {
|
||||
exts.add(entry.getKey().toString());
|
||||
}
|
||||
}
|
||||
return ArrayUtil.toStringArray(exts);
|
||||
@@ -284,8 +261,7 @@ public class FileTypeAssocTable<T> {
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
int result;
|
||||
result = myExtensionMappings.hashCode();
|
||||
int result = myExtensionMappings.hashCode();
|
||||
result = 31 * result + myMatchingMappings.hashCode();
|
||||
result = 31 * result + myExactFileNameMappings.hashCode();
|
||||
result = 31 * result + myExactFileNameAnyCaseMappings.hashCode();
|
||||
|
||||
@@ -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.
|
||||
@@ -31,6 +31,7 @@ public class IgnoredPatternSet {
|
||||
private final Set<String> myMasks = new LinkedHashSet<String>();
|
||||
private final FileTypeAssocTable<Boolean> myIgnorePatterns = new FileTypeAssocTable<Boolean>().copy();
|
||||
|
||||
@NotNull
|
||||
Set<String> getIgnoreMasks() {
|
||||
return Collections.unmodifiableSet(myMasks);
|
||||
}
|
||||
@@ -41,9 +42,7 @@ public class IgnoredPatternSet {
|
||||
StringTokenizer tokenizer = new StringTokenizer(list, ";");
|
||||
while (tokenizer.hasMoreTokens()) {
|
||||
String ignoredFile = tokenizer.nextToken();
|
||||
if (ignoredFile != null) {
|
||||
addIgnoreMask(ignoredFile);
|
||||
}
|
||||
addIgnoreMask(ignoredFile);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -64,7 +63,7 @@ public class IgnoredPatternSet {
|
||||
return fileName.endsWith(FileUtil.ASYNC_DELETE_EXTENSION);
|
||||
}
|
||||
|
||||
public void clearPatterns() {
|
||||
void clearPatterns() {
|
||||
myMasks.clear();
|
||||
myIgnorePatterns.removeAllAssociations(Boolean.TRUE);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package org.jetbrains.ide
|
||||
|
||||
import com.intellij.testFramework.FixtureRule
|
||||
import com.intellij.util.Consumer
|
||||
import com.intellij.util.concurrency.Semaphore
|
||||
import com.intellij.util.net.NetUtils
|
||||
@@ -17,7 +18,6 @@ import org.jetbrains.io.ChannelExceptionHandler
|
||||
import org.jetbrains.io.Decoder
|
||||
import org.jetbrains.io.MessageDecoder
|
||||
import org.jetbrains.io.NettyUtil
|
||||
import org.jetbrains.testFramework.FixtureRule
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.rules.RuleChain
|
||||
|
||||
@@ -2,10 +2,10 @@ package org.jetbrains.ide
|
||||
|
||||
import com.google.gson.stream.JsonWriter
|
||||
import com.intellij.openapi.vfs.CharsetToolkit
|
||||
import com.intellij.testFramework.FixtureRule
|
||||
import io.netty.handler.codec.http.HttpResponseStatus
|
||||
import org.hamcrest.CoreMatchers.equalTo
|
||||
import org.jetbrains.ide.TestManager.TestDescriptor
|
||||
import org.jetbrains.testFramework.FixtureRule
|
||||
import org.junit.Assert.assertThat
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
|
||||
@@ -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.
|
||||
@@ -29,7 +29,7 @@ import org.jetbrains.annotations.Nullable;
|
||||
public abstract class FileTypeRegistry {
|
||||
public static Getter<FileTypeRegistry> ourInstanceGetter;
|
||||
|
||||
public abstract boolean isFileIgnored(@NonNls @NotNull VirtualFile file);
|
||||
public abstract boolean isFileIgnored(@NotNull VirtualFile file);
|
||||
|
||||
public static FileTypeRegistry getInstance() {
|
||||
return ourInstanceGetter.get();
|
||||
@@ -86,7 +86,7 @@ public abstract class FileTypeRegistry {
|
||||
* Finds a file type with the specified name.
|
||||
*/
|
||||
@Nullable
|
||||
public abstract FileType findFileTypeByName(String fileTypeName);
|
||||
public abstract FileType findFileTypeByName(@NotNull String fileTypeName);
|
||||
|
||||
/**
|
||||
* Pluggable file type detector by content
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
* Copyright 2000-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -70,7 +70,8 @@ public class PsiFileStubImpl<T extends PsiFile> extends StubBase<T> implements P
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiFileStub[] getStubRoots() {
|
||||
return myStubRoots != null ? myStubRoots : new PsiFileStub[]{this};
|
||||
PsiFileStub[] roots = myStubRoots;
|
||||
return roots == null ? new PsiFileStub[]{this} : roots;
|
||||
}
|
||||
|
||||
public void setStubRoots(@NotNull PsiFileStub[] roots) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2011 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.
|
||||
@@ -43,7 +43,7 @@ public class CoreFileTypeRegistry extends FileTypeRegistry {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFileIgnored(@NonNls @NotNull VirtualFile file) {
|
||||
public boolean isFileIgnored(@NotNull VirtualFile file) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -93,7 +93,7 @@ public class CoreFileTypeRegistry extends FileTypeRegistry {
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public FileType findFileTypeByName(String fileTypeName) {
|
||||
public FileType findFileTypeByName(@NotNull String fileTypeName) {
|
||||
for (FileType type : myAllFileTypes) {
|
||||
if (type.getName().equals(fileTypeName)) {
|
||||
return type;
|
||||
|
||||
@@ -1,705 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2014 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.editor.impl;
|
||||
|
||||
import com.intellij.diagnostic.Dumpable;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.application.impl.ApplicationInfoImpl;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.editor.event.DocumentEvent;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.util.LocalTimeCounter;
|
||||
import com.intellij.util.text.CharArrayCharSequence;
|
||||
import com.intellij.util.text.CharArrayUtil;
|
||||
import com.intellij.util.text.CharSequenceBackedByArray;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.lang.ref.Reference;
|
||||
import java.lang.ref.SoftReference;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author cdr
|
||||
*/
|
||||
abstract class CharArray implements CharSequenceBackedByArray, Dumpable {
|
||||
private static final boolean CHECK_DOCUMENT_CONSISTENCY = ApplicationManager.getApplication() != null && ApplicationManager.getApplication().isUnitTestMode();
|
||||
private static final Logger LOG = Logger.getInstance("#" + CharArray.class.getName());
|
||||
|
||||
@SuppressWarnings("UseOfArchaicSystemPropertyAccessors")
|
||||
private static final boolean DISABLE_DEFERRED_PROCESSING = Boolean.getBoolean("idea.document.deny.deferred.changes");
|
||||
|
||||
@SuppressWarnings("UseOfArchaicSystemPropertyAccessors")
|
||||
private static final boolean DEBUG_DEFERRED_PROCESSING = LOG.isDebugEnabled() || Boolean.getBoolean("idea.document.debug.bulk.processing");
|
||||
/**
|
||||
* We can't exclude possibility of situation when <code>'defer changes'</code> state is {@link #setDeferredChangeMode(boolean) entered}
|
||||
* but not exited, hence, we want to perform automatic flushing if necessary in order to avoid memory leaks. This constant holds
|
||||
* a value that defines that 'automatic flushing' criteria, i.e. every time number of stored deferred changes exceeds this value,
|
||||
* they are automatically flushed.
|
||||
*/
|
||||
private static final int MAX_DEFERRED_CHANGES_NUMBER = 10000;
|
||||
|
||||
private final TextChangesStorage myDeferredChangesStorage;
|
||||
|
||||
private volatile int myStart; // start offset in myArray (used as an optimization when call substring())
|
||||
private volatile int myCount;
|
||||
|
||||
private volatile CharSequence myOriginalSequence;
|
||||
private volatile char[] myArray;
|
||||
private volatile Reference<String> myStringRef; // buffers String value - for not to generate it every time
|
||||
private volatile int myBufferSize;
|
||||
private volatile int myDeferredShift;
|
||||
private volatile boolean myDeferredChangeMode;
|
||||
private volatile boolean myHasDeferredChanges;
|
||||
// this lock is for mutual exclusion during read action access
|
||||
// (some fields are changed in read action too)
|
||||
private final Object lock = new String("myOriginalSequence");
|
||||
|
||||
// We had a problems with bulk document text processing, hence, debug facilities were introduced. The fields group below work with them.
|
||||
// The main idea is to hold all history of bulk processing iteration in order to be able to retrieve it from client and reproduce the
|
||||
// problem.
|
||||
|
||||
private final boolean myDebug = isDebug();
|
||||
|
||||
boolean isDebug() {
|
||||
return DEBUG_DEFERRED_PROCESSING || CHECK_DOCUMENT_CONSISTENCY && !ApplicationInfoImpl.isInPerformanceTest();
|
||||
}
|
||||
|
||||
/**
|
||||
* Duplicate instance of the current char array that is used during debug processing as follows - apply every text change
|
||||
* from the bulk changes group to this instance immediately in order to be able to check if the current 'deferred change-aware'
|
||||
* instance functionally behaves at the same way as 'straightforward' one.
|
||||
*/
|
||||
private CharArray myDebugArray;
|
||||
|
||||
/**
|
||||
* Holds deferred changes create during the current bulk processing iteration.
|
||||
*/
|
||||
private List<TextChangeImpl> myDebugDeferredChanges;
|
||||
|
||||
/**
|
||||
* Document text on bulk processing start.
|
||||
*/
|
||||
private String myDebugTextOnBatchUpdateStart;
|
||||
|
||||
// bufferSize == 0 means unbounded
|
||||
CharArray(final int bufferSize, @NotNull char[] data, int length) {
|
||||
myBufferSize = bufferSize;
|
||||
myDeferredChangesStorage = new TextChangesStorage();
|
||||
myArray = Arrays.copyOf(data, length);
|
||||
myCount = length;
|
||||
|
||||
if (myDebug) {
|
||||
myDebugArray = new CharArray(bufferSize, data, length) {
|
||||
@NotNull
|
||||
@Override
|
||||
protected DocumentEvent beforeChangedUpdate(int offset,
|
||||
CharSequence oldString,
|
||||
CharSequence newString,
|
||||
boolean wholeTextReplaced) {
|
||||
return CharArray.this.beforeChangedUpdate(offset, oldString, newString, wholeTextReplaced);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void afterChangedUpdate(@NotNull DocumentEvent event, long newModificationStamp) {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void assertWriteAccess() {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void assertReadAccess() {
|
||||
}
|
||||
|
||||
@Override
|
||||
boolean isDebug() {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
myDebugDeferredChanges = new ArrayList<TextChangeImpl>();
|
||||
}
|
||||
assertConsistency();
|
||||
}
|
||||
|
||||
public void setBufferSize(int bufferSize) {
|
||||
assert bufferSize >= 0 : bufferSize;
|
||||
myBufferSize = bufferSize;
|
||||
assertConsistency();
|
||||
}
|
||||
|
||||
private DocumentEvent startChange(int offset,
|
||||
@Nullable CharSequence oldString,
|
||||
@Nullable CharSequence newString,
|
||||
boolean wholeTextReplaced) {
|
||||
assert myStart == 0; // can't change substring
|
||||
assertWriteAccess();
|
||||
assertConsistency();
|
||||
|
||||
return beforeChangedUpdate(offset, oldString, newString, wholeTextReplaced);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
protected abstract DocumentEvent beforeChangedUpdate(int offset,
|
||||
@Nullable CharSequence oldString,
|
||||
@Nullable CharSequence newString,
|
||||
boolean wholeTextReplaced);
|
||||
protected abstract void afterChangedUpdate(@NotNull DocumentEvent event, long newModificationStamp);
|
||||
|
||||
protected abstract void assertWriteAccess();
|
||||
protected abstract void assertReadAccess();
|
||||
|
||||
private void setText(@NotNull CharSequence chars) {
|
||||
assertConsistency();
|
||||
myOriginalSequence = chars.toString();
|
||||
myArray = null;
|
||||
myStringRef = null;
|
||||
myCount = chars.length();
|
||||
assert myStart == 0; // can't change substring
|
||||
myDeferredChangesStorage.clear();
|
||||
myHasDeferredChanges = false;
|
||||
trimToSize();
|
||||
|
||||
if (myDebug) {
|
||||
myDebugArray.setText(chars);
|
||||
myDebugDeferredChanges.clear();
|
||||
}
|
||||
assertConsistency();
|
||||
}
|
||||
|
||||
private void assertConsistency() {
|
||||
if (isDeferredChangeMode()) {
|
||||
assert myOriginalSequence == null;
|
||||
}
|
||||
CharSequence originalSequence = myOriginalSequence;
|
||||
int origLen = originalSequence == null ? -1 : originalSequence.length();
|
||||
String string = com.intellij.reference.SoftReference.dereference(myStringRef);
|
||||
int stringLen = string == null ? -1 : string.length();
|
||||
assert origLen == stringLen || origLen==-1 || stringLen==-1;
|
||||
|
||||
int count = myCount + myDeferredShift;
|
||||
assert count == origLen || origLen==-1;
|
||||
assert count == stringLen || stringLen==-1;
|
||||
|
||||
if (!myDebug) return;
|
||||
final CharSequence seqFromCharArray;
|
||||
|
||||
if (myArray != null) {
|
||||
assert myCount <= myArray.length;
|
||||
seqFromCharArray = new CharArrayCharSequence(myArray, myStart, myCount);
|
||||
}
|
||||
else {
|
||||
seqFromCharArray = null;
|
||||
}
|
||||
|
||||
if (seqFromCharArray != null && originalSequence != null) {
|
||||
assert StringUtil.equals(seqFromCharArray, originalSequence);
|
||||
}
|
||||
if (!isDeferredChangeMode() && seqFromCharArray != null && string != null) {
|
||||
assert StringUtil.equals(seqFromCharArray, string);
|
||||
}
|
||||
if (originalSequence != null && string != null) {
|
||||
assert string.equals(originalSequence.toString());
|
||||
}
|
||||
|
||||
myDebugArray.assertConsistency();
|
||||
|
||||
CharSequence str = com.intellij.reference.SoftReference.dereference(myStringRef);
|
||||
if (str == null) {
|
||||
if (myHasDeferredChanges) {
|
||||
str = doSubString(0, myCount + myDeferredShift).toString();
|
||||
}
|
||||
else if (myOriginalSequence != null) {
|
||||
str = myOriginalSequence.toString();
|
||||
}
|
||||
else {
|
||||
str = seqFromCharArray;
|
||||
}
|
||||
}
|
||||
assert count == str.length();
|
||||
if (isDeferredChangeMode()) {
|
||||
String expected = myDebugArray.toString();
|
||||
checkStrings("toString()", expected, str);
|
||||
}
|
||||
}
|
||||
|
||||
public void replace(int startOffset,
|
||||
int endOffset,
|
||||
@NotNull CharSequence toDelete,
|
||||
@NotNull CharSequence newString,
|
||||
long newModificationStamp,
|
||||
boolean wholeTextReplaced) {
|
||||
final DocumentEvent event = startChange(startOffset, toDelete, newString, wholeTextReplaced);
|
||||
|
||||
startOffset += myStart;
|
||||
endOffset += myStart;
|
||||
doReplace(startOffset, endOffset, newString);
|
||||
afterChangedUpdate(event, newModificationStamp);
|
||||
assertConsistency();
|
||||
}
|
||||
|
||||
private void doReplace(int startOffset, int endOffset, @NotNull CharSequence newString) {
|
||||
prepareForModification();
|
||||
|
||||
if (isDeferredChangeMode()) {
|
||||
storeChange(new TextChangeImpl(newString, startOffset, endOffset));
|
||||
if (myDebug) {
|
||||
myDebugArray.doReplace(startOffset, endOffset, newString);
|
||||
}
|
||||
}
|
||||
else {
|
||||
int newLength = newString.length();
|
||||
int oldLength = endOffset - startOffset;
|
||||
|
||||
CharArrayUtil.getChars(newString, myArray, startOffset, Math.min(newLength, oldLength));
|
||||
myStringRef = null;
|
||||
|
||||
if (newLength > oldLength) {
|
||||
doInsert(newString.subSequence(oldLength, newLength), endOffset);
|
||||
}
|
||||
else if (newLength < oldLength) {
|
||||
doRemove(startOffset + newLength, startOffset + oldLength);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void remove(int startIndex, int endIndex, @NotNull CharSequence toDelete) {
|
||||
DocumentEvent event = startChange(startIndex, toDelete, null, false);
|
||||
startIndex += myStart;
|
||||
endIndex += myStart;
|
||||
doRemove(startIndex, endIndex);
|
||||
afterChangedUpdate(event, LocalTimeCounter.currentTime());
|
||||
assertConsistency();
|
||||
}
|
||||
|
||||
private void doRemove(int startIndex, int endIndex) {
|
||||
if (startIndex == endIndex) {
|
||||
return;
|
||||
}
|
||||
prepareForModification();
|
||||
|
||||
if (isDeferredChangeMode()) {
|
||||
storeChange(new TextChangeImpl("", startIndex, endIndex));
|
||||
if (myDebug) {
|
||||
myDebugArray.doRemove(startIndex, endIndex);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (endIndex < myCount) {
|
||||
System.arraycopy(myArray, endIndex, myArray, startIndex, myCount - endIndex);
|
||||
myStringRef = null;
|
||||
}
|
||||
myCount -= endIndex - startIndex;
|
||||
}
|
||||
}
|
||||
|
||||
public void insert(@NotNull CharSequence s, int startIndex) {
|
||||
DocumentEvent event = startChange(startIndex, null, s, false);
|
||||
startIndex += myStart;
|
||||
doInsert(s, startIndex);
|
||||
|
||||
afterChangedUpdate(event, LocalTimeCounter.currentTime());
|
||||
trimToSize();
|
||||
assertConsistency();
|
||||
}
|
||||
|
||||
private void doInsert(@NotNull CharSequence s, final int startIndex) {
|
||||
prepareForModification();
|
||||
|
||||
if (isDeferredChangeMode()) {
|
||||
storeChange(new TextChangeImpl(s, startIndex));
|
||||
if (myDebug) {
|
||||
myDebugArray.doInsert(s, startIndex);
|
||||
}
|
||||
}
|
||||
else {
|
||||
int insertLength = s.length();
|
||||
myArray = resizeArray(myArray, myCount + insertLength);
|
||||
if (startIndex < myCount) {
|
||||
System.arraycopy(myArray, startIndex, myArray, startIndex + insertLength, myCount - startIndex);
|
||||
}
|
||||
|
||||
CharArrayUtil.getChars(s, myArray, startIndex);
|
||||
myCount += insertLength;
|
||||
myStringRef = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores given change at collection of deferred changes (merging it with others if necessary) and updates current object
|
||||
* state ({@link #length() length} etc).
|
||||
*
|
||||
* @param change new change to store
|
||||
*/
|
||||
private void storeChange(@NotNull TextChangeImpl change) {
|
||||
if (!change.isWithinBounds(length())) {
|
||||
LOG.error(
|
||||
"Invalid change attempt detected - given change bounds are not within the current char array. Change: " +
|
||||
change.getText().length()+":" + change.getStart()+"-" + change.getEnd(), dumpState());
|
||||
return;
|
||||
}
|
||||
if (myDeferredChangesStorage.size() >= MAX_DEFERRED_CHANGES_NUMBER) {
|
||||
flushDeferredChanged();
|
||||
}
|
||||
myDeferredChangesStorage.store(change);
|
||||
myHasDeferredChanges = true;
|
||||
myDeferredShift += change.getDiff();
|
||||
|
||||
if (myDebug) {
|
||||
myDebugDeferredChanges.add(change);
|
||||
}
|
||||
}
|
||||
|
||||
private void prepareForModification() {
|
||||
if (myOriginalSequence != null) {
|
||||
myArray = new char[myOriginalSequence.length()];
|
||||
CharArrayUtil.getChars(myOriginalSequence, myArray, 0);
|
||||
myCount = myArray.length;
|
||||
myOriginalSequence = null;
|
||||
myStart = 0;
|
||||
}
|
||||
myStringRef = null;
|
||||
|
||||
assertConsistency();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public CharSequence getCharArray() {
|
||||
assertConsistency();
|
||||
CharSequence originalSequence = myOriginalSequence;
|
||||
return originalSequence == null ? this : originalSequence;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public String toString() {
|
||||
assertConsistency();
|
||||
String str = com.intellij.reference.SoftReference.dereference(myStringRef);
|
||||
if (str == null) {
|
||||
if (myHasDeferredChanges) {
|
||||
str = substring(0, length()).toString();
|
||||
}
|
||||
else {
|
||||
str = myOriginalSequence == null ? new String(myArray, myStart, myCount) : myOriginalSequence.toString();
|
||||
}
|
||||
myStringRef = new SoftReference<String>(str);
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final int length() {
|
||||
final int result = myCount + myDeferredShift;
|
||||
if (myDebug && isDeferredChangeMode()) {
|
||||
int expected = myDebugArray.length();
|
||||
if (expected != result) {
|
||||
dumpDebugInfo("Incorrect length() processing. Expected: '" + expected + "', actual: '" + result + "'");
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final char charAt(int i) {
|
||||
if (i < 0 || i >= length()) {
|
||||
throw new IndexOutOfBoundsException("Wrong offset: " + i + "; count:" + length());
|
||||
}
|
||||
i += myStart;
|
||||
final char result;
|
||||
if (!myHasDeferredChanges) {
|
||||
if (myOriginalSequence != null) {
|
||||
result = myOriginalSequence.charAt(i);
|
||||
}
|
||||
else {
|
||||
result = myArray[i];
|
||||
}
|
||||
}
|
||||
else {
|
||||
result = myDeferredChangesStorage.charAt(myArray, i);
|
||||
}
|
||||
|
||||
if (myDebug && isDeferredChangeMode()) {
|
||||
char expected = myDebugArray.charAt(i);
|
||||
if (expected != result) {
|
||||
dumpDebugInfo("Incorrect charAt() processing for index " + i + ". Expected: '" + expected + "', actual: '" + result + "'");
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public CharSequence subSequence(final int start, final int end) {
|
||||
assertReadAccess();
|
||||
assertConsistency();
|
||||
if (start == 0 && end == length()) return this;
|
||||
if (myOriginalSequence != null) {
|
||||
return myOriginalSequence.subSequence(start, end);
|
||||
}
|
||||
flushDeferredChanged();
|
||||
return new CharArrayCharSequence(myArray, start, end);
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public char[] getChars() {
|
||||
assertReadAccess();
|
||||
assertConsistency();
|
||||
char[] array = myArray;
|
||||
CharSequence originalSequence = myOriginalSequence;
|
||||
if (myHasDeferredChanges || originalSequence != null && array == null) {
|
||||
// slow track
|
||||
synchronized (lock) {
|
||||
flushDeferredChanged();
|
||||
array = myArray;
|
||||
originalSequence = myOriginalSequence;
|
||||
if (originalSequence != null && array == null) {
|
||||
myArray = array = CharArrayUtil.fromSequence(originalSequence);
|
||||
myStringRef = null;
|
||||
}
|
||||
}
|
||||
assertConsistency();
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getChars(@NotNull final char[] dst, final int dstOffset) {
|
||||
assertReadAccess();
|
||||
assertConsistency();
|
||||
flushDeferredChanged();
|
||||
if (myOriginalSequence == null) {
|
||||
System.arraycopy(myArray, myStart, dst, dstOffset, length());
|
||||
}
|
||||
else {
|
||||
CharArrayUtil.getChars(myOriginalSequence, dst, dstOffset);
|
||||
}
|
||||
|
||||
if (myDebug && isDeferredChangeMode()) {
|
||||
char[] expected = new char[dst.length];
|
||||
myDebugArray.getChars(expected, dstOffset);
|
||||
for (int i = dstOffset, j = myStart; i < dst.length && j < myArray.length; i++, j++) {
|
||||
if (expected[i] != myArray[j]) {
|
||||
dumpDebugInfo("getChars(char[], int). Given array of length " + dst.length + ", offset " + dstOffset + ". Found char '" + myArray[j] +
|
||||
"' at index " + i + ", expected to find '" + expected[i] + "'");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public CharSequence substring(final int start, final int end) {
|
||||
assertReadAccess();
|
||||
final CharSequence result = doSubString(start, end);
|
||||
|
||||
assertConsistency();
|
||||
return result;
|
||||
}
|
||||
|
||||
private CharSequence doSubString(int start, int end) {
|
||||
if (start == end) return "";
|
||||
final CharSequence result;
|
||||
if (myOriginalSequence == null) {
|
||||
result = myDeferredChangesStorage.substring(myArray, start + myStart, end + myStart);
|
||||
}
|
||||
else {
|
||||
result = myOriginalSequence.subSequence(start, end);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static char[] resizeArray(@NotNull char[] array, int newSize) {
|
||||
if (newSize < array.length) {
|
||||
return array;
|
||||
}
|
||||
|
||||
int newArraySize = array.length;
|
||||
if (newArraySize == 0) {
|
||||
newArraySize = 16;
|
||||
}
|
||||
while (newArraySize <= newSize) {
|
||||
newArraySize = newArraySize * 12 / 10 + 1;
|
||||
}
|
||||
char[] newArray = new char[newArraySize];
|
||||
System.arraycopy(array, 0, newArray, 0, array.length);
|
||||
return newArray;
|
||||
}
|
||||
|
||||
private void trimToSize() {
|
||||
if (myBufferSize != 0 && length() > myBufferSize) {
|
||||
flushDeferredChanged();
|
||||
|
||||
// make a copy
|
||||
int endIndex = myCount - myBufferSize;
|
||||
String toDelete = getCharArray().subSequence(0, endIndex).toString();
|
||||
remove(0, endIndex, toDelete);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return <code>true</code> if this object is in the defer changes mode, see {@link #setDeferredChangeMode(boolean)};
|
||||
*/
|
||||
public boolean isDeferredChangeMode() {
|
||||
return myDeferredChangeMode;
|
||||
}
|
||||
|
||||
public boolean hasDeferredChanges() {
|
||||
return myHasDeferredChanges;
|
||||
}
|
||||
|
||||
/**
|
||||
* There is a possible case that client of this class wants to perform great number of modifications in a short amount of time
|
||||
* (e.g. end-user performs formatting of the document backed by the object of the current class). It may result in significant
|
||||
* performance degradation is the changes are performed one by one (every time the change is applied tail content is shifted to
|
||||
* the left or right). So, we may want to optimize that by avoiding actual array modification until information about
|
||||
* all target changes is provided and perform array data moves only after that.
|
||||
* <p/>
|
||||
* This method allows to define that <code>'defer changes'</code> mode usages, i.e. expected usage pattern is as follows:
|
||||
* <pre>
|
||||
* <ol>
|
||||
* <li>
|
||||
* Client of this class enters <code>'defer changes'</code> mode (calls this method with <code>'true'</code> argument).
|
||||
* That means that all subsequent changes will not actually modify backed array data and will be stored separately;
|
||||
* </li>
|
||||
* <li>
|
||||
* Number of target changes are applied to the current object via standard API
|
||||
* ({@link #insert(CharSequence, int) insert},
|
||||
* {@link #remove(int, int, CharSequence) remove} and
|
||||
* {@link #replace(int, int, java.lang.CharSequence, java.lang.CharSequence, long, boolean)});
|
||||
* </li>
|
||||
* <li>
|
||||
* Client of this class indicates that <code>'massive change time'</code> is over by calling this method with <code>'false'</code>
|
||||
* argument. That flushes all deferred changes (if any) to the backed data array and makes every subsequent change to
|
||||
* be immediate flushed to the backed array;
|
||||
* </li>
|
||||
* </ol>
|
||||
* </pre>
|
||||
* <p/>
|
||||
* <b>Note:</b> we can't exclude possibility that <code>'defer changes'</code> mode is started but inadvertently not ended
|
||||
* (due to programming error, unexpected exception etc). Hence, this class is free to automatically end
|
||||
* <code>'defer changes'</code> mode when necessary in order to avoid memory leak with infinite deferred changes storing.
|
||||
*
|
||||
* @param deferredChangeMode flag that defines if <code>'defer changes'</code> mode should be used by the current object
|
||||
*/
|
||||
public void setDeferredChangeMode(boolean deferredChangeMode) {
|
||||
if (!DISABLE_DEFERRED_PROCESSING) {
|
||||
if (deferredChangeMode) {
|
||||
if (myDebug) {
|
||||
myDebugArray.setText(myDebugTextOnBatchUpdateStart = toString());
|
||||
myDebugDeferredChanges.clear();
|
||||
}
|
||||
prepareForModification();
|
||||
}
|
||||
else {
|
||||
flushDeferredChanged();
|
||||
}
|
||||
myDeferredChangeMode = deferredChangeMode;
|
||||
}
|
||||
assertConsistency();
|
||||
}
|
||||
|
||||
private void flushDeferredChanged() {
|
||||
List<TextChangeImpl> changes = myDeferredChangesStorage.getChanges();
|
||||
if (changes.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
synchronized (lock) {
|
||||
char[] beforeMerge = null;
|
||||
if (myDebug) {
|
||||
beforeMerge = new char[myArray.length];
|
||||
System.arraycopy(myArray, 0, beforeMerge, 0, myArray.length);
|
||||
}
|
||||
|
||||
BulkChangesMerger changesMerger = BulkChangesMerger.INSTANCE;
|
||||
final boolean inPlace;
|
||||
if (myArray.length < length()) {
|
||||
myArray = changesMerger.mergeToCharArray(myArray, myCount, changes);
|
||||
inPlace = false;
|
||||
}
|
||||
else {
|
||||
changesMerger.mergeInPlace(myArray, myCount, changes);
|
||||
inPlace = true;
|
||||
}
|
||||
|
||||
myCount += myDeferredShift;
|
||||
myDeferredShift = 0;
|
||||
myDeferredChangesStorage.clear();
|
||||
myHasDeferredChanges = false;
|
||||
myDeferredChangeMode = false;
|
||||
myStringRef = null;
|
||||
|
||||
if (myDebug) {
|
||||
for (int i = 0, max = length(); i < max; i++) {
|
||||
if (myArray[i] != myDebugArray.myArray[i]) {
|
||||
dumpDebugInfo("flushDeferredChanged(). Index " + i + ", expected: '" + myDebugArray.myArray[i]+"', actual '" +
|
||||
myArray[i]+"'. Text before merge: '" + Arrays.toString(beforeMerge)+"', merge inplace: "+inPlace);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
assertConsistency();
|
||||
}
|
||||
|
||||
@Override
|
||||
@NonNls
|
||||
@NotNull
|
||||
public String dumpState() {
|
||||
return "deferred changes mode: " + isDeferredChangeMode()+", length: " + length()+" (data array length: " + myCount+
|
||||
", deferred shift: " + myDeferredShift+"); view offsets: [" + myStart+"; "+myCount+"]; deferred changes: "+myDeferredChangesStorage;
|
||||
}
|
||||
|
||||
private void checkStrings(@NonNls @NotNull String operation, @NotNull String expected, @NotNull CharSequence actual) {
|
||||
if (StringUtil.equals(expected, actual)) {
|
||||
return;
|
||||
}
|
||||
for (int i = 0, max = Math.min(expected.length(), actual.length()); i < max; i++) {
|
||||
if (actual.charAt(i) != expected.charAt(i)) {
|
||||
dumpDebugInfo(
|
||||
"Incorrect " +
|
||||
operation+" processing. Expected length: " +
|
||||
expected.length()+", actual length: " +
|
||||
actual.length()+". Unmatched symbol at " +
|
||||
i+" - expected: '" +
|
||||
expected.charAt(i)+"', " +
|
||||
"actual: '" +
|
||||
actual.charAt(i)+"', expected document: '" +
|
||||
expected+"', actual document: '" +
|
||||
actual+"'"
|
||||
);
|
||||
return;
|
||||
}
|
||||
}
|
||||
dumpDebugInfo("Incorrect " + operation+" processing. Expected length: " + expected.length()+", actual length: " +
|
||||
actual.length()+", expected: '" + expected+"', actual: '" + actual+"'");
|
||||
}
|
||||
|
||||
private void dumpDebugInfo(@NonNls @NotNull String problem) {
|
||||
LOG.error(
|
||||
"Incorrect CharArray processing detected: " + problem +
|
||||
". Start: " + myStart
|
||||
+ ", count: " + myCount + ", text on batch update start: " +
|
||||
myDebugTextOnBatchUpdateStart + ", deferred changes history: " +
|
||||
myDebugDeferredChanges + ", current deferred changes: " + myDeferredChangesStorage
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -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.
|
||||
@@ -68,7 +68,7 @@ public abstract class PsiFileImpl extends ElementBase implements PsiFileEx, PsiF
|
||||
protected IElementType myContentElementType;
|
||||
private long myModificationStamp;
|
||||
|
||||
protected PsiFile myOriginalFile = null;
|
||||
protected PsiFile myOriginalFile;
|
||||
private final FileViewProvider myViewProvider;
|
||||
private volatile Reference<StubTree> myStub;
|
||||
private boolean myInvalidated;
|
||||
@@ -555,7 +555,7 @@ public abstract class PsiFileImpl extends ElementBase implements PsiFileEx, PsiF
|
||||
}
|
||||
private static final Comparator<PsiFile> FILE_BY_LANGUAGE_ID = new Comparator<PsiFile>() {
|
||||
@Override
|
||||
public int compare(PsiFile o1, PsiFile o2) {
|
||||
public int compare(@NotNull PsiFile o1, @NotNull PsiFile o2) {
|
||||
return o1.getLanguage().getID().compareTo(o2.getLanguage().getID());
|
||||
}
|
||||
};
|
||||
@@ -944,14 +944,18 @@ public abstract class PsiFileImpl extends ElementBase implements PsiFileEx, PsiF
|
||||
return this == another;
|
||||
}
|
||||
|
||||
private static final Key<SoftReference<StubTree>> STUB_TREE_IN_PARSED_TREE = Key.create("STUB_TREE_IN_PARSED_TREE");
|
||||
private static final Key<Reference<StubTree>> STUB_TREE_IN_PARSED_TREE = Key.create("STUB_TREE_IN_PARSED_TREE");
|
||||
private final Object myStubFromTreeLock = new Object();
|
||||
|
||||
@NotNull
|
||||
public StubTree calcStubTree() {
|
||||
FileElement fileElement = calcTreeElement();
|
||||
StubTree tree = SoftReference.dereference(fileElement.getUserData(STUB_TREE_IN_PARSED_TREE));
|
||||
if (tree != null) {
|
||||
return tree;
|
||||
}
|
||||
synchronized (myStubFromTreeLock) {
|
||||
SoftReference<StubTree> ref = fileElement.getUserData(STUB_TREE_IN_PARSED_TREE);
|
||||
StubTree tree = SoftReference.dereference(ref);
|
||||
tree = SoftReference.dereference(fileElement.getUserData(STUB_TREE_IN_PARSED_TREE));
|
||||
|
||||
if (tree == null) {
|
||||
ApplicationManager.getApplication().assertReadAccessAllowed();
|
||||
|
||||
@@ -346,8 +346,8 @@ public class UnifiedDiffViewer extends ListenerDiffViewerBase {
|
||||
EditorHighlighter highlighter2 = DiffUtil.initEditorHighlighter(project, content2, text2);
|
||||
|
||||
if (highlighter1 == null && highlighter2 == null) return null;
|
||||
if (highlighter1 == null) highlighter1 = DiffUtil.initEmptyEditorHighlighter(project, text1);
|
||||
if (highlighter2 == null) highlighter2 = DiffUtil.initEmptyEditorHighlighter(project, text2);
|
||||
if (highlighter1 == null) highlighter1 = DiffUtil.initEmptyEditorHighlighter(text1);
|
||||
if (highlighter2 == null) highlighter2 = DiffUtil.initEmptyEditorHighlighter(text2);
|
||||
|
||||
return new UnifiedEditorHighlighter(myDocument, highlighter1, highlighter2, ranges, textLength);
|
||||
}
|
||||
|
||||
@@ -107,7 +107,7 @@ public class DiffUtil {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static EditorHighlighter initEmptyEditorHighlighter(@Nullable Project project, @NotNull CharSequence text) {
|
||||
public static EditorHighlighter initEmptyEditorHighlighter(@NotNull CharSequence text) {
|
||||
EditorHighlighter highlighter = createEmptyEditorHighlighter();
|
||||
highlighter.setText(text);
|
||||
return highlighter;
|
||||
@@ -216,10 +216,6 @@ public class DiffUtil {
|
||||
scrollToCaret(editor, animated);
|
||||
}
|
||||
|
||||
public static void scrollToPoint(@Nullable Editor editor, @NotNull Point point) {
|
||||
scrollToPoint(editor, point, false);
|
||||
}
|
||||
|
||||
public static void scrollToPoint(@Nullable Editor editor, @NotNull Point point, boolean animated) {
|
||||
if (editor == null) return;
|
||||
if (!animated) editor.getScrollingModel().disableAnimation();
|
||||
@@ -876,14 +872,6 @@ public class DiffUtil {
|
||||
return holder;
|
||||
}
|
||||
|
||||
public static <T> UserDataHolderBase createUserDataHolder(@NotNull Key<T> key1, @Nullable T value1,
|
||||
@NotNull Key<T> key2, @Nullable T value2) {
|
||||
UserDataHolderBase holder = new UserDataHolderBase();
|
||||
holder.putUserData(key1, value1);
|
||||
holder.putUserData(key2, value2);
|
||||
return holder;
|
||||
}
|
||||
|
||||
public static boolean isUserDataFlagSet(@NotNull Key<Boolean> key, UserDataHolder... holders) {
|
||||
for (UserDataHolder holder : holders) {
|
||||
if (holder == null) continue;
|
||||
@@ -1039,9 +1027,5 @@ public class DiffUtil {
|
||||
this(ignorePolicy.getComparisonPolicy(), highlightPolicy.isFineFragments(), highlightPolicy.isShouldSquash(),
|
||||
ignorePolicy.isShouldTrimChunks());
|
||||
}
|
||||
|
||||
public DiffConfig() {
|
||||
this(IgnorePolicy.DEFAULT, HighlightPolicy.BY_LINE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -161,6 +161,20 @@ public interface RunnerAndConfigurationSettings {
|
||||
*/
|
||||
boolean isEditBeforeRun();
|
||||
|
||||
/**
|
||||
* Sets the "Before launch: Activate tool window" flag (for activation tool window Run/Debug etc.)
|
||||
*
|
||||
* @param b if true, the tool window will be activated before launching this configuration.
|
||||
*/
|
||||
void setActivateToolWindowBeforeRun(boolean activate);
|
||||
|
||||
/**
|
||||
* Returns the "Before launch: Activate tool window" flag (for activation tool window Run/Debug etc.)
|
||||
*
|
||||
* @return if true (it's default value), the tool window will be activated before launching this configuration.
|
||||
*/
|
||||
boolean isActivateToolWindowBeforeRun();
|
||||
|
||||
/**
|
||||
* Sets the "Single instance only" flag (meaning that only one instance of this run configuration can be run at the same time).
|
||||
*
|
||||
|
||||
@@ -16,10 +16,7 @@
|
||||
|
||||
package com.intellij.execution.runners;
|
||||
|
||||
import com.intellij.execution.ExecutionException;
|
||||
import com.intellij.execution.ExecutionResult;
|
||||
import com.intellij.execution.Executor;
|
||||
import com.intellij.execution.RunManager;
|
||||
import com.intellij.execution.*;
|
||||
import com.intellij.execution.configurations.*;
|
||||
import com.intellij.execution.ui.RunContentDescriptor;
|
||||
import com.intellij.openapi.options.SettingsEditor;
|
||||
@@ -72,6 +69,10 @@ abstract class BaseProgramRunner<Settings extends RunnerSettings> implements Pro
|
||||
static RunContentDescriptor postProcess(@NotNull ExecutionEnvironment environment, @Nullable RunContentDescriptor descriptor, @Nullable Callback callback) {
|
||||
if (descriptor != null) {
|
||||
descriptor.setExecutionId(environment.getExecutionId());
|
||||
RunnerAndConfigurationSettings settings = environment.getRunnerAndConfigurationSettings();
|
||||
if (settings != null) {
|
||||
descriptor.setActivateToolWindowWhenAdded(settings.isActivateToolWindowBeforeRun());
|
||||
}
|
||||
}
|
||||
if (callback != null) {
|
||||
callback.processStarted(descriptor);
|
||||
|
||||
@@ -266,11 +266,6 @@ public class CodeStyleSettings extends CommonCodeStyleSettings implements Clonea
|
||||
*/
|
||||
@Deprecated
|
||||
public int RIGHT_MARGIN = 120;
|
||||
/**
|
||||
* @deprecated Use isWrapOnTyping(Language) instead or setWrapOnTyping(Language,boolean) for testing purposes.
|
||||
* @see #isWrapOnTyping(Language)
|
||||
* @see #setWrapOnTyping(Language, boolean)
|
||||
*/
|
||||
public boolean WRAP_WHEN_TYPING_REACHES_RIGHT_MARGIN = false;
|
||||
|
||||
|
||||
@@ -962,35 +957,4 @@ public class CodeStyleSettings extends CommonCodeStyleSettings implements Clonea
|
||||
public void setDefaultRightMargin(int rightMargin) {
|
||||
RIGHT_MARGIN = rightMargin;
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines whether or not wrapping should occur when typing reaches right margin.
|
||||
* @param language The language to check the option for or null for a global option.
|
||||
* @return True if wrapping on right margin is enabled.
|
||||
*/
|
||||
public boolean isWrapOnTyping(@Nullable Language language) {
|
||||
if (language != null) {
|
||||
CommonCodeStyleSettings langSettings = getCommonSettings(language);
|
||||
if (langSettings != null) {
|
||||
if (langSettings.WRAP_ON_TYPING != WrapOnTyping.UNDEFINED.intValue) {
|
||||
return langSettings.WRAP_ON_TYPING == WrapOnTyping.WRAP.intValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
//noinspection deprecation
|
||||
return WRAP_WHEN_TYPING_REACHES_RIGHT_MARGIN;
|
||||
}
|
||||
|
||||
@TestOnly
|
||||
public void setWrapOnTyping(@Nullable Language language, boolean wrapOnTyping) {
|
||||
if (language != null) {
|
||||
CommonCodeStyleSettings langSettings = getCommonSettings(language);
|
||||
if (langSettings != null) {
|
||||
langSettings.WRAP_ON_TYPING = wrapOnTyping ? WrapOnTyping.WRAP.intValue : WrapOnTyping.NO_WRAP.intValue;
|
||||
return;
|
||||
}
|
||||
}
|
||||
//noinspection deprecation
|
||||
WRAP_WHEN_TYPING_REACHES_RIGHT_MARGIN = wrapOnTyping;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -113,7 +113,6 @@ public interface CodeStyleSettingsCustomizable {
|
||||
|
||||
enum WrappingOrBraceOption {
|
||||
RIGHT_MARGIN,
|
||||
WRAP_ON_TYPING,
|
||||
KEEP_CONTROL_STATEMENT_IN_ONE_LINE,
|
||||
LINE_COMMENT_AT_FIRST_COLUMN,
|
||||
BLOCK_COMMENT_AT_FIRST_COLUMN,
|
||||
|
||||
@@ -890,24 +890,6 @@ public class CommonCodeStyleSettings {
|
||||
|
||||
public int FORCE_REARRANGE_MODE = REARRANGE_ACCORDIND_TO_DIALOG;
|
||||
|
||||
public enum WrapOnTyping {
|
||||
UNDEFINED (-1),
|
||||
NO_WRAP (0),
|
||||
WRAP (1);
|
||||
|
||||
public int intValue;
|
||||
|
||||
WrapOnTyping(int i) {
|
||||
this.intValue = i;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines if wrapping should occur when typing reaches right margin. <b>Do not refer to this field directly, use
|
||||
* <code>CodeStyleSettings.isWrapOnTyping(Language)</code> method instead</b>.
|
||||
* @see CodeStyleSettings#isWrapOnTyping(Language)
|
||||
*/
|
||||
public int WRAP_ON_TYPING = WrapOnTyping.UNDEFINED.intValue;
|
||||
|
||||
//-------------------------Indent options-------------------------------------------------
|
||||
public static class IndentOptions implements JDOMExternalizable, Cloneable {
|
||||
|
||||
@@ -158,7 +158,6 @@ public class GeneralCodeStylePanel extends CodeStyleAbstractPanel {
|
||||
settings.LINE_SEPARATOR = getSelectedLineSeparator();
|
||||
|
||||
settings.setDefaultRightMargin(((Number) myRightMarginSpinner.getValue()).intValue());
|
||||
//noinspection deprecation
|
||||
settings.WRAP_WHEN_TYPING_REACHES_RIGHT_MARGIN = myCbWrapWhenTypingReachesRightMargin.isSelected();
|
||||
myIndentOptionsEditor.setEnabled(true);
|
||||
myIndentOptionsEditor.apply(settings, settings.OTHER_INDENT_OPTIONS);
|
||||
@@ -224,7 +223,6 @@ public class GeneralCodeStylePanel extends CodeStyleAbstractPanel {
|
||||
return true;
|
||||
}
|
||||
|
||||
//noinspection deprecation
|
||||
if (settings.WRAP_WHEN_TYPING_REACHES_RIGHT_MARGIN ^ myCbWrapWhenTypingReachesRightMargin.isSelected()) {
|
||||
return true;
|
||||
}
|
||||
@@ -281,7 +279,6 @@ public class GeneralCodeStylePanel extends CodeStyleAbstractPanel {
|
||||
}
|
||||
|
||||
myRightMarginSpinner.setValue(settings.getDefaultRightMargin());
|
||||
//noinspection deprecation
|
||||
myCbWrapWhenTypingReachesRightMargin.setSelected(settings.WRAP_WHEN_TYPING_REACHES_RIGHT_MARGIN);
|
||||
myIndentOptionsEditor.reset(settings, settings.OTHER_INDENT_OPTIONS);
|
||||
myIndentOptionsEditor.setEnabled(true);
|
||||
|
||||
-76
@@ -31,7 +31,6 @@ import com.intellij.ui.treeStructure.treetable.TreeTableModel;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.ui.AbstractTableCellEditor;
|
||||
import com.intellij.util.ui.ColumnInfo;
|
||||
import com.intellij.util.ui.ThreeStateCheckBox;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
import gnu.trove.THashMap;
|
||||
import gnu.trove.THashSet;
|
||||
@@ -352,11 +351,6 @@ public abstract class OptionTableWithPreviewPanel extends CustomizableLanguageCo
|
||||
myOptions.add(new BooleanOption(null, fieldName, title, groupName, null, null));
|
||||
}
|
||||
|
||||
protected void addOption(
|
||||
@NotNull String filedName, @NotNull String title, @Nullable String groupName, int undefinedValue, int falseValue, int trueValue) {
|
||||
myOptions.add(new TriStateOption(null, filedName, title, groupName, null, null, undefinedValue, falseValue, trueValue));
|
||||
}
|
||||
|
||||
protected void addOption(@NotNull String fieldName, @NotNull String title, @Nullable String groupName,
|
||||
@NotNull String[] options, @NotNull int[] values) {
|
||||
myOptions.add(new SelectionOption(null, fieldName, title, groupName, null, null, options, values));
|
||||
@@ -437,61 +431,6 @@ public abstract class OptionTableWithPreviewPanel extends CustomizableLanguageCo
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private class TriStateOption extends Option {
|
||||
|
||||
private int myUndefinedValue;
|
||||
private int myFalseValue;
|
||||
private int myTrueValue;
|
||||
|
||||
public TriStateOption(@Nullable Class<? extends CustomCodeStyleSettings> clazz,
|
||||
@NotNull String fieldName,
|
||||
@NotNull String title,
|
||||
@Nullable String groupName,
|
||||
@Nullable OptionAnchor anchor,
|
||||
@Nullable String anchorFiledName,
|
||||
int undefinedValue,
|
||||
int falseValue,
|
||||
int trueValue) {
|
||||
super(clazz, fieldName, title, groupName, anchor, anchorFiledName);
|
||||
myUndefinedValue = undefinedValue;
|
||||
myFalseValue = falseValue;
|
||||
myTrueValue = trueValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getValue(CodeStyleSettings settings) {
|
||||
try {
|
||||
int value = field.getInt(getSettings(settings));
|
||||
return getState(value);
|
||||
}
|
||||
catch (IllegalAccessException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setValue(Object value, CodeStyleSettings settings) {
|
||||
try {
|
||||
int intValue =
|
||||
ThreeStateCheckBox.State.DONT_CARE.equals(value) ? myUndefinedValue :
|
||||
ThreeStateCheckBox.State.SELECTED.equals(value) ? myTrueValue : myFalseValue;
|
||||
field.setInt(getSettings(settings), intValue);
|
||||
}
|
||||
catch (IllegalAccessException ignored) {
|
||||
}
|
||||
}
|
||||
|
||||
public ThreeStateCheckBox.State getState(Object value) {
|
||||
if (value instanceof Integer) {
|
||||
if (value.equals(myTrueValue)) return ThreeStateCheckBox.State.SELECTED;
|
||||
if (value.equals(myFalseValue)) return ThreeStateCheckBox.State.NOT_SELECTED;
|
||||
}
|
||||
return ThreeStateCheckBox.State.DONT_CARE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private class SelectionOption extends Option {
|
||||
@NotNull final String[] options;
|
||||
@NotNull final int[] values;
|
||||
@@ -746,7 +685,6 @@ public abstract class OptionTableWithPreviewPanel extends CustomizableLanguageCo
|
||||
private final JCheckBox myCheckBox = new JBCheckBox();
|
||||
private final JPanel myEmptyLabel = new JPanel();
|
||||
private final JLabel myIntLabel = new JLabel();
|
||||
private final ThreeStateCheckBox myTriStateCheckBox = new ThreeStateCheckBox();
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
@@ -787,10 +725,6 @@ public abstract class OptionTableWithPreviewPanel extends CustomizableLanguageCo
|
||||
myIntLabel.setText(value.toString());
|
||||
return myIntLabel;
|
||||
}
|
||||
else if (value instanceof ThreeStateCheckBox.State) {
|
||||
myTriStateCheckBox.setState((ThreeStateCheckBox.State)value);
|
||||
return myTriStateCheckBox;
|
||||
}
|
||||
|
||||
myCheckBox.putClientProperty("JComponent.sizeVariant", "small");
|
||||
myComboBox.putClientProperty("JComponent.sizeVariant", "small");
|
||||
@@ -849,7 +783,6 @@ public abstract class OptionTableWithPreviewPanel extends CustomizableLanguageCo
|
||||
private final JCheckBox myBooleanEditor = new JBCheckBox();
|
||||
private JBComboBoxTableCellEditorComponent myOptionsEditor = new JBComboBoxTableCellEditorComponent();
|
||||
private MyIntOptionEditor myIntOptionsEditor = new MyIntOptionEditor();
|
||||
private ThreeStateCheckBox myTriStateOptionsEditor = new ThreeStateCheckBox();
|
||||
private Component myCurrentEditor = null;
|
||||
private MyTreeNode myCurrentNode = null;
|
||||
|
||||
@@ -865,7 +798,6 @@ public abstract class OptionTableWithPreviewPanel extends CustomizableLanguageCo
|
||||
};
|
||||
myBooleanEditor.addActionListener(itemChoosen);
|
||||
myOptionsEditor.addActionListener(itemChoosen);
|
||||
myTriStateOptionsEditor.addActionListener(itemChoosen);
|
||||
myBooleanEditor.putClientProperty("JComponent.sizeVariant", "small");
|
||||
myOptionsEditor.putClientProperty("JComponent.sizeVariant", "small");
|
||||
}
|
||||
@@ -887,9 +819,6 @@ public abstract class OptionTableWithPreviewPanel extends CustomizableLanguageCo
|
||||
else if (myCurrentEditor == myIntOptionsEditor) {
|
||||
return myIntOptionsEditor.getPresentableValue();
|
||||
}
|
||||
else if (myCurrentEditor == myTriStateOptionsEditor) {
|
||||
return myTriStateOptionsEditor.getState();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
@@ -917,11 +846,6 @@ public abstract class OptionTableWithPreviewPanel extends CustomizableLanguageCo
|
||||
myIntOptionsEditor.setDefaultValue(intOption.getDefaultValue());
|
||||
myIntOptionsEditor.setDefaultValueText(intOption.getDefaultValueText());
|
||||
}
|
||||
else if (node.getKey() instanceof TriStateOption) {
|
||||
TriStateOption triStateOption = (TriStateOption)node.getKey();
|
||||
myCurrentEditor = myTriStateOptionsEditor;
|
||||
myTriStateOptionsEditor.setState(triStateOption.getState(node.getValue()));
|
||||
}
|
||||
else {
|
||||
myCurrentEditor = myOptionsEditor;
|
||||
myOptionsEditor.setCell(table, row, column);
|
||||
|
||||
+3
-11
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="com.intellij.application.options.codeStyle.RightMarginForm">
|
||||
<grid id="27dc6" binding="myTopPanel" layout-manager="GridLayoutManager" row-count="3" column-count="3" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||
<margin top="10" left="0" bottom="10" right="10"/>
|
||||
<grid id="27dc6" binding="myTopPanel" layout-manager="GridLayoutManager" row-count="2" column-count="3" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||
<margin top="10" left="10" bottom="10" right="10"/>
|
||||
<constraints>
|
||||
<xy x="20" y="20" width="500" height="400"/>
|
||||
</constraints>
|
||||
@@ -18,7 +18,7 @@
|
||||
</component>
|
||||
<vspacer id="1265c">
|
||||
<constraints>
|
||||
<grid row="2" column="0" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
|
||||
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
</vspacer>
|
||||
<component id="78fe" class="javax.swing.JTextField" binding="myRightMarginField">
|
||||
@@ -39,14 +39,6 @@
|
||||
<text resource-bundle="messages/ApplicationBundle" key="settings.code.style.default.general"/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="7701d" class="javax.swing.JCheckBox" binding="myWrapOnTypingCheckBox" custom-create="true" default-binding="true">
|
||||
<constraints>
|
||||
<grid row="1" column="0" row-span="1" col-span="3" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text value="Wrap on typing"/>
|
||||
</properties>
|
||||
</component>
|
||||
</children>
|
||||
</grid>
|
||||
</form>
|
||||
|
||||
+6
-38
@@ -16,10 +16,8 @@
|
||||
package com.intellij.application.options.codeStyle;
|
||||
|
||||
import com.intellij.lang.Language;
|
||||
import com.intellij.openapi.application.ApplicationBundle;
|
||||
import com.intellij.psi.codeStyle.CodeStyleSettings;
|
||||
import com.intellij.psi.codeStyle.CommonCodeStyleSettings;
|
||||
import com.intellij.util.ui.ThreeStateCheckBox;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.swing.*;
|
||||
@@ -45,7 +43,6 @@ public class RightMarginForm {
|
||||
private JTextField myRightMarginField;
|
||||
private JCheckBox myDefaultGeneralCheckBox;
|
||||
private JPanel myTopPanel;
|
||||
private JCheckBox myWrapOnTypingCheckBox;
|
||||
private final Language myLanguage;
|
||||
private final int myDefaultRightMargin;
|
||||
|
||||
@@ -80,22 +77,6 @@ public class RightMarginForm {
|
||||
myRightMarginField.setEnabled(false);
|
||||
}
|
||||
}
|
||||
if (langSettings != settings) {
|
||||
if (CommonCodeStyleSettings.WrapOnTyping.WRAP.intValue == langSettings.WRAP_ON_TYPING) {
|
||||
((ThreeStateCheckBox)myWrapOnTypingCheckBox).setState(ThreeStateCheckBox.State.SELECTED);
|
||||
}
|
||||
else if (CommonCodeStyleSettings.WrapOnTyping.NO_WRAP.intValue == langSettings.WRAP_ON_TYPING) {
|
||||
((ThreeStateCheckBox)myWrapOnTypingCheckBox).setState(ThreeStateCheckBox.State.NOT_SELECTED);
|
||||
}
|
||||
else {
|
||||
((ThreeStateCheckBox)myWrapOnTypingCheckBox).setState(ThreeStateCheckBox.State.DONT_CARE);
|
||||
}
|
||||
}
|
||||
else {
|
||||
((ThreeStateCheckBox)myWrapOnTypingCheckBox)
|
||||
.setState(settings.isWrapOnTyping(myLanguage) ? ThreeStateCheckBox.State.SELECTED : ThreeStateCheckBox.State.NOT_SELECTED);
|
||||
myWrapOnTypingCheckBox.setEnabled(false);
|
||||
}
|
||||
}
|
||||
|
||||
public void apply(@NotNull CodeStyleSettings settings) {
|
||||
@@ -107,26 +88,17 @@ public class RightMarginForm {
|
||||
else {
|
||||
langSettings.RIGHT_MARGIN = getFieldRightMargin(settings.getDefaultRightMargin());
|
||||
}
|
||||
langSettings.WRAP_ON_TYPING = getWrapOnTypingIntValue();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isModified(@NotNull CodeStyleSettings settings) {
|
||||
CommonCodeStyleSettings langSettings = settings.getCommonSettings(myLanguage);
|
||||
boolean isRightMarginChanged =
|
||||
myDefaultGeneralCheckBox.isSelected() ?
|
||||
langSettings.RIGHT_MARGIN >= 0 :
|
||||
langSettings.RIGHT_MARGIN != getFieldRightMargin(settings.getDefaultRightMargin());
|
||||
return isRightMarginChanged || getWrapOnTypingIntValue() != langSettings.WRAP_ON_TYPING;
|
||||
}
|
||||
|
||||
private int getWrapOnTypingIntValue() {
|
||||
ThreeStateCheckBox.State state = ((ThreeStateCheckBox)myWrapOnTypingCheckBox).getState();
|
||||
return
|
||||
ThreeStateCheckBox.State.SELECTED.equals(state) ? CommonCodeStyleSettings.WrapOnTyping.WRAP.intValue :
|
||||
ThreeStateCheckBox.State.NOT_SELECTED.equals(state) ? CommonCodeStyleSettings.WrapOnTyping.NO_WRAP.intValue :
|
||||
CommonCodeStyleSettings.WrapOnTyping.UNDEFINED.intValue;
|
||||
|
||||
if (myDefaultGeneralCheckBox.isSelected()) {
|
||||
return langSettings.RIGHT_MARGIN >= 0;
|
||||
}
|
||||
else {
|
||||
return langSettings.RIGHT_MARGIN != getFieldRightMargin(settings.getDefaultRightMargin());
|
||||
}
|
||||
}
|
||||
|
||||
private int getFieldRightMargin(int fallBackValue) {
|
||||
@@ -145,8 +117,4 @@ public class RightMarginForm {
|
||||
public JPanel getTopPanel() {
|
||||
return myTopPanel;
|
||||
}
|
||||
|
||||
private void createUIComponents() {
|
||||
myWrapOnTypingCheckBox = new ThreeStateCheckBox(ApplicationBundle.message("wrapping.wrap.on.typing"));
|
||||
}
|
||||
}
|
||||
|
||||
-19
@@ -17,7 +17,6 @@ package com.intellij.application.options.codeStyle;
|
||||
|
||||
import com.intellij.openapi.application.ApplicationBundle;
|
||||
import com.intellij.psi.codeStyle.CodeStyleSettings;
|
||||
import com.intellij.psi.codeStyle.CommonCodeStyleSettings;
|
||||
import com.intellij.psi.codeStyle.LanguageCodeStyleSettingsProvider;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.containers.MultiMap;
|
||||
@@ -59,27 +58,9 @@ public class WrappingAndBracesPanel extends OptionTableWithPreviewPanel {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void addOption(@NotNull String fieldName,
|
||||
@NotNull String title,
|
||||
@Nullable String groupName,
|
||||
int minValue,
|
||||
int maxValue,
|
||||
int defaultValue,
|
||||
String defaultValueText) {
|
||||
super.addOption(fieldName, title, groupName, minValue, maxValue, defaultValue, defaultValueText);
|
||||
if (groupName != null) {
|
||||
myGroupToFields.putValue(groupName, fieldName);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void initTables() {
|
||||
addOption("RIGHT_MARGIN", ApplicationBundle.message("editbox.right.margin.columns"), null, 0, 999, -1, ApplicationBundle.message("settings.code.style.default.general"));
|
||||
addOption("WRAP_ON_TYPING", ApplicationBundle.message("wrapping.wrap.on.typing"), null,
|
||||
CommonCodeStyleSettings.WrapOnTyping.UNDEFINED.intValue,
|
||||
CommonCodeStyleSettings.WrapOnTyping.NO_WRAP.intValue,
|
||||
CommonCodeStyleSettings.WrapOnTyping.WRAP.intValue);
|
||||
|
||||
addOption("KEEP_LINE_BREAKS", ApplicationBundle.message("wrapping.keep.line.breaks"), WRAPPING_KEEP);
|
||||
addOption("KEEP_FIRST_COLUMN_COMMENT", ApplicationBundle.message("wrapping.keep.comment.at.first.column"), WRAPPING_KEEP);
|
||||
|
||||
+1
-2
@@ -17,7 +17,6 @@ package com.intellij.codeInsight.editorActions;
|
||||
|
||||
import com.intellij.codeInsight.template.TemplateManager;
|
||||
import com.intellij.formatting.FormatConstants;
|
||||
import com.intellij.lang.Language;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.formatter.WhiteSpaceFormattingStrategy;
|
||||
import com.intellij.ide.DataManager;
|
||||
@@ -48,7 +47,7 @@ public class AutoHardWrapHandler {
|
||||
/**
|
||||
* This key is used as a flag that indicates if <code>'auto wrap line on typing'</code> activity is performed now.
|
||||
*
|
||||
* @see CodeStyleSettings#isWrapOnTyping(Language)
|
||||
* @see CodeStyleSettings#WRAP_WHEN_TYPING_REACHES_RIGHT_MARGIN
|
||||
*/
|
||||
public static final Key<Boolean> AUTO_WRAP_LINE_IN_PROGRESS_KEY = new Key<Boolean>("AUTO_WRAP_LINE_IN_PROGRESS");
|
||||
|
||||
|
||||
@@ -43,6 +43,7 @@ import com.intellij.openapi.fileEditor.impl.FileEditorManagerImpl;
|
||||
import com.intellij.openapi.fileTypes.SyntaxHighlighter;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.openapi.util.Computable;
|
||||
import com.intellij.openapi.util.Disposer;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
@@ -550,7 +551,12 @@ public class LanguageConsoleImpl extends ConsoleViewImpl implements LanguageCons
|
||||
|
||||
@NotNull
|
||||
public PsiFile getFile() {
|
||||
return PsiUtilCore.getPsiFile(project, virtualFile);
|
||||
return ApplicationManager.getApplication().runReadAction(new Computable<PsiFile>() {
|
||||
@Override
|
||||
public PsiFile compute() {
|
||||
return PsiUtilCore.getPsiFile(project, virtualFile);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
@@ -35,6 +35,7 @@ import com.intellij.openapi.util.SystemInfo;
|
||||
import com.intellij.ui.*;
|
||||
import com.intellij.ui.components.JBList;
|
||||
import com.intellij.util.containers.hash.HashSet;
|
||||
import com.intellij.util.ui.JBUI;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
@@ -52,6 +53,7 @@ import java.util.List;
|
||||
class BeforeRunStepsPanel extends JPanel {
|
||||
|
||||
private final JCheckBox myShowSettingsBeforeRunCheckBox;
|
||||
private final JCheckBox myActivateToolWindowBeforeRunCheckBox;
|
||||
private final JBList myList;
|
||||
private final CollectionListModel<BeforeRunTask> myModel;
|
||||
private RunConfiguration myRunConfiguration;
|
||||
@@ -138,12 +140,22 @@ class BeforeRunStepsPanel extends JPanel {
|
||||
updateText();
|
||||
}
|
||||
});
|
||||
myActivateToolWindowBeforeRunCheckBox = new JCheckBox(ExecutionBundle.message("configuration.activate.toolwindow.before.run"));
|
||||
myActivateToolWindowBeforeRunCheckBox.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
updateText();
|
||||
}
|
||||
});
|
||||
|
||||
myPanel = myDecorator.createPanel();
|
||||
|
||||
setLayout(new BorderLayout());
|
||||
add(myPanel, BorderLayout.CENTER);
|
||||
add(myShowSettingsBeforeRunCheckBox, BorderLayout.SOUTH);
|
||||
JPanel checkboxPanel = new JPanel(new FlowLayout(FlowLayout.LEADING, JBUI.scale(5), JBUI.scale(5)));
|
||||
checkboxPanel.add(myShowSettingsBeforeRunCheckBox);
|
||||
checkboxPanel.add(myActivateToolWindowBeforeRunCheckBox);
|
||||
add(checkboxPanel, BorderLayout.SOUTH);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -165,7 +177,9 @@ class BeforeRunStepsPanel extends JPanel {
|
||||
originalTasks.addAll(runManager.getBeforeRunTasks(myRunConfiguration));
|
||||
myModel.replaceAll(originalTasks);
|
||||
myShowSettingsBeforeRunCheckBox.setSelected(settings.isEditBeforeRun());
|
||||
myShowSettingsBeforeRunCheckBox.setEnabled(!(isUnknown()));
|
||||
myShowSettingsBeforeRunCheckBox.setEnabled(!isUnknown());
|
||||
myActivateToolWindowBeforeRunCheckBox.setSelected(settings.isActivateToolWindowBeforeRun());
|
||||
myActivateToolWindowBeforeRunCheckBox.setEnabled(!isUnknown());
|
||||
myPanel.setVisible(checkBeforeRunTasksAbility(false));
|
||||
updateText();
|
||||
}
|
||||
@@ -209,6 +223,9 @@ class BeforeRunStepsPanel extends JPanel {
|
||||
}
|
||||
}
|
||||
}
|
||||
if (myActivateToolWindowBeforeRunCheckBox.isSelected()) {
|
||||
sb.append(sb.length() > 0 ? ", " : "").append(ExecutionBundle.message("configuration.activate.toolwindow.before.run"));
|
||||
}
|
||||
if (sb.length() > 0) {
|
||||
sb.insert(0, ": ");
|
||||
}
|
||||
@@ -228,6 +245,10 @@ class BeforeRunStepsPanel extends JPanel {
|
||||
return myShowSettingsBeforeRunCheckBox.isSelected();
|
||||
}
|
||||
|
||||
public boolean needActivateToolWindowBeforeRun() {
|
||||
return myActivateToolWindowBeforeRunCheckBox.isSelected();
|
||||
}
|
||||
|
||||
private boolean checkBeforeRunTasksAbility(boolean checkOnlyAddAction) {
|
||||
if (isUnknown()) {
|
||||
return false;
|
||||
|
||||
+2
@@ -130,8 +130,10 @@ public class ConfigurationSettingsEditorWrapper extends SettingsEditor<RunnerAnd
|
||||
RunnerAndConfigurationSettings runManagerSettings = runManager.getSettings(runConfiguration);
|
||||
if (runManagerSettings != null) {
|
||||
runManagerSettings.setEditBeforeRun(myBeforeRunStepsPanel.needEditBeforeRun());
|
||||
runManagerSettings.setActivateToolWindowBeforeRun(myBeforeRunStepsPanel.needActivateToolWindowBeforeRun());
|
||||
} else {
|
||||
settings.setEditBeforeRun(myBeforeRunStepsPanel.needEditBeforeRun());
|
||||
settings.setActivateToolWindowBeforeRun(myBeforeRunStepsPanel.needActivateToolWindowBeforeRun());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -388,6 +388,7 @@ class RunConfigurable extends BaseConfigurable {
|
||||
|
||||
JComponent configurableComponent = configurable.createComponent();
|
||||
final JBScrollPane scrollPane = new JBScrollPane(configurableComponent);
|
||||
scrollPane.getVerticalScrollBar().setUnitIncrement(10);
|
||||
scrollPane.setBorder(null);
|
||||
myRightPanel.add(scrollPane, BorderLayout.CENTER);
|
||||
if (configurable instanceof SingleConfigurationConfigurable) {
|
||||
|
||||
+19
@@ -72,6 +72,8 @@ public class RunnerAndConfigurationSettingsImpl implements JDOMExternalizable, C
|
||||
@NonNls
|
||||
private static final String EDIT_BEFORE_RUN = "editBeforeRun";
|
||||
@NonNls
|
||||
private static final String ACTIVATE_TOOLWINDOW_BEFORE_RUN = "activateToolWindowBeforeRun";
|
||||
@NonNls
|
||||
public static final String SINGLETON = "singleton";
|
||||
|
||||
/** for compatibility */
|
||||
@@ -98,6 +100,7 @@ public class RunnerAndConfigurationSettingsImpl implements JDOMExternalizable, C
|
||||
|
||||
private boolean myTemporary;
|
||||
private boolean myEditBeforeRun;
|
||||
private boolean myActivateToolWindowBeforeRun = true;
|
||||
private boolean mySingleton;
|
||||
private boolean myWasSingletonSpecifiedExplicitly;
|
||||
private String myFolderName;
|
||||
@@ -305,6 +308,16 @@ public class RunnerAndConfigurationSettingsImpl implements JDOMExternalizable, C
|
||||
return myEditBeforeRun;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setActivateToolWindowBeforeRun(boolean activate) {
|
||||
myActivateToolWindowBeforeRun = activate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isActivateToolWindowBeforeRun() {
|
||||
return myActivateToolWindowBeforeRun;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSingleton(boolean singleton) {
|
||||
mySingleton = singleton;
|
||||
@@ -338,6 +351,8 @@ public class RunnerAndConfigurationSettingsImpl implements JDOMExternalizable, C
|
||||
myIsTemplate = Boolean.valueOf(element.getAttributeValue(TEMPLATE_FLAG_ATTRIBUTE)).booleanValue();
|
||||
myTemporary = Boolean.valueOf(element.getAttributeValue(TEMPORARY_ATTRIBUTE)).booleanValue() || TEMP_CONFIGURATION.equals(element.getName());
|
||||
myEditBeforeRun = Boolean.valueOf(element.getAttributeValue(EDIT_BEFORE_RUN)).booleanValue();
|
||||
String value = element.getAttributeValue(ACTIVATE_TOOLWINDOW_BEFORE_RUN);
|
||||
myActivateToolWindowBeforeRun = value == null || Boolean.valueOf(value).booleanValue();
|
||||
myFolderName = element.getAttributeValue(FOLDER_NAME);
|
||||
//assert myID == null: "myId must be null at readExternal() stage";
|
||||
//myID = element.getAttributeValue(UNIQUE_ID, UUID.randomUUID().toString());
|
||||
@@ -391,6 +406,9 @@ public class RunnerAndConfigurationSettingsImpl implements JDOMExternalizable, C
|
||||
if (isEditBeforeRun()) {
|
||||
element.setAttribute(EDIT_BEFORE_RUN, String.valueOf(true));
|
||||
}
|
||||
if (!isActivateToolWindowBeforeRun()) {
|
||||
element.setAttribute(ACTIVATE_TOOLWINDOW_BEFORE_RUN, String.valueOf(false));
|
||||
}
|
||||
if (myWasSingletonSpecifiedExplicitly || mySingleton != factory.isConfigurationSingletonByDefault()) {
|
||||
element.setAttribute(SINGLETON, String.valueOf(mySingleton));
|
||||
}
|
||||
@@ -469,6 +487,7 @@ public class RunnerAndConfigurationSettingsImpl implements JDOMExternalizable, C
|
||||
|
||||
setSingleton(template.isSingleton());
|
||||
setEditBeforeRun(template.isEditBeforeRun());
|
||||
setActivateToolWindowBeforeRun(template.isActivateToolWindowBeforeRun());
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
|
||||
@@ -203,6 +203,9 @@ class InitialInfoBuilder {
|
||||
if (rootBlock instanceof ReadOnlyBlockInformationProvider) {
|
||||
myReadOnlyBlockInformationProvider = (ReadOnlyBlockInformationProvider)rootBlock;
|
||||
}
|
||||
if (!isInsideFormattingRanges && !myCollectAlignmentsInsideFormattingRange) {
|
||||
return processSimpleBlock(rootBlock, parent, true, index, parentBlock);
|
||||
}
|
||||
|
||||
final List<Block> subBlocks = rootBlock.getSubBlocks();
|
||||
if (subBlocks.isEmpty() || myReadOnlyBlockInformationProvider != null
|
||||
@@ -237,10 +240,11 @@ class InitialInfoBuilder {
|
||||
}
|
||||
boolean blocksMayBeOfInterest = false;
|
||||
|
||||
if (myPositionOfInterest != -1) {
|
||||
if (myPositionOfInterest != -1 && rootBlock.getTextRange().contains(myPositionOfInterest)) {
|
||||
myResult.put(wrappedRootBlock, rootBlock);
|
||||
blocksMayBeOfInterest = true;
|
||||
}
|
||||
|
||||
final boolean blocksAreReadOnly = rootBlock instanceof ReadOnlyBlockContainer || blocksMayBeOfInterest;
|
||||
|
||||
State state = new State(rootBlock, wrappedRootBlock, currentWrapParent, blocksAreReadOnly, rootBlockIsRightBlock);
|
||||
|
||||
+6
-14
@@ -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.
|
||||
@@ -31,7 +31,6 @@ import javax.swing.*;
|
||||
* @author Rustam Vishnyakov
|
||||
*/
|
||||
public class EnforcedPlainTextFileTypeFactory extends FileTypeFactory {
|
||||
|
||||
public static final LayeredIcon ENFORCED_PLAIN_TEXT_ICON = new LayeredIcon(2);
|
||||
public static final String ENFORCED_PLAIN_TEXT = "Enforced Plain Text";
|
||||
|
||||
@@ -40,15 +39,10 @@ public class EnforcedPlainTextFileTypeFactory extends FileTypeFactory {
|
||||
ENFORCED_PLAIN_TEXT_ICON.setIcon(PlatformIcons.EXCLUDED_FROM_COMPILE_ICON, 1);
|
||||
}
|
||||
|
||||
|
||||
private final FileTypeIdentifiableByVirtualFile myFileType;
|
||||
|
||||
|
||||
public EnforcedPlainTextFileTypeFactory() {
|
||||
|
||||
|
||||
myFileType = new FileTypeIdentifiableByVirtualFile() {
|
||||
|
||||
public EnforcedPlainTextFileTypeFactory() {
|
||||
myFileType = new FileTypeIdentifiableByVirtualFile() {
|
||||
@Override
|
||||
public boolean isMyFileType(@NotNull VirtualFile file) {
|
||||
return isMarkedAsPlainText(file);
|
||||
@@ -95,14 +89,12 @@ public class EnforcedPlainTextFileTypeFactory extends FileTypeFactory {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void createFileTypes(final @NotNull FileTypeConsumer consumer) {
|
||||
public void createFileTypes(@NotNull final FileTypeConsumer consumer) {
|
||||
consumer.consume(myFileType, "");
|
||||
}
|
||||
|
||||
private static boolean isMarkedAsPlainText(VirtualFile file) {
|
||||
private static boolean isMarkedAsPlainText(@NotNull VirtualFile file) {
|
||||
EnforcedPlainTextFileTypeManager typeManager = EnforcedPlainTextFileTypeManager.getInstance();
|
||||
if (typeManager == null) return false;
|
||||
return typeManager.isMarkedAsPlainText(file);
|
||||
return typeManager != null && typeManager.isMarkedAsPlainText(file);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+4
-4
@@ -48,7 +48,7 @@ public class EnforcedPlainTextFileTypeManager implements ProjectManagerListener
|
||||
ProjectManager.getInstance().addProjectManagerListener(this);
|
||||
}
|
||||
|
||||
public boolean isMarkedAsPlainText(VirtualFile file) {
|
||||
public boolean isMarkedAsPlainText(@NotNull VirtualFile file) {
|
||||
if (!(file instanceof VirtualFileWithId) || file.isDirectory()) return false;
|
||||
if (!mySetsInitialized) {
|
||||
synchronized (LOCK) {
|
||||
@@ -77,15 +77,15 @@ public class EnforcedPlainTextFileTypeManager implements ProjectManagerListener
|
||||
return !originalType.isBinary() && originalType != FileTypes.PLAIN_TEXT && originalType != StdFileTypes.JAVA;
|
||||
}
|
||||
|
||||
public void markAsPlainText(@NotNull Project project, VirtualFile... files) {
|
||||
public void markAsPlainText(@NotNull Project project, @NotNull VirtualFile... files) {
|
||||
setPlainTextStatus(project, true, files);
|
||||
}
|
||||
|
||||
public void resetOriginalFileType(@NotNull Project project, VirtualFile... files) {
|
||||
public void resetOriginalFileType(@NotNull Project project, @NotNull VirtualFile... files) {
|
||||
setPlainTextStatus(project, false, files);
|
||||
}
|
||||
|
||||
private void setPlainTextStatus(@NotNull final Project project, final boolean isAdded, final VirtualFile... files) {
|
||||
private void setPlainTextStatus(@NotNull final Project project, final boolean isAdded, @NotNull final VirtualFile... files) {
|
||||
ApplicationManager.getApplication().runWriteAction(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
|
||||
+10
-9
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2011 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.
|
||||
@@ -20,7 +20,7 @@ import com.intellij.openapi.vfs.VfsUtilCore;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.openapi.vfs.VirtualFileManager;
|
||||
import com.intellij.openapi.vfs.VirtualFileWithId;
|
||||
import com.intellij.util.containers.HashSet;
|
||||
import gnu.trove.THashSet;
|
||||
import org.jdom.Attribute;
|
||||
import org.jdom.Element;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -30,23 +30,23 @@ import java.util.*;
|
||||
/**
|
||||
* @author Rustam Vishnyakov
|
||||
*/
|
||||
public class PersistentFileSetManager implements PersistentStateComponent<Element> {
|
||||
class PersistentFileSetManager implements PersistentStateComponent<Element> {
|
||||
private static final String FILE_ELEMENT = "file";
|
||||
private static final String PATH_ATTR = "url";
|
||||
|
||||
private final Set<VirtualFile> myFiles = new HashSet<VirtualFile>();
|
||||
private final Set<VirtualFile> myFiles = new THashSet<VirtualFile>();
|
||||
|
||||
protected boolean addFile(VirtualFile file) {
|
||||
protected boolean addFile(@NotNull VirtualFile file) {
|
||||
if (!(file instanceof VirtualFileWithId) || file.isDirectory()) return false;
|
||||
myFiles.add(file);
|
||||
return true;
|
||||
}
|
||||
|
||||
protected boolean containsFile(VirtualFile file) {
|
||||
protected boolean containsFile(@NotNull VirtualFile file) {
|
||||
return myFiles.contains(file);
|
||||
}
|
||||
|
||||
protected boolean removeFile(VirtualFile file) {
|
||||
protected boolean removeFile(@NotNull VirtualFile file) {
|
||||
if (!myFiles.contains(file)) return false;
|
||||
myFiles.remove(file);
|
||||
return true;
|
||||
@@ -56,8 +56,9 @@ public class PersistentFileSetManager implements PersistentStateComponent<Elemen
|
||||
public Collection<VirtualFile> getFiles() {
|
||||
return myFiles;
|
||||
}
|
||||
|
||||
public Collection<VirtualFile> getSortedFiles() {
|
||||
|
||||
@NotNull
|
||||
private Collection<VirtualFile> getSortedFiles() {
|
||||
List<VirtualFile> sortedFiles = new ArrayList<VirtualFile>();
|
||||
sortedFiles.addAll(myFiles);
|
||||
Collections.sort(sortedFiles, new Comparator<VirtualFile>() {
|
||||
|
||||
+3
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2012 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.
|
||||
@@ -22,6 +22,7 @@ import com.intellij.openapi.components.StoragePathMacros;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.roots.ProjectFileIndex;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* @author Rustam Vishnyakov
|
||||
@@ -34,7 +35,7 @@ public class ProjectPlainTextFileTypeManager extends PersistentFileSetManager {
|
||||
myIndex = projectFileIndex;
|
||||
}
|
||||
|
||||
public boolean hasProjectContaining(VirtualFile file) {
|
||||
boolean hasProjectContaining(@NotNull VirtualFile file) {
|
||||
return myIndex.isInContent(file);
|
||||
}
|
||||
|
||||
|
||||
@@ -74,17 +74,10 @@ public class CodeStyleFacadeImpl extends CodeStyleFacade {
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public boolean isWrapWhenTypingReachesRightMargin() {
|
||||
//noinspection deprecation
|
||||
return CodeStyleSettingsManager.getSettings(myProject).WRAP_WHEN_TYPING_REACHES_RIGHT_MARGIN;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isWrapOnTyping(@Nullable Language language) {
|
||||
return CodeStyleSettingsManager.getSettings(myProject).isWrapOnTyping(language);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getTabSize(final FileType fileType) {
|
||||
return CodeStyleSettingsManager.getSettings(myProject).getTabSize(fileType);
|
||||
|
||||
@@ -56,17 +56,8 @@ public abstract class CodeStyleFacade {
|
||||
|
||||
public abstract int getRightMargin(Language language);
|
||||
|
||||
/**
|
||||
* @return True if wrap on typing is enabled
|
||||
* @deprecated Use isWrapOnTyping(language) instead
|
||||
*/
|
||||
public abstract boolean isWrapWhenTypingReachesRightMargin();
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public boolean isWrapOnTyping(@Nullable Language language) {
|
||||
return isWrapWhenTypingReachesRightMargin();
|
||||
}
|
||||
|
||||
public abstract int getTabSize(final FileType fileType);
|
||||
|
||||
public abstract boolean useTabCharacter(final FileType fileType);
|
||||
|
||||
@@ -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.
|
||||
@@ -65,7 +65,7 @@ public class MockFileTypeManager extends FileTypeManager {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFileIgnored(@NonNls @NotNull VirtualFile file) {
|
||||
public boolean isFileIgnored(@NotNull VirtualFile file) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -123,6 +123,7 @@ public class MockFileTypeManager extends FileTypeManager {
|
||||
return MockLanguageFileType.INSTANCE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFileOfType(@NotNull VirtualFile file, @NotNull FileType type) {
|
||||
return false;
|
||||
}
|
||||
@@ -135,7 +136,7 @@ public class MockFileTypeManager extends FileTypeManager {
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public FileType findFileTypeByName(String fileTypeName) {
|
||||
public FileType findFileTypeByName(@NotNull String fileTypeName) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,10 +22,14 @@ import com.intellij.openapi.ui.ComponentWithBrowseButton;
|
||||
import com.intellij.openapi.ui.TextComponentAccessor;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
/**
|
||||
* User: anna
|
||||
*/
|
||||
public class TextFieldWithHistoryWithBrowseButton extends ComponentWithBrowseButton<TextFieldWithHistory> {
|
||||
private String myText;
|
||||
|
||||
public TextFieldWithHistoryWithBrowseButton() {
|
||||
super(new TextFieldWithHistory(), null);
|
||||
}
|
||||
@@ -54,4 +58,10 @@ public class TextFieldWithHistoryWithBrowseButton extends ComponentWithBrowseBut
|
||||
public String getText() {
|
||||
return getChildComponent().getText();
|
||||
}
|
||||
|
||||
public void setText(String text) {
|
||||
final ComboBoxModel model = getChildComponent().getModel();
|
||||
model.setSelectedItem(text);
|
||||
myText = text;
|
||||
}
|
||||
}
|
||||
|
||||
+3
-14
@@ -501,20 +501,9 @@ public class EditorMarkupModelImpl extends MarkupModelImpl implements EditorMark
|
||||
}
|
||||
|
||||
if (myErrorStripeRenderer != null) {
|
||||
if (isMirrored() && g instanceof Graphics2D) {
|
||||
Graphics2D g2d = (Graphics2D)g;
|
||||
AffineTransform old = g2d.getTransform();
|
||||
AffineTransform tx = AffineTransform.getScaleInstance(-1, 1);
|
||||
tx.translate(-getErrorIconWidth(), 0);
|
||||
g2d.transform(tx);
|
||||
myErrorStripeRenderer.paint(this, g2d, new Rectangle(0, 0, getErrorIconWidth(), getErrorIconHeight()));
|
||||
g2d.setTransform(old);
|
||||
}
|
||||
else {
|
||||
int x = getThinGap() + myMinMarkHeight;
|
||||
final Rectangle b = new Rectangle(x, 0, getErrorIconWidth(), getErrorIconHeight());
|
||||
myErrorStripeRenderer.paint(this, g, b);
|
||||
}
|
||||
int x = isMirrored() ? 0 : (getThinGap() + myMinMarkHeight);
|
||||
final Rectangle b = new Rectangle(x, 0, getErrorIconWidth(), getErrorIconHeight());
|
||||
myErrorStripeRenderer.paint(this, g, b);
|
||||
}
|
||||
}
|
||||
finally {
|
||||
|
||||
@@ -213,7 +213,7 @@ public class SettingsImpl implements EditorSettings {
|
||||
public boolean isWrapWhenTypingReachesRightMargin(Project project) {
|
||||
return myWrapWhenTypingReachesRightMargin != null ?
|
||||
myWrapWhenTypingReachesRightMargin.booleanValue() :
|
||||
CodeStyleFacade.getInstance(project).isWrapOnTyping(myLanguage);
|
||||
CodeStyleFacade.getInstance(project).isWrapWhenTypingReachesRightMargin();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -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.
|
||||
@@ -144,7 +144,7 @@ public class FileTypeChooser extends DialogWrapper {
|
||||
}
|
||||
FileType type = file.getFileType();
|
||||
if (type == FileTypes.UNKNOWN) {
|
||||
type = getKnownFileTypeOrAssociate(file.getName());
|
||||
type = getKnownFileTypeOrAssociate(file.getName());
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
+12
-10
@@ -594,7 +594,7 @@ public class FileTypeManagerImpl extends FileTypeManagerEx implements Persistent
|
||||
}
|
||||
|
||||
@Override
|
||||
public FileType findFileTypeByName(String fileTypeName) {
|
||||
public FileType findFileTypeByName(@NotNull String fileTypeName) {
|
||||
FileType type = getStdFileType(fileTypeName);
|
||||
// TODO: Abstract file types are not std one, so need to be restored specially,
|
||||
// currently there are 6 of them and restoration does not happen very often so just iteration is enough
|
||||
@@ -738,7 +738,7 @@ public class FileTypeManagerImpl extends FileTypeManagerEx implements Persistent
|
||||
});
|
||||
}
|
||||
|
||||
private void unregisterFileTypeWithoutNotification(FileType fileType) {
|
||||
private void unregisterFileTypeWithoutNotification(@NotNull FileType fileType) {
|
||||
myPatternsTable.removeAllAssociations(fileType);
|
||||
mySchemesManager.removeScheme(fileType);
|
||||
if (fileType instanceof FileTypeIdentifiableByVirtualFile) {
|
||||
@@ -793,14 +793,14 @@ public class FileTypeManagerImpl extends FileTypeManagerEx implements Persistent
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFileIgnored(@NonNls @NotNull VirtualFile file) {
|
||||
public boolean isFileIgnored(@NotNull VirtualFile file) {
|
||||
return myIgnoredFileCache.isFileIgnored(file);
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings({"deprecation"})
|
||||
@NotNull
|
||||
public String[] getAssociatedExtensions(@NotNull FileType type) {
|
||||
//noinspection deprecation
|
||||
return myPatternsTable.getAssociatedExtensions(type);
|
||||
}
|
||||
|
||||
@@ -1033,7 +1033,7 @@ public class FileTypeManagerImpl extends FileTypeManagerEx implements Persistent
|
||||
FileNameMatcher[] unresolvedMappingKeys = myUnresolvedMappings.keySet().toArray(new FileNameMatcher[myUnresolvedMappings.size()]);
|
||||
Arrays.sort(unresolvedMappingKeys, new Comparator<FileNameMatcher>() {
|
||||
@Override
|
||||
public int compare(FileNameMatcher o1, FileNameMatcher o2) {
|
||||
public int compare(@NotNull FileNameMatcher o1, @NotNull FileNameMatcher o2) {
|
||||
return o1.getPresentableString().compareTo(o2.getPresentableString());
|
||||
}
|
||||
});
|
||||
@@ -1080,7 +1080,7 @@ public class FileTypeManagerImpl extends FileTypeManagerEx implements Persistent
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isApproved(FileNameMatcher matcher) {
|
||||
private boolean isApproved(@NotNull FileNameMatcher matcher) {
|
||||
Pair<FileType, Boolean> pair = myRemovedMappings.get(matcher);
|
||||
return pair != null && pair.getSecond();
|
||||
}
|
||||
@@ -1234,7 +1234,7 @@ public class FileTypeManagerImpl extends FileTypeManagerEx implements Persistent
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean shouldSave(FileType fileType) {
|
||||
private static boolean shouldSave(@NotNull FileType fileType) {
|
||||
return fileType != FileTypes.UNKNOWN && !fileType.isReadOnly();
|
||||
}
|
||||
|
||||
@@ -1248,6 +1248,7 @@ public class FileTypeManagerImpl extends FileTypeManagerEx implements Persistent
|
||||
return getFileTypeComponentName();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static String getFileTypeComponentName() {
|
||||
return PlatformUtils.isIdeaCommunity() ? "CommunityFileTypes" : "FileTypeManager";
|
||||
}
|
||||
@@ -1274,7 +1275,7 @@ public class FileTypeManagerImpl extends FileTypeManagerEx implements Persistent
|
||||
fireFileTypesChanged();
|
||||
}
|
||||
|
||||
public void associate(FileType fileType, FileNameMatcher matcher, boolean fireChange) {
|
||||
public void associate(@NotNull FileType fileType, @NotNull FileNameMatcher matcher, boolean fireChange) {
|
||||
if (!myPatternsTable.isAssociatedWith(fileType, matcher)) {
|
||||
if (fireChange) {
|
||||
fireBeforeFileTypesChanged();
|
||||
@@ -1286,7 +1287,7 @@ public class FileTypeManagerImpl extends FileTypeManagerEx implements Persistent
|
||||
}
|
||||
}
|
||||
|
||||
public void removeAssociation(FileType fileType, FileNameMatcher matcher, boolean fireChange) {
|
||||
public void removeAssociation(@NotNull FileType fileType, @NotNull FileNameMatcher matcher, boolean fireChange) {
|
||||
if (myPatternsTable.isAssociatedWith(fileType, matcher)) {
|
||||
if (fireChange) {
|
||||
fireBeforeFileTypesChanged();
|
||||
@@ -1311,7 +1312,7 @@ public class FileTypeManagerImpl extends FileTypeManagerEx implements Persistent
|
||||
return FileTypeChooser.getKnownFileTypeOrAssociate(file, project);
|
||||
}
|
||||
|
||||
private void registerReDetectedMappings(StandardFileType pair) {
|
||||
private void registerReDetectedMappings(@NotNull StandardFileType pair) {
|
||||
FileType fileType = pair.fileType;
|
||||
if (fileType == PlainTextFileType.INSTANCE) return;
|
||||
for (FileNameMatcher matcher : pair.matchers) {
|
||||
@@ -1333,6 +1334,7 @@ public class FileTypeManagerImpl extends FileTypeManagerEx implements Persistent
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
Map<FileNameMatcher, Pair<FileType, Boolean>> getRemovedMappings() {
|
||||
return myRemovedMappings;
|
||||
}
|
||||
|
||||
+1
-1
@@ -217,7 +217,7 @@ public class ProjectManagerImpl extends ProjectManagerEx implements PersistentSt
|
||||
}
|
||||
|
||||
public static int TEST_PROJECTS_CREATED;
|
||||
private static final boolean LOG_PROJECT_LEAKAGE_IN_TESTS = false;
|
||||
private static final boolean LOG_PROJECT_LEAKAGE_IN_TESTS = true;
|
||||
private static final int MAX_LEAKY_PROJECTS = 42;
|
||||
@SuppressWarnings("FieldCanBeLocal") private final Map<Project, String> myProjects = new WeakHashMap<Project, String>();
|
||||
|
||||
|
||||
@@ -1053,6 +1053,32 @@ public class FSRecords implements Forceable {
|
||||
}
|
||||
}
|
||||
|
||||
// returns id, parent(id), parent(parent(id)), ... rootId
|
||||
@NotNull
|
||||
public static TIntArrayList getParents(int id) {
|
||||
TIntArrayList result = new TIntArrayList(10);
|
||||
r.lock();
|
||||
try {
|
||||
int parentId;
|
||||
do {
|
||||
result.add(id);
|
||||
parentId = getRecordInt(id, PARENT_OFFSET);
|
||||
if (parentId == id || result.size() % 128 == 0 && result.contains(parentId)) {
|
||||
LOG.error("Cyclic parent child relations in the database. id = " + parentId);
|
||||
return result;
|
||||
}
|
||||
id = parentId;
|
||||
} while (parentId != 0);
|
||||
}
|
||||
catch (Throwable e) {
|
||||
throw DbConnection.handleError(e);
|
||||
}
|
||||
finally {
|
||||
r.unlock();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static void setParent(int id, int parent) {
|
||||
if (id == parent) {
|
||||
LOG.error("Cyclic parent/child relations");
|
||||
|
||||
+14
-48
@@ -61,7 +61,7 @@ public class PersistentFSImpl extends PersistentFS implements ApplicationCompone
|
||||
|
||||
private final ReadWriteLock myRootsLock = new ReentrantReadWriteLock();
|
||||
private final Map<String, VirtualFileSystemEntry> myRoots = ContainerUtil.newTroveMap(FileUtil.PATH_HASHING_STRATEGY);
|
||||
private final TIntObjectHashMap<VirtualFileSystemEntry> myRootsById = new TIntObjectHashMap<VirtualFileSystemEntry>();
|
||||
private final ConcurrentIntObjectMap<VirtualFileSystemEntry> myRootsById = ContainerUtil.createConcurrentIntObjectMap();
|
||||
|
||||
private final ConcurrentIntObjectMap<VirtualFileSystemEntry> myIdToDirCache = ContainerUtil.createConcurrentIntObjectMap();
|
||||
private final Object myInputLock = new Object();
|
||||
@@ -199,7 +199,7 @@ public class PersistentFSImpl extends PersistentFS implements ApplicationCompone
|
||||
return nameIds.toArray(new FSRecords.NameId[nameIds.size()]);
|
||||
}
|
||||
|
||||
public static void setChildrenCached(int id) {
|
||||
private static void setChildrenCached(int id) {
|
||||
int flags = FSRecords.getFlags(id);
|
||||
FSRecords.setFlags(id, flags | CHILDREN_CACHED_FLAG, true);
|
||||
}
|
||||
@@ -311,11 +311,6 @@ public class PersistentFSImpl extends PersistentFS implements ApplicationCompone
|
||||
return isDirectory(getFileAttributes(getFileId(file)));
|
||||
}
|
||||
|
||||
private static int getParent(final int id) {
|
||||
assert id > 0;
|
||||
return FSRecords.getParent(id);
|
||||
}
|
||||
|
||||
private static boolean namesEqual(@NotNull VirtualFileSystem fs, @NotNull CharSequence n1, CharSequence n2) {
|
||||
return Comparing.equal(n1, n2, fs.isCaseSensitive());
|
||||
}
|
||||
@@ -912,9 +907,8 @@ public class PersistentFSImpl extends PersistentFS implements ApplicationCompone
|
||||
return null;
|
||||
}
|
||||
|
||||
boolean mark = false;
|
||||
|
||||
myRootsLock.writeLock().lock();
|
||||
boolean mark = false;
|
||||
try {
|
||||
VirtualFileSystemEntry root = myRoots.get(rootUrl);
|
||||
if (root != null) return root;
|
||||
@@ -962,59 +956,31 @@ public class PersistentFSImpl extends PersistentFS implements ApplicationCompone
|
||||
myIdToDirCache.clear();
|
||||
}
|
||||
|
||||
private static final int DEPTH_LIMIT = 75;
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public NewVirtualFile findFileById(final int id) {
|
||||
return findFileById(id, false, null, 0);
|
||||
return findFileById(id, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public NewVirtualFile findFileByIdIfCached(final int id) {
|
||||
return findFileById(id, true, null, 0);
|
||||
return findFileById(id, true);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private VirtualFileSystemEntry findFileById(int id, boolean cachedOnly, TIntArrayList visited, int mask) {
|
||||
private VirtualFileSystemEntry findFileById(int id, boolean cachedOnly) {
|
||||
VirtualFileSystemEntry cached = myIdToDirCache.get(id);
|
||||
if (cached != null) return cached;
|
||||
|
||||
if (visited != null && (visited.size() >= DEPTH_LIMIT || (mask & id) == id && visited.contains(id))) {
|
||||
@NonNls String sb = "Dead loop detected in persistent FS (id=" + id + " cached-only=" + cachedOnly + "):";
|
||||
for (int i = 0; i < visited.size(); i++) {
|
||||
int _id = visited.get(i);
|
||||
sb += "\n " + _id + " '" + getName(_id) + "' " +
|
||||
String.format("%02x", getFileAttributes(_id)) + ' ' + myIdToDirCache.containsKey(_id);
|
||||
}
|
||||
LOG.error(sb);
|
||||
return null;
|
||||
}
|
||||
|
||||
int parentId = getParent(id);
|
||||
if (parentId >= id) {
|
||||
if (visited == null) visited = new TIntArrayList(DEPTH_LIMIT);
|
||||
}
|
||||
if (visited != null) visited.add(id);
|
||||
|
||||
VirtualFileSystemEntry result;
|
||||
if (parentId == 0) {
|
||||
myRootsLock.readLock().lock();
|
||||
try {
|
||||
result = myRootsById.get(id);
|
||||
}
|
||||
finally {
|
||||
myRootsLock.readLock().unlock();
|
||||
}
|
||||
}
|
||||
else {
|
||||
VirtualFileSystemEntry parentFile = findFileById(parentId, cachedOnly, visited, mask | id);
|
||||
if (parentFile instanceof VirtualDirectoryImpl) {
|
||||
result = ((VirtualDirectoryImpl)parentFile).findChildById(id, cachedOnly);
|
||||
}
|
||||
else {
|
||||
result = null;
|
||||
TIntArrayList parents = FSRecords.getParents(id);
|
||||
int rootId = parents.get(parents.size() - 1);
|
||||
VirtualFileSystemEntry result = myRootsById.get(rootId);
|
||||
for (int i=parents.size() - 2; i>=0; i--) {
|
||||
if (result == null) {
|
||||
break;
|
||||
}
|
||||
int parentId = parents.get(i);
|
||||
result = ((VirtualDirectoryImpl)result).findChildById(parentId, cachedOnly);
|
||||
}
|
||||
|
||||
if (result != null && result.isDirectory()) {
|
||||
|
||||
@@ -985,7 +985,11 @@ public class FocusManagerImpl extends IdeFocusManager implements Disposable {
|
||||
@Override
|
||||
public void run() {
|
||||
if (ApplicationManager.getApplication().isActive()) {
|
||||
window.toFront();
|
||||
if (window instanceof JFrame && ((JFrame)window).getState() == Frame.ICONIFIED) {
|
||||
((JFrame)window).setState(Frame.NORMAL);
|
||||
} else {
|
||||
window.toFront();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -1094,7 +1098,7 @@ public class FocusManagerImpl extends IdeFocusManager implements Disposable {
|
||||
if (mgr.getFocusOwner() == null) {
|
||||
Component c = getComponent(myLastFocusedAtDeactivation, ideFrame);
|
||||
if (c == null || !c.isShowing()) {
|
||||
c = getComponent(myLastFocused, ideFrame);
|
||||
c = getComponent(myLastFocusedAtDeactivation, ideFrame);
|
||||
}
|
||||
|
||||
final boolean mouseEventAhead = IdeEventQueue.isMouseEventAhead(null);
|
||||
|
||||
@@ -223,7 +223,6 @@ wrapping.long.lines=Ensure right margin is not exceeded
|
||||
wrapping.comments=Comments
|
||||
wrapping.comments.wrap.at.right.margin=Wrap at right margin
|
||||
wrapping.annotation.parameters=Annotation parameters
|
||||
wrapping.wrap.on.typing=Wrap on typing
|
||||
|
||||
checkbox.align.multiline.chained.methods=Chained methods
|
||||
checkbox.align.multiline.method.parameters=Method parameters
|
||||
|
||||
@@ -351,6 +351,7 @@ export.test.results.footer=Generated by {0} on {1}
|
||||
export.test.results.file.exists.message=File ''{0}'' already exists.\nDo you want to overwrite it?
|
||||
export.test.results.file.exists.title=Export Test Results
|
||||
configuration.edit.before.run=Show this page
|
||||
configuration.activate.toolwindow.before.run=Activate tool window
|
||||
configuration.singleton=Check no other instances are running
|
||||
failed.to.create.output.file=Failed to create output file ''{0}''
|
||||
|
||||
|
||||
@@ -1,243 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2011 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.openapi.editor.impl;
|
||||
|
||||
import com.intellij.openapi.editor.event.DocumentEvent;
|
||||
import com.intellij.openapi.editor.impl.event.DocumentEventImpl;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.util.LocalTimeCounter;
|
||||
import com.intellij.util.containers.Stack;
|
||||
import com.intellij.util.text.CharSequenceBackedByArray;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jmock.Expectations;
|
||||
import org.jmock.Mockery;
|
||||
import org.jmock.api.Invocation;
|
||||
import org.jmock.integration.junit4.JUnit4Mockery;
|
||||
import org.jmock.lib.action.CustomAction;
|
||||
import org.jmock.lib.legacy.ClassImposteriser;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.TestWatcher;
|
||||
import org.junit.runner.Description;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* @author Denis Zhdanov
|
||||
* @since 03/01/2011
|
||||
*/
|
||||
public class CharArrayTest {
|
||||
@Rule
|
||||
public TestWatcher configReader = new TestWatcher() {
|
||||
@Override
|
||||
protected void starting(Description description) {
|
||||
Config config = description.getAnnotation(Config.class);
|
||||
if (config != null) {
|
||||
myConfig = config;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private CharArray myArray;
|
||||
private Config myConfig;
|
||||
private Mockery myMockery;
|
||||
private DocumentImpl myDocument;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
myMockery = new JUnit4Mockery() {{
|
||||
setImposteriser(ClassImposteriser.INSTANCE);
|
||||
}};
|
||||
myDocument = myMockery.mock(DocumentImpl.class);
|
||||
|
||||
myMockery.checking(new Expectations() {{
|
||||
allowing(myDocument).getTextLength(); will(new CustomAction("getTextLength") {
|
||||
@Override
|
||||
public Object invoke(Invocation invocation) throws Throwable {
|
||||
return myArray.length();
|
||||
}
|
||||
});
|
||||
}});
|
||||
|
||||
init(10);
|
||||
if (myConfig != null) {
|
||||
myArray.insert(myConfig.text(), 0);
|
||||
myArray.setDeferredChangeMode(myConfig.deferred());
|
||||
}
|
||||
}
|
||||
|
||||
@After
|
||||
public void checkExpectations() {
|
||||
myMockery.assertIsSatisfied();
|
||||
}
|
||||
|
||||
@Config(text = "1234", deferred = true)
|
||||
@Test
|
||||
public void deferredReplace() {
|
||||
replace(1, 3, "abc");
|
||||
assertTrue(myArray.hasDeferredChanges());
|
||||
checkText("1abc4");
|
||||
|
||||
replace(2, 3, "XY");
|
||||
checkText("1aXYc4");
|
||||
|
||||
replace(3, 6, "ABC");
|
||||
checkText("1aXABC");
|
||||
|
||||
myArray.setDeferredChangeMode(false);
|
||||
checkText("1aXABC");
|
||||
}
|
||||
|
||||
@Config(text = "01234567", deferred = true)
|
||||
@Test
|
||||
public void subSequenceWithDeferredChangeBeforeIt() {
|
||||
replace(0, 2, "abc");
|
||||
CharSequenceBackedByArray subsSequence = (CharSequenceBackedByArray)myArray.subSequence(5, 6);
|
||||
assertArrayEquals("4".toCharArray(), subsSequence.getChars());
|
||||
}
|
||||
|
||||
@Config(text = "01234567", deferred = true)
|
||||
@Test
|
||||
public void subSequenceWithDeferredChangeIntersectingFromLeft() {
|
||||
replace(0, 2, "abc");
|
||||
CharSequenceBackedByArray subsSequence = (CharSequenceBackedByArray)myArray.subSequence(2, 4);
|
||||
assertArrayEquals("c2".toCharArray(), subsSequence.getChars());
|
||||
}
|
||||
|
||||
@Config(text = "01234567", deferred = true)
|
||||
@Test
|
||||
public void subSequenceWithDeferredChangeIntersectingFromRight() {
|
||||
replace(4, 6, "abc");
|
||||
CharSequenceBackedByArray subsSequence = (CharSequenceBackedByArray)myArray.subSequence(3, 5);
|
||||
assertArrayEquals("3a".toCharArray(), subsSequence.getChars());
|
||||
}
|
||||
|
||||
@Config(text = "01234567", deferred = true)
|
||||
@Test
|
||||
public void subSequenceWithDeferredChangeAfterIt() {
|
||||
replace(6, 8, "abc");
|
||||
CharSequenceBackedByArray subsSequence = (CharSequenceBackedByArray)myArray.subSequence(1, 2);
|
||||
assertArrayEquals("1".toCharArray(), subsSequence.getChars());
|
||||
}
|
||||
|
||||
private void init(int size) {
|
||||
myArray = new CharArray(size, new char[0], 0) {
|
||||
@NotNull
|
||||
@Override
|
||||
protected DocumentEvent beforeChangedUpdate(int offset, CharSequence oldString, CharSequence newString,
|
||||
boolean wholeTextReplaced) {
|
||||
return new DocumentEventImpl(myDocument, offset, oldString, newString, LocalTimeCounter.currentTime(), wholeTextReplaced);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void afterChangedUpdate(@NotNull DocumentEvent event, long newModificationStamp) {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void assertWriteAccess() {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void assertReadAccess() {
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private void checkText(@NonNls @NotNull String expected) {
|
||||
// Test as a whole.
|
||||
assertEquals(expected, myArray.toString());
|
||||
assertEquals(expected.length(), myArray.length());
|
||||
|
||||
// Test 'charAt()'.
|
||||
for (int i = 0; i < expected.length(); i++) {
|
||||
if (expected.charAt(i) != myArray.charAt(i)) {
|
||||
fail(String.format(
|
||||
"Detected incorrect 'charAt()' processing for deferred changes. Text: '%1$s'. Expected to get symbol '%2$c' "
|
||||
+ "(numeric value %2$d) at index %3$d but actual symbol is '%4$c' (numeric value %4$d)",
|
||||
expected, (int)expected.charAt(i), i, (int)myArray.charAt(i)));
|
||||
}
|
||||
assertEquals(expected.charAt(i), myArray.charAt(i));
|
||||
}
|
||||
|
||||
// Test 'substring()'.
|
||||
for (int start = 0; start < myArray.length() - 1; start++) {
|
||||
for (int end = start; end < myArray.length(); end++) {
|
||||
if (!expected.substring(start, end).equals(myArray.substring(start, end).toString())) {
|
||||
fail(String.format(
|
||||
"Detected incorrect 'substring()' processing for deferred changes. Text: '%s', expected to get substring '%s' for "
|
||||
+ "interval [%d; %d) but got '%s'", expected, expected.substring(start, end), start, end, myArray.substring(start, end)
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Test subSequence().
|
||||
checkSubSequence(expected, myArray, new Stack<Pair<Integer, Integer>>());
|
||||
}
|
||||
|
||||
private void checkSubSequence(@NotNull String expected, @NotNull CharSequence actual,
|
||||
@NotNull Stack<Pair<Integer, Integer>> history) {
|
||||
assertEquals(expected.length(), actual.length());
|
||||
for (int i = 0; i < expected.length(); i++) {
|
||||
char expectedChar = expected.charAt(i);
|
||||
char actualChar = actual.charAt(i);
|
||||
if (expectedChar != actualChar) {
|
||||
fail(String.format(
|
||||
"Detected incorrect charAt() processing for result of subSequence() with deferred changes. Original text: '%s', "
|
||||
+ "actual subSequence text: '%s', index: %d, expected symbol: '%c', actual symbol: '%c', subSequence history: %s",
|
||||
myArray.toString(), expected, i, expectedChar, actualChar, history
|
||||
));
|
||||
}
|
||||
}
|
||||
if (!expected.equals(actual.toString())) {
|
||||
fail(String.format(
|
||||
"Detected incorrect toString() processing for result of subSequence() with deferred changes. Original text: '%s', "
|
||||
+ "expected subSequence text: '%s', actual subSequence text: '%s', subSequence history: %s",
|
||||
myArray.toString(), expected, actual.toString(), history
|
||||
));
|
||||
}
|
||||
assertEquals(expected, actual.toString());
|
||||
for (int start = 0; start < expected.length(); start++) {
|
||||
for (int end = start; end < expected.length(); end++) {
|
||||
history.push(new Pair<Integer, Integer>(start, end));
|
||||
checkSubSequence(expected.substring(start, end), actual.subSequence(start, end), history);
|
||||
history.pop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void replace(int startOffset, int endOffset, @NonNls String newText) {
|
||||
myArray.replace(
|
||||
startOffset, endOffset, myArray.substring(startOffset, endOffset), newText, LocalTimeCounter.currentTime(),
|
||||
startOffset == 0 && endOffset == myArray.length()
|
||||
);
|
||||
}
|
||||
|
||||
@Target(ElementType.METHOD)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
private @interface Config {
|
||||
String text() default "";
|
||||
boolean deferred() default false;
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,18 @@
|
||||
/*
|
||||
* 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.options
|
||||
|
||||
import com.intellij.openapi.application.invokeAndWaitIfNeed
|
||||
@@ -9,7 +24,10 @@ import com.intellij.openapi.util.JDOMUtil
|
||||
import com.intellij.openapi.util.io.BufferExposingByteArrayOutputStream
|
||||
import com.intellij.openapi.util.io.FileUtil
|
||||
import com.intellij.openapi.util.text.StringUtil
|
||||
import com.intellij.testFramework.FixtureRule
|
||||
import com.intellij.testFramework.PlatformTestUtil
|
||||
import com.intellij.testFramework.TemporaryDirectory
|
||||
import com.intellij.testFramework.exists
|
||||
import com.intellij.util.SmartList
|
||||
import com.intellij.util.lang.CompoundRuntimeException
|
||||
import com.intellij.util.xmlb.SkipDefaultValuesSerializationFilters
|
||||
@@ -25,9 +43,6 @@ import org.hamcrest.CoreMatchers.sameInstance
|
||||
import org.hamcrest.MatcherAssert.assertThat
|
||||
import org.hamcrest.collection.IsMapContaining.hasKey
|
||||
import org.jdom.Element
|
||||
import org.jetbrains.testFramework.FixtureRule
|
||||
import org.jetbrains.testFramework.TemporaryDirectory
|
||||
import org.jetbrains.testFramework.exists
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import java.io.File
|
||||
|
||||
@@ -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.
|
||||
@@ -106,7 +106,7 @@ public class MockFileTypeManager extends FileTypeManagerEx {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFileIgnored(@NonNls @NotNull VirtualFile file) {
|
||||
public boolean isFileIgnored(@NotNull VirtualFile file) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -191,7 +191,7 @@ public class MockFileTypeManager extends FileTypeManagerEx {
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public FileType findFileTypeByName(String fileTypeName) {
|
||||
public FileType findFileTypeByName(@NotNull String fileTypeName) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
+1
-2
@@ -13,10 +13,9 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jetbrains.testFramework
|
||||
package com.intellij.testFramework
|
||||
|
||||
import com.intellij.openapi.application.invokeAndWaitIfNeed
|
||||
import com.intellij.testFramework.UsefulTestCase
|
||||
import com.intellij.testFramework.fixtures.IdeaTestFixtureFactory
|
||||
import org.junit.rules.ExternalResource
|
||||
|
||||
+1
-1
@@ -13,7 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jetbrains.testFramework
|
||||
package com.intellij.testFramework
|
||||
|
||||
import com.intellij.openapi.util.io.FileUtil
|
||||
import com.intellij.openapi.util.io.FileUtilRt
|
||||
+1
-1
@@ -13,7 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jetbrains.testFramework
|
||||
package com.intellij.testFramework
|
||||
|
||||
import org.hamcrest.Description
|
||||
import org.hamcrest.Factory
|
||||
@@ -144,7 +144,7 @@ editor.soft.wrap.force.limit.description=If document contains lines longer than
|
||||
editor.navigation.history.stack.size=25
|
||||
editor.navigation.history.stack.size.description=Stack size limit for back/forward and last/next edit location navigation
|
||||
|
||||
editor.mac.smooth.scrolling=true
|
||||
editor.mac.smooth.scrolling=false
|
||||
editor.mac.smooth.scrolling.description=Enable precise (with sub-line resolution) scrolling on Mac with mouse or trackpad
|
||||
|
||||
ide.showIndexRebuildMessage=false
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
*/
|
||||
package com.intellij.util.text;
|
||||
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class ByteArrayCharSequence implements CharSequence {
|
||||
@@ -40,11 +39,6 @@ public class ByteArrayCharSequence implements CharSequence {
|
||||
return h;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
return obj instanceof CharSequence && StringUtil.equals(this, (CharSequence)obj);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final int length() {
|
||||
return myChars.length;
|
||||
|
||||
@@ -233,13 +233,15 @@ public class FileUtilHeavyTest {
|
||||
public void testToCanonicalPathSymLinksAware() throws Exception {
|
||||
assumeTrue(SystemInfo.areSymLinksSupported);
|
||||
|
||||
File root = IoTestUtil.createTestDir(myTempDirectory, "root");
|
||||
assertTrue(new File(root, "dir1/dir2/dir3/dir4").mkdirs());
|
||||
File rootDir = IoTestUtil.createTestDir(myTempDirectory, "root");
|
||||
assertTrue(new File(rootDir, "dir1/dir2/dir3/dir4").mkdirs());
|
||||
|
||||
String root = FileUtil.toSystemIndependentName(FileUtil.resolveShortWindowsName(rootDir.getPath()));
|
||||
|
||||
// non-recursive link
|
||||
IoTestUtil.createSymLink(new File(root, "dir1/dir2").getPath(), new File(root, "dir1/dir2_link").getPath());
|
||||
IoTestUtil.createSymLink(new File(rootDir, "dir1/dir2").getPath(), new File(rootDir, "dir1/dir2_link").getPath());
|
||||
// recursive links to a parent dir
|
||||
IoTestUtil.createSymLink(new File(root, "dir1").getPath(), new File(root, "dir1/dir1_link").getPath());
|
||||
IoTestUtil.createSymLink(new File(rootDir, "dir1").getPath(), new File(rootDir, "dir1/dir1_link").getPath());
|
||||
|
||||
// I) links should NOT be resolved when ../ stays inside the linked path
|
||||
// I.I) non-recursive links
|
||||
@@ -266,13 +268,25 @@ public class FileUtilHeavyTest {
|
||||
assertEquals(root + "/dir1/dir2", FileUtil.toCanonicalPath(root + "/dir1/dir2_link/dir3/../../../dir1/dir2", true));
|
||||
assertEquals(root + "/dir1/dir2", FileUtil.toCanonicalPath(root + "/dir1/../dir1/dir2_link/../dir2", true));
|
||||
|
||||
// II.I) recursive links
|
||||
assertEquals(root.getPath(), FileUtil.toCanonicalPath(root + "/dir1/dir1_link/../", true));
|
||||
assertEquals(root + "/dir1", FileUtil.toCanonicalPath(root + "/dir1/dir1_link/../dir1", true));
|
||||
assertEquals(root + "/dir1", FileUtil.toCanonicalPath(root + "/dir1/dir1_link/../../root/dir1", true));
|
||||
assertEquals(root + "/dir1", FileUtil.toCanonicalPath(root + "/dir1/dir1_link/dir3/../../dir1", true));
|
||||
assertEquals(root + "/dir1", FileUtil.toCanonicalPath(root + "/dir1/dir1_link/dir3/../../../root/dir1", true));
|
||||
assertEquals(root + "/dir1", FileUtil.toCanonicalPath(root + "/dir1/../dir1/dir1_link/../dir1", true));
|
||||
// II.I) recursive links
|
||||
// the rules seems to be different when ../ goes over recursive link:
|
||||
// * on Windows ../ goes to link's parent
|
||||
// * on Unix ../ goes to target's parent
|
||||
if (SystemInfo.isWindows) {
|
||||
assertEquals(root + "/dir1", FileUtil.toCanonicalPath(root + "/dir1/dir1_link/../", true));
|
||||
assertEquals(root + "/dir1/dir2", FileUtil.toCanonicalPath(root + "/dir1/dir1_link/../dir2", true));
|
||||
assertEquals(root + "/dir1/dir2", FileUtil.toCanonicalPath(root + "/dir1/dir1_link/../../dir1/dir2", true));
|
||||
assertEquals(root + "/dir1/dir2", FileUtil.toCanonicalPath(root + "/dir1/dir1_link/dir2/../../dir2", true));
|
||||
assertEquals(root + "/dir1/dir2", FileUtil.toCanonicalPath(root + "/dir1/dir1_link/dir2/../../../dir1/dir2", true));
|
||||
assertEquals(root + "/dir1/dir2", FileUtil.toCanonicalPath(root + "/dir1/../dir1/dir1_link/../dir2", true));
|
||||
} else {
|
||||
assertEquals(root, FileUtil.toCanonicalPath(root + "/dir1/dir1_link/../", true));
|
||||
assertEquals(root + "/dir1", FileUtil.toCanonicalPath(root + "/dir1/dir1_link/../dir1", true));
|
||||
assertEquals(root + "/dir1", FileUtil.toCanonicalPath(root + "/dir1/dir1_link/../../root/dir1", true));
|
||||
assertEquals(root + "/dir1", FileUtil.toCanonicalPath(root + "/dir1/dir1_link/dir2/../../dir1", true));
|
||||
assertEquals(root + "/dir1", FileUtil.toCanonicalPath(root + "/dir1/dir1_link/dir2/../../../root/dir1", true));
|
||||
assertEquals(root + "/dir1", FileUtil.toCanonicalPath(root + "/dir1/../dir1/dir1_link/../dir1", true));
|
||||
}
|
||||
|
||||
// some corner cases, behavior should be the same as the default FileUtil.toCanonicalPath
|
||||
assertEquals(FileUtil.toCanonicalPath("..", false), FileUtil.toCanonicalPath("..", true));
|
||||
|
||||
@@ -279,9 +279,9 @@ public class ChangeListManagerImpl extends ChangeListManagerEx implements Projec
|
||||
vcsManager.addVcsListener(myVcsListener);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
myConflictTracker.startTracking();
|
||||
myConflictTracker.startTracking();
|
||||
}
|
||||
}
|
||||
|
||||
private void broadcastStateAfterLoad() {
|
||||
|
||||
@@ -225,20 +225,20 @@ postfix.prefix.intention.name=Replace with ''{0}''
|
||||
|
||||
|
||||
#categories
|
||||
intention.category.annotations=Annotations
|
||||
intention.category.numbers=Numbers
|
||||
intention.category.boolean=Boolean
|
||||
intention.category.conditional.operator=Conditional Operator
|
||||
intention.category.shift.operation=Shift Operation
|
||||
intention.category.junit=JUnit
|
||||
intention.category.declaration=Declaration
|
||||
intention.category.imports=Imports
|
||||
intention.category.comments=Comments
|
||||
intention.category.control.flow=Control Flow
|
||||
intention.category.strings=Strings
|
||||
intention.category.modifiers=Modifiers
|
||||
intention.category.try.statements=Try Statements
|
||||
intention.category.other=Other
|
||||
intention.category.annotations=Java/Annotations
|
||||
intention.category.numbers=Java/Numbers
|
||||
intention.category.boolean=Java/Boolean
|
||||
intention.category.conditional.operator=Java/Conditional Operator
|
||||
intention.category.shift.operation=Java/Shift Operation
|
||||
intention.category.junit=Java/JUnit
|
||||
intention.category.declaration=Java/Declaration
|
||||
intention.category.imports=Java/Imports
|
||||
intention.category.comments=Java/Comments
|
||||
intention.category.control.flow=Java/Control Flow
|
||||
intention.category.strings=Java/Strings
|
||||
intention.category.modifiers=Java/Modifiers
|
||||
intention.category.try.statements=Java/Try Statements
|
||||
intention.category.other=Java/Other
|
||||
|
||||
#warnings
|
||||
0.is.declared.in.1.but.when.public.should.be.declared.in.a.file.named.2={0} is declared in {1} but when public should be declared in a file named {2}
|
||||
|
||||
@@ -251,21 +251,7 @@ public class JavaCoverageViewExtension extends CoverageViewExtension {
|
||||
}
|
||||
});
|
||||
for (final PsiFile file : childFiles) {
|
||||
if (file instanceof PsiJavaFile) {
|
||||
PsiClass[] classes = ApplicationManager.getApplication().runReadAction(new Computable<PsiClass[]>() {
|
||||
public PsiClass[] compute() {
|
||||
return file.isValid() ? ((PsiJavaFile) file).getClasses() : PsiClass.EMPTY_ARRAY;
|
||||
}
|
||||
});
|
||||
if (classes.length > 0) {
|
||||
PsiClass aClass = classes[0];
|
||||
if (!(node instanceof CoverageListRootNode) && getClassCoverageInfo(aClass) == null) continue;
|
||||
children.add(new CoverageListNode(myProject, aClass, mySuitesBundle, myStateBean));
|
||||
}
|
||||
}
|
||||
else if (file instanceof PsiClassOwner) {
|
||||
children.add(new CoverageListNode(myProject, file, mySuitesBundle, myStateBean));
|
||||
}
|
||||
collectFileChildren(file, node, children);
|
||||
}
|
||||
}
|
||||
else if (!myStateBean.myFlattenPackages) {
|
||||
@@ -287,6 +273,20 @@ public class JavaCoverageViewExtension extends CoverageViewExtension {
|
||||
return children;
|
||||
}
|
||||
|
||||
protected void collectFileChildren(final PsiFile file, AbstractTreeNode node, List<AbstractTreeNode> children) {
|
||||
if (file instanceof PsiClassOwner) {
|
||||
PsiClass[] classes = ApplicationManager.getApplication().runReadAction(new Computable<PsiClass[]>() {
|
||||
public PsiClass[] compute() {
|
||||
return file.isValid() ? ((PsiClassOwner) file).getClasses() : PsiClass.EMPTY_ARRAY;
|
||||
}
|
||||
});
|
||||
for (PsiClass aClass : classes) {
|
||||
if (!(node instanceof CoverageListRootNode) && getClassCoverageInfo(aClass) == null) continue;
|
||||
children.add(new CoverageListNode(myProject, aClass, mySuitesBundle, myStateBean));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private PackageAnnotator.ClassCoverageInfo getClassCoverageInfo(final PsiClass aClass) {
|
||||
return myAnnotator.getClassCoverageInfo(ApplicationManager.getApplication().runReadAction(new NullableComputable<String>() {
|
||||
|
||||
@@ -142,7 +142,7 @@
|
||||
<stacktrace.fold substring="at com.intellij.openapi.application.impl.ApplicationImpl.runWriteAction("/>
|
||||
<stacktrace.fold substring="at com.intellij.openapi.application.impl.ApplicationImpl.runReadAction("/>
|
||||
<stacktrace.fold substring="at com.intellij.openapi.application.RunResult.run("/>
|
||||
<stacktrace.fold substring="at com.intellij.openapi.command.impl.CommandProcessorImpl.executeCommand("/>
|
||||
<stacktrace.fold substring="at com.intellij.openapi.command.impl.CoreCommandProcessor.executeCommand("/>
|
||||
|
||||
<codeInsight.lineMarkerProvider language="JAVA"
|
||||
implementationClass="org.jetbrains.idea.devkit.navigation.DescriptionTypeRelatedItemLineMarkerProvider"/>
|
||||
|
||||
+1
-1
@@ -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.
|
||||
|
||||
+1
-1
@@ -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.
|
||||
|
||||
+1
-1
@@ -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.
|
||||
|
||||
+1
-1
@@ -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.
|
||||
|
||||
+1
-1
@@ -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.
|
||||
|
||||
+1
-1
@@ -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.
|
||||
|
||||
+1
-1
@@ -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.
|
||||
|
||||
@@ -63,7 +63,7 @@
|
||||
|
||||
<intentionAction>
|
||||
<className>com.intellij.codeInspection.capitalization.AnnotateCapitalizationIntention</className>
|
||||
<category>I18N</category>
|
||||
<category>Java/I18N</category>
|
||||
</intentionAction>
|
||||
|
||||
</extensions>
|
||||
|
||||
@@ -266,6 +266,11 @@ private layoutFull(Map args, String target, Set usedJars) {
|
||||
fileset(file: it)
|
||||
}
|
||||
|
||||
fileset(dir: "$ch/build/kotlinc/lib") {
|
||||
include(name: "kotlin-runtime.jar")
|
||||
include(name: "kotlin-reflect.jar")
|
||||
}
|
||||
|
||||
dir("libpty") {
|
||||
fileset(dir: "$ch/lib/libpty") {
|
||||
exclude(name: "*.txt")
|
||||
|
||||
@@ -303,6 +303,11 @@ private layoutFull(Map args, String target, Set usedJars) {
|
||||
fileset(file: it)
|
||||
}
|
||||
|
||||
fileset(dir: "$ch/build/kotlinc/lib") {
|
||||
include(name: "kotlin-runtime.jar")
|
||||
include(name: "kotlin-reflect.jar")
|
||||
}
|
||||
|
||||
dir("libpty") {
|
||||
fileset(dir: "$ch/lib/libpty") {
|
||||
exclude(name: "*.txt")
|
||||
|
||||
@@ -4,7 +4,7 @@ import pstats
|
||||
from prof_util import statsToResponse
|
||||
|
||||
from _prof_imports import TSerialization
|
||||
from _prof_imports import TJSONProtocol
|
||||
from _prof_imports import TBinaryProtocol
|
||||
from _prof_imports import ProfilerResponse
|
||||
from _prof_imports import IS_PY3K
|
||||
|
||||
@@ -19,13 +19,20 @@ if __name__ == '__main__':
|
||||
|
||||
statsToResponse(stats.stats, m)
|
||||
|
||||
data = TSerialization.serialize(m, TJSONProtocol.TJSONProtocolFactory())
|
||||
data = TSerialization.serialize(m, TBinaryProtocol.TBinaryProtocolFactory())
|
||||
|
||||
# setup stdout to write binary data to it
|
||||
if IS_PY3K:
|
||||
data = data.decode("utf-8")
|
||||
out = sys.stdout.buffer
|
||||
elif sys.platform == 'win32':
|
||||
import os, msvcrt
|
||||
msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY)
|
||||
out = sys.stdout
|
||||
else:
|
||||
out = sys.stdout
|
||||
|
||||
sys.stdout.write(data)
|
||||
sys.stdout.flush()
|
||||
out.write(data)
|
||||
out.flush()
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import traceback
|
||||
|
||||
from _prof_imports import TSerialization
|
||||
from _prof_imports import TJSONProtocol
|
||||
from _prof_imports import TBinaryProtocol
|
||||
from _prof_imports import ProfilerRequest
|
||||
from _prof_imports import IS_PY3K
|
||||
|
||||
@@ -15,7 +15,7 @@ def send_message(sock, message):
|
||||
to a socket, prepended by its length packed in 4
|
||||
bytes (big endian).
|
||||
"""
|
||||
s = TSerialization.serialize(message, TJSONProtocol.TJSONProtocolFactory())
|
||||
s = TSerialization.serialize(message, TBinaryProtocol.TBinaryProtocolFactory())
|
||||
packed_len = struct.pack('>L', len(s))
|
||||
sock.sendall(packed_len + s)
|
||||
|
||||
@@ -29,7 +29,7 @@ def get_message(sock, msgtype):
|
||||
msg_buf = socket_read_n(sock, msg_len)
|
||||
|
||||
msg = msgtype()
|
||||
TSerialization.deserialize(msg, msg_buf, TJSONProtocol.TJSONProtocolFactory())
|
||||
TSerialization.deserialize(msg, msg_buf, TBinaryProtocol.TBinaryProtocolFactory())
|
||||
|
||||
return msg
|
||||
|
||||
|
||||
@@ -15,8 +15,7 @@ The Python plug-in provides smart editing for Python scripts. The feature set of
|
||||
<a href="https://youtrack.jetbrains.com/issues/PY">Issue tracker</a><br>
|
||||
]]></description>
|
||||
|
||||
<!-- <PyCharm version> <Build number> -->
|
||||
<version>@@PYCHARM_VERSION@@ @@BUILD_NUMBER@@</version>
|
||||
<version>@@PYCHARM_VERSION@@</version>
|
||||
<depends>com.intellij.modules.java</depends>
|
||||
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@ import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.stubs.StubElement;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import com.intellij.psi.tree.TokenSet;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.QualifiedName;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
@@ -58,7 +59,6 @@ public class PyPsiUtils {
|
||||
|
||||
/**
|
||||
* Finds the closest comma after the element skipping any whitespaces in-between.
|
||||
* @param element
|
||||
*/
|
||||
@Nullable
|
||||
public static PsiElement getPrevComma(@NotNull PsiElement element) {
|
||||
@@ -66,13 +66,36 @@ public class PyPsiUtils {
|
||||
return prevNode != null && prevNode.getNode().getElementType() == PyTokenTypes.COMMA ? prevNode : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds first non-whitespace sibling before given PSI element.
|
||||
*/
|
||||
@Nullable
|
||||
public static PsiElement getPrevNonWhitespaceSibling(@NotNull PsiElement element) {
|
||||
public static PsiElement getPrevNonWhitespaceSibling(@Nullable PsiElement element) {
|
||||
return PsiTreeUtil.skipSiblingsBackward(element, PsiWhiteSpace.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the closest comma before the element skipping any whitespaces in-between.
|
||||
* Finds first non-whitespace sibling before given AST node.
|
||||
*/
|
||||
@Nullable
|
||||
public static ASTNode getPrevNonWhitespaceSibling(@NotNull ASTNode node) {
|
||||
return skipSiblingsBackward(node, TokenSet.create(TokenType.WHITE_SPACE));
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds first sibling that is neither comment, nor whitespace before given element.
|
||||
* @param strict prohibit returning element itself
|
||||
*/
|
||||
@Nullable
|
||||
public static PsiElement getPrevNonCommentSibling(@Nullable PsiElement start, boolean strict) {
|
||||
if (!strict && !(start instanceof PsiWhiteSpace || start instanceof PsiComment)) {
|
||||
return start;
|
||||
}
|
||||
return PsiTreeUtil.skipSiblingsBackward(start, PsiWhiteSpace.class, PsiComment.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the closest comma after the element skipping any whitespaces in-between.
|
||||
*/
|
||||
@Nullable
|
||||
public static PsiElement getNextComma(@NotNull PsiElement element) {
|
||||
@@ -80,11 +103,58 @@ public class PyPsiUtils {
|
||||
return nextNode != null && nextNode.getNode().getElementType() == PyTokenTypes.COMMA ? nextNode : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds first non-whitespace sibling after given PSI element.
|
||||
*/
|
||||
@Nullable
|
||||
public static PsiElement getNextNonWhitespaceSibling(@NotNull PsiElement element) {
|
||||
public static PsiElement getNextNonWhitespaceSibling(@Nullable PsiElement element) {
|
||||
return PsiTreeUtil.skipSiblingsForward(element, PsiWhiteSpace.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds first non-whitespace sibling after given AST node.
|
||||
*/
|
||||
@Nullable
|
||||
public static ASTNode getNextNonWhitespaceSibling(@NotNull ASTNode after) {
|
||||
return skipSiblingsForward(after, TokenSet.create(TokenType.WHITE_SPACE));
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds first sibling that is neither comment, nor whitespace after given element.
|
||||
* @param strict prohibit returning element itself
|
||||
*/
|
||||
@Nullable
|
||||
public static PsiElement getNextNonCommentSibling(@Nullable PsiElement start, boolean strict) {
|
||||
if (!strict && !(start instanceof PsiWhiteSpace || start instanceof PsiComment)) {
|
||||
return start;
|
||||
}
|
||||
return PsiTreeUtil.skipSiblingsForward(start, PsiWhiteSpace.class, PsiComment.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds first token after given element that doesn't consist solely of spaces and is not empty (e.g. error marker).
|
||||
* @param ignoreComments ignore commentaries as well
|
||||
*/
|
||||
@Nullable
|
||||
public static PsiElement getNextSignificantLeaf(@Nullable PsiElement element, boolean ignoreComments) {
|
||||
while (element != null && StringUtil.isEmptyOrSpaces(element.getText()) || ignoreComments && element instanceof PsiComment) {
|
||||
element = PsiTreeUtil.nextLeaf(element);
|
||||
}
|
||||
return element;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds first token before given element that doesn't consist solely of spaces and is not empty (e.g. error marker).
|
||||
* @param ignoreComments ignore commentaries as well
|
||||
*/
|
||||
@Nullable
|
||||
public static PsiElement getPrevSignificantLeaf(@Nullable PsiElement element, boolean ignoreComments) {
|
||||
while (element != null && StringUtil.isEmptyOrSpaces(element.getText()) || ignoreComments && element instanceof PsiComment) {
|
||||
element = PsiTreeUtil.prevLeaf(element);
|
||||
}
|
||||
return element;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the closest comma looking for the next comma first and then for the preceding one.
|
||||
*/
|
||||
@@ -94,6 +164,70 @@ public class PyPsiUtils {
|
||||
return nextComma != null ? nextComma : getPrevComma(element);
|
||||
}
|
||||
|
||||
/**
|
||||
* Works similarly to {@link PsiTreeUtil#skipSiblingsForward(PsiElement, Class[])}, but for AST nodes.
|
||||
*/
|
||||
@Nullable
|
||||
public static ASTNode skipSiblingsForward(@Nullable ASTNode node, @NotNull TokenSet types) {
|
||||
if (node == null) {
|
||||
return null;
|
||||
}
|
||||
for (ASTNode next = node.getTreeNext(); next != null; next = next.getTreeNext()) {
|
||||
if (!types.contains(next.getElementType())) {
|
||||
return next;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Works similarly to {@link PsiTreeUtil#skipSiblingsBackward(PsiElement, Class[])}, but for AST nodes.
|
||||
*/
|
||||
@Nullable
|
||||
public static ASTNode skipSiblingsBackward(@Nullable ASTNode node, @NotNull TokenSet types) {
|
||||
if (node == null) {
|
||||
return null;
|
||||
}
|
||||
for (ASTNode prev = node.getTreePrev(); prev != null; prev = prev.getTreePrev()) {
|
||||
if (!types.contains(prev.getElementType())) {
|
||||
return prev;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns first child psi element with specified element type or {@code null} if no such element exists.
|
||||
* Semantically it's the same as {@code getChildByFilter(element, TokenSet.create(type), 0)}.
|
||||
*
|
||||
* @param element tree parent node
|
||||
* @param type element type expected
|
||||
* @return child element described
|
||||
*/
|
||||
@Nullable
|
||||
public static PsiElement getFirstChildOfType(@NotNull final PsiElement element, @NotNull PyElementType type) {
|
||||
final ASTNode child = element.getNode().findChildByType(type);
|
||||
return child != null ? child.getPsi() : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns child element in the psi tree
|
||||
*
|
||||
* @param filter Types of expected child
|
||||
* @param number number
|
||||
* @param element tree parent node
|
||||
* @return PsiElement - child psiElement
|
||||
*/
|
||||
@Nullable
|
||||
public static PsiElement getChildByFilter(@NotNull PsiElement element, @NotNull TokenSet filter, int number) {
|
||||
final ASTNode node = element.getNode();
|
||||
if (node != null) {
|
||||
final ASTNode[] children = node.getChildren(filter);
|
||||
return (0 <= number && number < children.length) ? children[number].getPsi() : null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void addBeforeInParent(@NotNull final PsiElement anchor, @NotNull final PsiElement... newElements) {
|
||||
final ASTNode anchorNode = anchor.getNode();
|
||||
LOG.assertTrue(anchorNode != null);
|
||||
@@ -326,22 +460,6 @@ public class PyPsiUtils {
|
||||
return result;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static PsiElement getSignificantToTheRight(PsiElement element, final boolean ignoreComments) {
|
||||
while (element != null && StringUtil.isEmptyOrSpaces(element.getText()) || ignoreComments && element instanceof PsiComment) {
|
||||
element = PsiTreeUtil.nextLeaf(element);
|
||||
}
|
||||
return element;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static PsiElement getSignificantToTheLeft(PsiElement element, final boolean ignoreComments) {
|
||||
while (element != null && StringUtil.isEmptyOrSpaces(element.getText()) || ignoreComments && element instanceof PsiComment) {
|
||||
element = PsiTreeUtil.prevLeaf(element);
|
||||
}
|
||||
return element;
|
||||
}
|
||||
|
||||
public static int findArgumentIndex(PyCallExpression call, PsiElement argument) {
|
||||
final PyExpression[] args = call.getArguments();
|
||||
for (int i = 0; i < args.length; i++) {
|
||||
|
||||
@@ -31,6 +31,7 @@ import com.jetbrains.python.PyTokenTypes;
|
||||
import com.jetbrains.python.PythonFileType;
|
||||
import com.jetbrains.python.psi.PyFunction;
|
||||
import com.jetbrains.python.psi.PyUtil;
|
||||
import com.jetbrains.python.psi.impl.PyPsiUtils;
|
||||
|
||||
/**
|
||||
* Adds appropriate first parameter to a freshly-typed method declaration.
|
||||
@@ -55,7 +56,7 @@ public class PyMethodNameTypedHandler extends TypedHandlerDelegate {
|
||||
|
||||
final ASTNode token_node = token.getNode();
|
||||
if (token_node != null && token_node.getElementType() == PyTokenTypes.IDENTIFIER) {
|
||||
PsiElement maybe_def = PyUtil.getFirstNonCommentBefore(token.getPrevSibling());
|
||||
PsiElement maybe_def = PyPsiUtils.getPrevNonCommentSibling(token.getPrevSibling(), false);
|
||||
if (maybe_def != null) {
|
||||
ASTNode def_node = maybe_def.getNode();
|
||||
if (def_node != null && def_node.getElementType() == PyTokenTypes.DEF_KEYWORD) {
|
||||
|
||||
+3
-3
@@ -24,7 +24,7 @@ import com.jetbrains.python.codeInsight.editorActions.smartEnter.PySmartEnterPro
|
||||
import com.jetbrains.python.psi.PyArgumentList;
|
||||
import com.jetbrains.python.psi.PyClass;
|
||||
import com.jetbrains.python.psi.PyDecorator;
|
||||
import com.jetbrains.python.psi.PyUtil;
|
||||
import com.jetbrains.python.psi.impl.PyPsiUtils;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
@@ -37,9 +37,9 @@ public class PyArgumentListFixer extends PyFixer<PyArgumentList> {
|
||||
|
||||
@Override
|
||||
public void doApply(@NotNull Editor editor, @NotNull PySmartEnterProcessor processor, @NotNull PyArgumentList arguments) throws IncorrectOperationException {
|
||||
final PsiElement rBrace = PyUtil.getChildByFilter(arguments, PyTokenTypes.CLOSE_BRACES, 0);
|
||||
final PsiElement rBrace = PyPsiUtils.getChildByFilter(arguments, PyTokenTypes.CLOSE_BRACES, 0);
|
||||
if (arguments.getParent() instanceof PyClass || arguments.getParent() instanceof PyDecorator) {
|
||||
final PsiElement lBrace = PyUtil.getChildByFilter(arguments, PyTokenTypes.OPEN_BRACES, 0);
|
||||
final PsiElement lBrace = PyPsiUtils.getChildByFilter(arguments, PyTokenTypes.OPEN_BRACES, 0);
|
||||
if (lBrace != null && rBrace == null) {
|
||||
final Document document = editor.getDocument();
|
||||
document.insertString(arguments.getTextRange().getEndOffset(), ")");
|
||||
|
||||
+2
-2
@@ -23,7 +23,7 @@ import com.jetbrains.python.PyTokenTypes;
|
||||
import com.jetbrains.python.codeInsight.editorActions.smartEnter.PySmartEnterProcessor;
|
||||
import com.jetbrains.python.psi.PyArgumentList;
|
||||
import com.jetbrains.python.psi.PyClass;
|
||||
import com.jetbrains.python.psi.PyUtil;
|
||||
import com.jetbrains.python.psi.impl.PyPsiUtils;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import static com.jetbrains.python.psi.PyUtil.sure;
|
||||
@@ -40,7 +40,7 @@ public class PyClassFixer extends PyFixer<PyClass> {
|
||||
}
|
||||
|
||||
public void doApply(@NotNull Editor editor, @NotNull PySmartEnterProcessor processor, @NotNull PyClass pyClass) throws IncorrectOperationException {
|
||||
final PsiElement colon = PyUtil.getFirstChildOfType(pyClass, PyTokenTypes.COLON);
|
||||
final PsiElement colon = PyPsiUtils.getFirstChildOfType(pyClass, PyTokenTypes.COLON);
|
||||
if (colon == null) {
|
||||
final PyArgumentList argList = PsiTreeUtil.getChildOfType(pyClass, PyArgumentList.class);
|
||||
final int colonOffset = sure(argList).getTextRange().getEndOffset();
|
||||
|
||||
+5
-5
@@ -24,7 +24,7 @@ import com.jetbrains.python.PyTokenTypes;
|
||||
import com.jetbrains.python.codeInsight.editorActions.smartEnter.PySmartEnterProcessor;
|
||||
import com.jetbrains.python.psi.PyConditionalStatementPart;
|
||||
import com.jetbrains.python.psi.PyExpression;
|
||||
import com.jetbrains.python.psi.PyUtil;
|
||||
import com.jetbrains.python.psi.impl.PyPsiUtils;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import static com.jetbrains.python.psi.PyUtil.sure;
|
||||
@@ -45,18 +45,18 @@ public class PyConditionalStatementPartFixer extends PyFixer<PyConditionalStatem
|
||||
throws IncorrectOperationException {
|
||||
final PyExpression condition = statementPart.getCondition();
|
||||
final Document document = editor.getDocument();
|
||||
final PsiElement colon = PyUtil.getFirstChildOfType(statementPart, PyTokenTypes.COLON);
|
||||
final PsiElement colon = PyPsiUtils.getFirstChildOfType(statementPart, PyTokenTypes.COLON);
|
||||
if (colon == null) {
|
||||
if (condition != null) {
|
||||
final PsiElement firstNonComment = PyUtil.getFirstNonCommentAfter(condition.getNextSibling());
|
||||
final PsiElement firstNonComment = PyPsiUtils.getNextNonCommentSibling(condition.getNextSibling(), false);
|
||||
if (firstNonComment != null && !":".equals(firstNonComment.getNode().getText())) {
|
||||
document.insertString(firstNonComment.getTextRange().getEndOffset(), ":");
|
||||
}
|
||||
}
|
||||
else {
|
||||
final TokenSet keywords = TokenSet.create(PyTokenTypes.IF_KEYWORD, PyTokenTypes.ELIF_KEYWORD, PyTokenTypes.WHILE_KEYWORD);
|
||||
final PsiElement keywordToken = PyUtil.getChildByFilter(statementPart,
|
||||
keywords, 0);
|
||||
final PsiElement keywordToken = PyPsiUtils.getChildByFilter(statementPart,
|
||||
keywords, 0);
|
||||
final int offset = sure(keywordToken).getTextRange().getEndOffset();
|
||||
document.insertString(offset, " :");
|
||||
processor.registerUnresolvedError(offset + 1);
|
||||
|
||||
+3
-3
@@ -22,7 +22,7 @@ import com.jetbrains.python.PyTokenTypes;
|
||||
import com.jetbrains.python.codeInsight.editorActions.smartEnter.PySmartEnterProcessor;
|
||||
import com.jetbrains.python.psi.PyExceptPart;
|
||||
import com.jetbrains.python.psi.PyExpression;
|
||||
import com.jetbrains.python.psi.PyUtil;
|
||||
import com.jetbrains.python.psi.impl.PyPsiUtils;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import static com.jetbrains.python.psi.PyUtil.sure;
|
||||
@@ -40,9 +40,9 @@ public class PyExceptFixer extends PyFixer<PyExceptPart> {
|
||||
|
||||
@Override
|
||||
public void doApply(@NotNull Editor editor, @NotNull PySmartEnterProcessor processor, @NotNull PyExceptPart exceptPart) throws IncorrectOperationException {
|
||||
final PsiElement colon = PyUtil.getFirstChildOfType(exceptPart, PyTokenTypes.COLON);
|
||||
final PsiElement colon = PyPsiUtils.getFirstChildOfType(exceptPart, PyTokenTypes.COLON);
|
||||
if (colon == null) {
|
||||
final PsiElement exceptToken = PyUtil.getFirstChildOfType(exceptPart, PyTokenTypes.EXCEPT_KEYWORD);
|
||||
final PsiElement exceptToken = PyPsiUtils.getFirstChildOfType(exceptPart, PyTokenTypes.EXCEPT_KEYWORD);
|
||||
int offset = sure(exceptToken).getTextRange().getEndOffset();
|
||||
final PyExpression exceptClass = exceptPart.getExceptClass();
|
||||
if (exceptClass != null) {
|
||||
|
||||
+4
-4
@@ -21,7 +21,7 @@ import com.intellij.psi.PsiElement;
|
||||
import com.jetbrains.python.PyTokenTypes;
|
||||
import com.jetbrains.python.codeInsight.editorActions.smartEnter.PySmartEnterProcessor;
|
||||
import com.jetbrains.python.psi.PyForPart;
|
||||
import com.jetbrains.python.psi.PyUtil;
|
||||
import com.jetbrains.python.psi.impl.PyPsiUtils;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import static com.jetbrains.python.psi.PyUtil.sure;
|
||||
@@ -39,16 +39,16 @@ public class PyForPartFixer extends PyFixer<PyForPart> {
|
||||
|
||||
@Override
|
||||
public void doApply(@NotNull Editor editor, @NotNull PySmartEnterProcessor processor, @NotNull PyForPart forPart) {
|
||||
final PsiElement colon = PyUtil.getFirstChildOfType(forPart, PyTokenTypes.COLON);
|
||||
final PsiElement colon = PyPsiUtils.getFirstChildOfType(forPart, PyTokenTypes.COLON);
|
||||
final Document document = editor.getDocument();
|
||||
final PsiElement forToken = PyUtil.getFirstChildOfType(forPart, PyTokenTypes.FOR_KEYWORD);
|
||||
final PsiElement forToken = PyPsiUtils.getFirstChildOfType(forPart, PyTokenTypes.FOR_KEYWORD);
|
||||
if (colon == null) {
|
||||
String textToInsert = ":";
|
||||
PsiElement sourceOrTarget = forPart.getSource();
|
||||
PsiElement positionToInsert = sourceOrTarget;
|
||||
if (sourceOrTarget == null) {
|
||||
sourceOrTarget = forPart.getTarget();
|
||||
final PsiElement inToken = PyUtil.getFirstChildOfType(forPart, PyTokenTypes.IN_KEYWORD);
|
||||
final PsiElement inToken = PyPsiUtils.getFirstChildOfType(forPart, PyTokenTypes.IN_KEYWORD);
|
||||
if (inToken == null) {
|
||||
if (sourceOrTarget == null) {
|
||||
positionToInsert = sure(forToken);
|
||||
|
||||
+2
-2
@@ -22,7 +22,7 @@ import com.jetbrains.python.PyTokenTypes;
|
||||
import com.jetbrains.python.codeInsight.editorActions.smartEnter.PySmartEnterProcessor;
|
||||
import com.jetbrains.python.psi.PyFunction;
|
||||
import com.jetbrains.python.psi.PyParameterList;
|
||||
import com.jetbrains.python.psi.PyUtil;
|
||||
import com.jetbrains.python.psi.impl.PyPsiUtils;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
@@ -39,7 +39,7 @@ public class PyFunctionFixer extends PyFixer<PyFunction> {
|
||||
@Override
|
||||
public void doApply(@NotNull Editor editor, @NotNull PySmartEnterProcessor processor, @NotNull PyFunction function)
|
||||
throws IncorrectOperationException {
|
||||
final PsiElement colon = PyUtil.getFirstChildOfType(function, PyTokenTypes.COLON);
|
||||
final PsiElement colon = PyPsiUtils.getFirstChildOfType(function, PyTokenTypes.COLON);
|
||||
if (!isFakeFunction(function) && colon == null) {
|
||||
final PyParameterList parameterList = function.getParameterList();
|
||||
if (function.getNameNode() == null) {
|
||||
|
||||
+3
-2
@@ -20,6 +20,7 @@ import com.intellij.psi.PsiElement;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import com.jetbrains.python.codeInsight.editorActions.smartEnter.PySmartEnterProcessor;
|
||||
import com.jetbrains.python.psi.*;
|
||||
import com.jetbrains.python.psi.impl.PyPsiUtils;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
@@ -37,7 +38,7 @@ public class PyMissingBracesFixer extends PyFixer<PyElement> {
|
||||
public void doApply(@NotNull Editor editor, @NotNull PySmartEnterProcessor processor, @NotNull PyElement psiElement)
|
||||
throws IncorrectOperationException {
|
||||
if (psiElement instanceof PySetLiteralExpression || psiElement instanceof PyDictLiteralExpression) {
|
||||
final PsiElement lastChild = PyUtil.getFirstNonCommentBefore(psiElement.getLastChild());
|
||||
final PsiElement lastChild = PyPsiUtils.getPrevNonCommentSibling(psiElement.getLastChild(), false);
|
||||
if (lastChild != null && !"}".equals(lastChild.getText())) {
|
||||
editor.getDocument().insertString(lastChild.getTextRange().getEndOffset(), "}");
|
||||
}
|
||||
@@ -45,7 +46,7 @@ public class PyMissingBracesFixer extends PyFixer<PyElement> {
|
||||
else if (psiElement instanceof PyListLiteralExpression ||
|
||||
psiElement instanceof PySliceExpression ||
|
||||
psiElement instanceof PySubscriptionExpression) {
|
||||
final PsiElement lastChild = PyUtil.getFirstNonCommentBefore(psiElement.getLastChild());
|
||||
final PsiElement lastChild = PyPsiUtils.getPrevNonCommentSibling(psiElement.getLastChild(), false);
|
||||
if (lastChild != null && !"]".equals(lastChild.getText())) {
|
||||
editor.getDocument().insertString(lastChild.getTextRange().getEndOffset(), "]");
|
||||
}
|
||||
|
||||
+3
-3
@@ -23,7 +23,7 @@ import com.jetbrains.python.PyTokenTypes;
|
||||
import com.jetbrains.python.codeInsight.editorActions.smartEnter.PySmartEnterProcessor;
|
||||
import com.jetbrains.python.psi.PyFunction;
|
||||
import com.jetbrains.python.psi.PyParameterList;
|
||||
import com.jetbrains.python.psi.PyUtil;
|
||||
import com.jetbrains.python.psi.impl.PyPsiUtils;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import static com.jetbrains.python.psi.PyUtil.as;
|
||||
@@ -42,8 +42,8 @@ public class PyParameterListFixer extends PyFixer<PyParameterList> {
|
||||
@Override
|
||||
public void doApply(@NotNull Editor editor, @NotNull PySmartEnterProcessor processor, @NotNull PyParameterList parameters)
|
||||
throws IncorrectOperationException {
|
||||
final PsiElement lBrace = PyUtil.getChildByFilter(parameters, PyTokenTypes.OPEN_BRACES, 0);
|
||||
final PsiElement rBrace = PyUtil.getChildByFilter(parameters, PyTokenTypes.CLOSE_BRACES, 0);
|
||||
final PsiElement lBrace = PyPsiUtils.getChildByFilter(parameters, PyTokenTypes.OPEN_BRACES, 0);
|
||||
final PsiElement rBrace = PyPsiUtils.getChildByFilter(parameters, PyTokenTypes.CLOSE_BRACES, 0);
|
||||
final PyFunction pyFunction = as(parameters.getParent(), PyFunction.class);
|
||||
if (pyFunction != null && !PyFunctionFixer.isFakeFunction(pyFunction) && (lBrace == null || rBrace == null)) {
|
||||
final Document document = editor.getDocument();
|
||||
|
||||
+3
-2
@@ -22,6 +22,7 @@ import com.intellij.util.IncorrectOperationException;
|
||||
import com.jetbrains.python.PyTokenTypes;
|
||||
import com.jetbrains.python.codeInsight.editorActions.smartEnter.PySmartEnterProcessor;
|
||||
import com.jetbrains.python.psi.*;
|
||||
import com.jetbrains.python.psi.impl.PyPsiUtils;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import static com.jetbrains.python.psi.PyUtil.sure;
|
||||
@@ -41,10 +42,10 @@ public class PyUnconditionalStatementPartFixer extends PyFixer<PyElement> {
|
||||
public void doApply(@NotNull Editor editor, @NotNull PySmartEnterProcessor processor, @NotNull PyElement psiElement)
|
||||
throws IncorrectOperationException {
|
||||
if (PyUtil.instanceOf(psiElement, PyElsePart.class, PyTryPart.class, PyFinallyPart.class)) {
|
||||
final PsiElement colon = PyUtil.getFirstChildOfType(psiElement, PyTokenTypes.COLON);
|
||||
final PsiElement colon = PyPsiUtils.getFirstChildOfType(psiElement, PyTokenTypes.COLON);
|
||||
if (colon == null) {
|
||||
final TokenSet keywords = TokenSet.create(PyTokenTypes.ELSE_KEYWORD, PyTokenTypes.TRY_KEYWORD, PyTokenTypes.FINALLY_KEYWORD);
|
||||
final PsiElement keywordToken = PyUtil.getChildByFilter(psiElement, keywords, 0);
|
||||
final PsiElement keywordToken = PyPsiUtils.getChildByFilter(psiElement, keywords, 0);
|
||||
editor.getDocument().insertString(sure(keywordToken).getTextRange().getEndOffset(), ":");
|
||||
}
|
||||
}
|
||||
|
||||
+4
-4
@@ -23,9 +23,9 @@ import com.intellij.util.IncorrectOperationException;
|
||||
import com.jetbrains.python.PyTokenTypes;
|
||||
import com.jetbrains.python.codeInsight.editorActions.smartEnter.PySmartEnterProcessor;
|
||||
import com.jetbrains.python.psi.PyExpression;
|
||||
import com.jetbrains.python.psi.PyUtil;
|
||||
import com.jetbrains.python.psi.PyWithItem;
|
||||
import com.jetbrains.python.psi.PyWithStatement;
|
||||
import com.jetbrains.python.psi.impl.PyPsiUtils;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
@@ -38,8 +38,8 @@ public class PyWithFixer extends PyFixer<PyWithStatement> {
|
||||
|
||||
@Override
|
||||
public void doApply(@NotNull Editor editor, @NotNull PySmartEnterProcessor processor, @NotNull PyWithStatement withStatement) throws IncorrectOperationException {
|
||||
final PsiElement colonToken = PyUtil.getFirstChildOfType(withStatement, PyTokenTypes.COLON);
|
||||
final PsiElement withToken = PyUtil.getFirstChildOfType(withStatement, PyTokenTypes.WITH_KEYWORD);
|
||||
final PsiElement colonToken = PyPsiUtils.getFirstChildOfType(withStatement, PyTokenTypes.COLON);
|
||||
final PsiElement withToken = PyPsiUtils.getFirstChildOfType(withStatement, PyTokenTypes.WITH_KEYWORD);
|
||||
final Document document = editor.getDocument();
|
||||
if (colonToken == null && withToken != null) {
|
||||
int insertAt = withToken.getTextRange().getEndOffset();
|
||||
@@ -52,7 +52,7 @@ public class PyWithFixer extends PyFixer<PyWithStatement> {
|
||||
else {
|
||||
final PyExpression expression = lastItem.getExpression();
|
||||
insertAt = expression.getTextRange().getEndOffset();
|
||||
final PsiElement asToken = PyUtil.getFirstChildOfType(lastItem, PyTokenTypes.AS_KEYWORD);
|
||||
final PsiElement asToken = PyPsiUtils.getFirstChildOfType(lastItem, PyTokenTypes.AS_KEYWORD);
|
||||
if (asToken != null) {
|
||||
insertAt = asToken.getTextRange().getEndOffset();
|
||||
final PyExpression target = lastItem.getTarget();
|
||||
|
||||
@@ -26,6 +26,7 @@ import com.intellij.util.IncorrectOperationException;
|
||||
import com.jetbrains.python.PyBundle;
|
||||
import com.jetbrains.python.PyTokenTypes;
|
||||
import com.jetbrains.python.psi.*;
|
||||
import com.jetbrains.python.psi.impl.PyPsiUtils;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
@@ -54,11 +55,11 @@ public class PySplitIfIntention extends BaseIntentionAction {
|
||||
final IElementType elementType = elementAtOffset.getNode().getElementType();
|
||||
if (elementType == PyTokenTypes.COLON) {
|
||||
elementAtOffset = elementAtOffset.getPrevSibling();
|
||||
elementAtOffset = PyUtil.getFirstNonCommentBefore(elementAtOffset);
|
||||
elementAtOffset = PyPsiUtils.getPrevNonCommentSibling(elementAtOffset, false);
|
||||
}
|
||||
else if (elementType == PyTokenTypes.IF_KEYWORD) {
|
||||
elementAtOffset = elementAtOffset.getNextSibling();
|
||||
elementAtOffset = PyUtil.getFirstNonCommentAfter(elementAtOffset);
|
||||
elementAtOffset = PyPsiUtils.getNextNonCommentSibling(elementAtOffset, false);
|
||||
}
|
||||
|
||||
PsiElement element = PsiTreeUtil.getParentOfType(elementAtOffset, PyBinaryExpression.class, false);
|
||||
@@ -87,11 +88,11 @@ public class PySplitIfIntention extends BaseIntentionAction {
|
||||
final IElementType elementType = elementAtOffset.getNode().getElementType();
|
||||
if (elementType == PyTokenTypes.COLON) {
|
||||
elementAtOffset = elementAtOffset.getPrevSibling();
|
||||
elementAtOffset = PyUtil.getFirstNonCommentBefore(elementAtOffset);
|
||||
elementAtOffset = PyPsiUtils.getPrevNonCommentSibling(elementAtOffset, false);
|
||||
}
|
||||
else if (elementType == PyTokenTypes.IF_KEYWORD) {
|
||||
elementAtOffset = elementAtOffset.getNextSibling();
|
||||
elementAtOffset = PyUtil.getFirstNonCommentAfter(elementAtOffset);
|
||||
elementAtOffset = PyPsiUtils.getNextNonCommentSibling(elementAtOffset, false);
|
||||
}
|
||||
|
||||
PyBinaryExpression element = PsiTreeUtil.getParentOfType(elementAtOffset, PyBinaryExpression.class, false);
|
||||
|
||||
@@ -64,8 +64,8 @@ public class DocStringUtil {
|
||||
@Nullable
|
||||
public static PyStringLiteralExpression findDocStringExpression(@Nullable PyElement parent) {
|
||||
if (parent != null) {
|
||||
PsiElement seeker = PyUtil.getFirstNonCommentAfter(parent.getFirstChild());
|
||||
if (seeker instanceof PyExpressionStatement) seeker = PyUtil.getFirstNonCommentAfter(seeker.getFirstChild());
|
||||
PsiElement seeker = PyPsiUtils.getNextNonCommentSibling(parent.getFirstChild(), false);
|
||||
if (seeker instanceof PyExpressionStatement) seeker = PyPsiUtils.getNextNonCommentSibling(seeker.getFirstChild(), false);
|
||||
if (seeker instanceof PyStringLiteralExpression) return (PyStringLiteralExpression)seeker;
|
||||
}
|
||||
return null;
|
||||
|
||||
@@ -51,7 +51,6 @@ import com.intellij.psi.codeStyle.CodeStyleSettings;
|
||||
import com.intellij.psi.codeStyle.CodeStyleSettingsManager;
|
||||
import com.intellij.psi.codeStyle.CommonCodeStyleSettings.IndentOptions;
|
||||
import com.intellij.psi.stubs.StubElement;
|
||||
import com.intellij.psi.tree.TokenSet;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.QualifiedName;
|
||||
import com.intellij.ui.awt.RelativePoint;
|
||||
@@ -100,44 +99,6 @@ public class PyUtil {
|
||||
private PyUtil() {
|
||||
}
|
||||
|
||||
public static ASTNode getNextNonWhitespace(ASTNode after) {
|
||||
ASTNode node = after;
|
||||
do {
|
||||
node = node.getTreeNext();
|
||||
}
|
||||
while (isWhitespace(node));
|
||||
return node;
|
||||
}
|
||||
|
||||
public static ASTNode getPreviousNonWhitespace(ASTNode after) {
|
||||
ASTNode node = after;
|
||||
do {
|
||||
node = node.getTreePrev();
|
||||
}
|
||||
while (isWhitespace(node));
|
||||
return node;
|
||||
}
|
||||
|
||||
private static boolean isWhitespace(ASTNode node) {
|
||||
return node != null && node.getElementType().equals(TokenType.WHITE_SPACE);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static PsiElement getFirstNonCommentAfter(PsiElement start) {
|
||||
PsiElement seeker = start;
|
||||
while (seeker instanceof PsiWhiteSpace || seeker instanceof PsiComment) seeker = seeker.getNextSibling();
|
||||
return seeker;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static PsiElement getFirstNonCommentBefore(PsiElement start) {
|
||||
PsiElement seeker = start;
|
||||
while (seeker instanceof PsiWhiteSpace || seeker instanceof PsiComment) {
|
||||
seeker = seeker.getPrevSibling();
|
||||
}
|
||||
return seeker;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static <T extends PyElement> T[] getAllChildrenOfType(@NotNull PsiElement element, @NotNull Class<T> aClass) {
|
||||
List<T> result = new SmartList<T>();
|
||||
@@ -917,38 +878,6 @@ public class PyUtil {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns child element in the psi tree
|
||||
*
|
||||
* @param filter Types of expected child
|
||||
* @param number number
|
||||
* @param element tree parent node
|
||||
* @return PsiElement - child psiElement
|
||||
*/
|
||||
@Nullable
|
||||
public static PsiElement getChildByFilter(@NotNull final PsiElement element, final @NotNull TokenSet filter, final int number) {
|
||||
final ASTNode node = element.getNode();
|
||||
if (node != null) {
|
||||
final ASTNode[] children = node.getChildren(filter);
|
||||
return (0 <= number && number < children.length) ? children[number].getPsi() : null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns first child psi element with specified element type or {@code null} if no such element exists.
|
||||
* Semantically it's the same as {@code getChildByFilter(element, TokenSet.create(type), 0)}.
|
||||
*
|
||||
* @param element tree parent node
|
||||
* @param type element type expected
|
||||
* @return child element described
|
||||
*/
|
||||
@Nullable
|
||||
public static PsiElement getFirstChildOfType(@NotNull final PsiElement element, @NotNull PyElementType type) {
|
||||
final ASTNode child = element.getNode().findChildByType(type);
|
||||
return child != null ? child.getPsi() : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* If argument is a PsiDirectory, turn it into a PsiFile that points to __init__.py in that directory.
|
||||
* If there's no __init__.py there, null is returned, there's no point to resolve to a dir which is not a package.
|
||||
|
||||
@@ -157,7 +157,7 @@ public class PyArgumentListImpl extends PyElementImpl implements PyArgumentList
|
||||
}
|
||||
}
|
||||
else {
|
||||
ASTNode before = PyUtil.getNextNonWhitespace(pars[0]);
|
||||
ASTNode before = PyPsiUtils.getNextNonWhitespaceSibling(pars[0]);
|
||||
ASTNode anchorBefore;
|
||||
if (before != null && elementPrecedesElementsOfType(before, PythonDialectsTokenSetProvider.INSTANCE.getExpressionTokens())) {
|
||||
ASTNode comma = createComma();
|
||||
@@ -265,7 +265,7 @@ public class PyArgumentListImpl extends PyElementImpl implements PyArgumentList
|
||||
break;
|
||||
}
|
||||
else if (type == PyTokenTypes.COMMA) {
|
||||
ASTNode next = PyUtil.getNextNonWhitespace(node);
|
||||
ASTNode next = PyPsiUtils.getNextNonWhitespaceSibling(node);
|
||||
if (next == null) {
|
||||
addArgumentLastWithoutComma(argument);
|
||||
}
|
||||
|
||||
@@ -19,11 +19,10 @@ import com.intellij.lang.ASTNode;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.jetbrains.python.PyTokenTypes;
|
||||
import com.jetbrains.python.PythonDialectsTokenSetProvider;
|
||||
import com.jetbrains.python.psi.PyUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import com.jetbrains.python.psi.PyAugAssignmentStatement;
|
||||
import com.jetbrains.python.psi.PyElementVisitor;
|
||||
import com.jetbrains.python.psi.PyExpression;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
@@ -55,6 +54,6 @@ public class PyAugAssignmentStatementImpl extends PyElementImpl implements PyAug
|
||||
|
||||
@Nullable
|
||||
public PsiElement getOperation() {
|
||||
return PyUtil.getChildByFilter(this, PyTokenTypes.AUG_ASSIGN_OPERATIONS, 0);
|
||||
return PyPsiUtils.getChildByFilter(this, PyTokenTypes.AUG_ASSIGN_OPERATIONS, 0);
|
||||
}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user