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

This commit is contained in:
Kirill Kalishev
2011-08-03 22:00:44 +04:00
77 changed files with 1223 additions and 457 deletions
@@ -2107,7 +2107,18 @@ public class HighlightUtil {
if (highlightInfo != null) return highlightInfo;
PsiElement refParent = ref.getParent();
if (refParent instanceof PsiMethodCallExpression) {
PsiElement granny;
if (refParent instanceof PsiReferenceExpression && (granny = refParent.getParent()) instanceof PsiMethodCallExpression) {
PsiReferenceExpression referenceToMethod = ((PsiMethodCallExpression)granny).getMethodExpression();
PsiExpression qualifierExpression = referenceToMethod.getQualifierExpression();
if (qualifierExpression == ref) {
PsiElement qualifier = resolved;
if (qualifier != null && !(qualifier instanceof PsiClass) && !(qualifier instanceof PsiVariable)) {
return HighlightInfo.createHighlightInfo(HighlightInfoType.WRONG_REF, qualifierExpression, "Qualifier must be an expression");
}
}
}
else if (refParent instanceof PsiMethodCallExpression) {
return null; // methods checked elsewhere
}
if (resolved == null) {
@@ -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.codeInsight.daemon.impl.quickfix.LocateLibraryDialog">
<grid id="cbd77" binding="contentPane" layout-manager="GridLayoutManager" row-count="2" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="10" left="10" bottom="10" right="10"/>
<margin top="0" left="10" bottom="10" right="10"/>
<constraints>
<xy x="48" y="54" width="623" height="297"/>
</constraints>
@@ -57,25 +57,15 @@
</component>
</children>
</grid>
<grid id="4582d" layout-manager="GridLayoutManager" row-count="1" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="5" left="5" bottom="5" right="5"/>
<component id="a8ddb" class="javax.swing.JTextPane" binding="myDescription">
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="7" anchor="1" fill="1" indent="0" use-parent-layout="false"/>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="2" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
<border type="etched"/>
<children>
<component id="a8ddb" class="javax.swing.JTextPane" binding="myDescription">
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="2" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<editable value="false"/>
<text value=""/>
</properties>
</component>
</children>
</grid>
<properties>
<editable value="false"/>
<text value=""/>
</properties>
</component>
</children>
</grid>
<buttonGroups>
@@ -31,7 +31,7 @@ import org.jetbrains.annotations.NotNull;
public class SafeDeleteFix implements IntentionAction {
private final PsiElement myElement;
public SafeDeleteFix(PsiElement element) {
public SafeDeleteFix(@NotNull PsiElement element) {
myElement = element;
}
@@ -28,14 +28,11 @@ import com.intellij.openapi.options.colors.AttributesDescriptor;
import com.intellij.openapi.options.colors.ColorDescriptor;
import com.intellij.openapi.options.colors.ColorSettingsPage;
import com.intellij.pom.java.LanguageLevel;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class JavaColorSettingsPage implements ColorSettingsPage, InspectionColorSettingsPage {
@@ -125,15 +122,7 @@ public class JavaColorSettingsPage implements ColorSettingsPage, InspectionColor
@NotNull
public AttributesDescriptor[] getAttributeDescriptors() {
List<AttributesDescriptor> descriptors = new ArrayList<AttributesDescriptor>();
ContainerUtil.addAll(descriptors, ourDescriptors);
descriptors.add(
new AttributesDescriptor(OptionsBundle.message("options.java.color.descriptor.full.coverage"), CodeInsightColors.LINE_FULL_COVERAGE));
descriptors.add(new AttributesDescriptor(OptionsBundle.message("options.java.color.descriptor.partial.coverage"),
CodeInsightColors.LINE_PARTIAL_COVERAGE));
descriptors.add(
new AttributesDescriptor(OptionsBundle.message("options.java.color.descriptor.none.coverage"), CodeInsightColors.LINE_NONE_COVERAGE));
return descriptors.toArray(new AttributesDescriptor[descriptors.size()]);
return ourDescriptors;
}
@NotNull
@@ -117,7 +117,7 @@ public class PackageNode extends PackageDependenciesNode {
@Override
public boolean canSelectInLeftTree(final Map<PsiFile, Set<PsiFile>> deps) {
Set<PsiFile> files = deps.keySet();
String packageName = myPackage.getQualifiedName();
String packageName = myPackageQName;
for (PsiFile file : files) {
if (file instanceof PsiJavaFile && Comparing.equal(packageName, ((PsiJavaFile)file).getPackageName())) {
return true;
@@ -94,6 +94,10 @@ class DCC {
<error descr="Method call expected">DCC(1)</error>;
new DCC(1);
}
{
<error descr="Qualifier must be an expression">java</error>.toString();
}
}
class ThisExpression {
@@ -0,0 +1,47 @@
import java.lang.Comparable;
import java.lang.Integer;
import java.lang.Override;
import java.lang.Runnable;
public class ManyClasses {
public void foo() {
Runnable r = new Runnable() {
@Override
public void run() {
Comparable<Integer> c = new Comparable<Integer>() {
@Override
public int compareTo(Integer o) {
return 0;
}
};
}
};
class FooLocal {
Runnable r = new Runnable() {
@Override
public void run() {
}
};
}
}
public void bar() {
class FooLocal implements Runnable {
@Override
public void run() {
}
}
}
public class Child {
}
}
class Local {
public static class Sub {
}
}
@@ -312,14 +312,14 @@ class JavaAutoPopupTest extends CompletionAutoPopupTestCase {
}
""")
edt { myFixture.type 'A' }
joinAlarm() // completion started
joinAutopopup() // completion started
boolean tooQuick = false
edt {
tooQuick = lookup == null
myFixture.type 'IO'
}
joinAlarm() //I
joinAlarm() //O
joinAutopopup() //I
joinAutopopup() //O
joinCompletion()
assert lookup
assert 'ArrayIndexOutOfBoundsException' in myFixture.lookupElementStrings
@@ -490,11 +490,12 @@ public interface Test {
public void testCancellingDuringCalculation() {
myFixture.configureByText "a.java", """
class Aaaaaaa {}
public interface Test {
<caret>
}"""
edt { myFixture.type 'A' }
joinAlarm()
joinAutopopup()
def first = lookup
assert first
edt {
@@ -502,9 +503,9 @@ public interface Test {
lookup.hide()
myFixture.type 'a'
}
joinAlarm()
joinAlarm()
joinAlarm()
joinAutopopup()
joinAutopopup()
joinAutopopup()
assert lookup != first
}
@@ -518,25 +519,24 @@ public interface Test {
}
public void testDuringCompletionMustFinish() {
registerLongCompletionContributor()
edt { myFixture.addFileToProject 'directory/foo.txt', '' }
myFixture.configureByText "a.java", 'public interface Test { RuntiExce<caret>xxx }'
myFixture.completeBasic()
while (!lookup.items) {
Thread.sleep(10)
edt { lookup.refreshUi() }
}
edt { myFixture.type '\t' }
myFixture.checkResult 'public interface Test { RuntimeException<caret>x }'
}
private def registerLongCompletionContributor() {
def ep = Extensions.rootArea.getExtensionPoint("com.intellij.completion.contributor")
def bean = new CompletionContributorEP(language: 'JAVA', implementationClass: LongReplacementOffsetContributor.name)
ep.registerExtension(bean, LoadingOrder.LAST)
try {
edt { myFixture.addFileToProject 'directory/foo.txt', '' }
myFixture.configureByText "a.java", 'public interface Test { RuntiExce<caret>xxx }'
myFixture.completeBasic()
while (!lookup.items) {
Thread.sleep(10)
edt { lookup.refreshUi() }
}
edt { myFixture.type '\t' }
myFixture.checkResult 'public interface Test { RuntimeException<caret>x }'
}
finally {
ep.unregisterExtension(bean)
}
disposeOnTearDown({ ep.unregisterExtension(bean) } as Disposable)
}
public void testLeftRightMovements() {
@@ -562,7 +562,7 @@ public interface Test {
assertEquals 'iterable', lookup.currentItem.lookupString
edt { myFixture.performEditorAction(IdeActions.ACTION_EDITOR_MOVE_CARET_LEFT) }
joinAlarm()
joinAutopopup()
joinCompletion()
assert lookup.items.size() > 3
@@ -594,7 +594,7 @@ public interface Test {
wca.execute()
assert 'x' == another.document.text
}
joinAlarm()
joinAutopopup()
joinCompletion()
LookupImpl l1 = LookupManager.getActiveLookup(another)
if (l1) {
@@ -676,6 +676,92 @@ class Foo {
assert myFixture.editor.document.text.contains('filinpstr()')
}
public void testNoAutopopupAfterSpace() {
myFixture.configureByText("a.java", """ class Foo { { int newa; <caret> } } """)
edt { myFixture.type('new ') }
joinAutopopup()
joinCompletion()
assert !lookup
}
public void testRestartAndTypingDuringCopyCommit() {
registerLongCompletionContributor()
myFixture.configureByText("a.java", """ class Foo { { int newa; <caret> } } """)
myFixture.type 'n'
joinAutopopup()
myFixture.type 'e'
joinCommit() // original commit
myFixture.type 'w'
joinAutopopup()
joinCompletion()
myFixture.type '\n'
myFixture.checkResult(" class Foo { { int newa; new <caret>} } ")
assert !lookup
}
private void joinSomething(int degree) {
if (degree == 0) return
joinAlarm()
if (degree == 1) return
joinCommit()
if (degree == 2) return
joinCommit()
if (degree == 3) return
edt {}
if (degree == 4) return
joinCompletion()
}
public void testEveryPossibleWayToTypeIf() {
def src = "class Foo { { int ifa; <caret> } }"
def result = "class Foo { { int ifa; if <caret> } }"
int actions = 5
for (a1 in 0..actions) {
for (a2 in 0..actions) {
myFixture.configureByText("$a1 $a2 .java", src)
myFixture.type 'i'
joinSomething(a1)
myFixture.type 'f'
joinSomething(a2)
myFixture.type ' '
joinAutopopup()
joinCompletion()
myFixture.checkResult(result)
assert !lookup
}
}
for (a1 in 0..actions) {
myFixture.configureByText("$a1 if .java", src)
edt { myFixture.type 'if' }
joinSomething(a1)
myFixture.type ' '
joinAutopopup()
joinCompletion()
myFixture.checkResult(result)
assert !lookup
}
for (a1 in 0..actions) {
myFixture.configureByText("$a1 if .java", src)
myFixture.type 'i'
joinSomething(a1)
edt { myFixture.type 'f ' }
joinAutopopup()
joinCompletion()
myFixture.checkResult(result)
assert !lookup
}
}
public void testNonFinishedParameterComma() {
myFixture.configureByText("a.java", """ class Foo { void foo(int aaa, int aaaaa) { foo(<caret>) } } """)
type 'a,'
@@ -0,0 +1,45 @@
/*
* 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.psi.util;
import com.intellij.JavaTestUtil;
import com.intellij.psi.PsiClass;
import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase;
/**
* @author yole
*/
public class ClassUtilTest extends LightCodeInsightFixtureTestCase {
public void testFindPsiClassByJvmName() {
myFixture.configureByFile("ManyClasses.java");
assertNotNull(ClassUtil.findPsiClassByJVMName(getPsiManager(), "ManyClasses"));
assertNotNull(ClassUtil.findPsiClassByJVMName(getPsiManager(), "ManyClasses$1"));
assertNotNull(ClassUtil.findPsiClassByJVMName(getPsiManager(), "ManyClasses$1$1"));
assertNotNull(ClassUtil.findPsiClassByJVMName(getPsiManager(), "ManyClasses$1FooLocal"));
assertNotNull(ClassUtil.findPsiClassByJVMName(getPsiManager(), "ManyClasses$1FooLocal$1"));
assertNotNull(ClassUtil.findPsiClassByJVMName(getPsiManager(), "ManyClasses$Child"));
assertNotNull(ClassUtil.findPsiClassByJVMName(getPsiManager(), "Local"));
assertNotNull(ClassUtil.findPsiClassByJVMName(getPsiManager(), "Local$Sub"));
final PsiClass fooLocal2 = ClassUtil.findPsiClassByJVMName(getPsiManager(), "ManyClasses$2FooLocal");
assertEquals("Runnable", fooLocal2.getImplementsListTypes() [0].getClassName());
}
@Override
protected String getBasePath() {
return JavaTestUtil.getRelativeJavaTestDataPath() + "/psi/classUtil/";
}
}
@@ -148,7 +148,7 @@ public class ClassUtil {
super.visitClass(aClass);
return;
}
if (aClass.getQualifiedName() == null && Comparing.strEqual(name, aClass.getName())) {
if (Comparing.strEqual(name, aClass.getName())) {
myCurrentIdx++;
if (myCurrentIdx == idx || idx == -1) {
result[0] = aClass;
@@ -16,18 +16,17 @@
package com.intellij.codeInsight.completion
import com.intellij.codeInsight.AutoPopupController
import com.intellij.codeInsight.CodeInsightSettings
import com.intellij.codeInsight.completion.impl.CompletionServiceImpl
import com.intellij.codeInsight.editorActions.CompletionAutoPopupHandler
import com.intellij.codeInsight.lookup.LookupManager
import com.intellij.codeInsight.lookup.impl.LookupImpl
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.editor.ex.DocumentEx
import com.intellij.psi.PsiDocumentManager
import com.intellij.testFramework.PlatformTestUtil
import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase
import com.intellij.util.concurrency.Semaphore
import com.intellij.util.ui.UIUtil
import java.util.concurrent.atomic.AtomicBoolean
import com.intellij.openapi.application.ApplicationManager
/**
* @author peter
@@ -58,17 +57,12 @@ abstract class CompletionAutoPopupTestCase extends LightCodeInsightFixtureTestCa
for (i in 0..<s.size()) {
final c = s.charAt(i)
myFixture.type(c)
joinAlarm() // for the autopopup handler's alarm, or the restartCompletion's invokeLater
joinAutopopup() // for the autopopup handler's alarm, or the restartCompletion's invokeLater
joinCompletion()
}
}
protected void joinCompletion() {
joinCommit() // file copy commit in background
def controller = AutoPopupController.getInstance(getProject())
controller.executePendingRequests();
for (i in 0.1000) {
if (i==999) {
printThreadDump()
@@ -85,7 +79,7 @@ abstract class CompletionAutoPopupTestCase extends LightCodeInsightFixtureTestCa
l = LookupManager.getInstance(project).activeLookup
}
if (!l || !l.calculating) {
joinAlarm() // for invokeLater in CompletionProgressIndicator.stop()
edt {} // for invokeLater in CompletionProgressIndicator.stop()
return
}
Thread.sleep(10)
@@ -94,21 +88,30 @@ abstract class CompletionAutoPopupTestCase extends LightCodeInsightFixtureTestCa
fail("Too long completion")
}
private def joinCommit() {
protected def joinCommit() {
final AtomicBoolean committed = new AtomicBoolean()
edt {
PsiDocumentManager.getInstance(project).cancelAndRunWhenAllCommitted("wait for all comm") {
ApplicationManager.application.invokeLater { committed.set(true) }
}
}
def start = System.currentTimeMillis()
while (!committed.get()) {
if (System.currentTimeMillis() - start >= 10000) {
fail('too long waiting for a document to be committed')
}
UIUtil.pump();
}
}
protected void joinAlarm() {
joinCommit()
edt { PlatformTestUtil.waitForAlarm(CodeInsightSettings.instance.AUTO_LOOKUP_DELAY)}
protected void joinAutopopup() {
joinAlarm();
joinCommit() // physical document commit
joinCommit() // file copy commit in background
}
protected def joinAlarm() {
AutoPopupController.getInstance(getProject()).executePendingRequests()
}
@Override protected void runTest() {
@@ -39,6 +39,10 @@ public class Main {
public static void main(final String[] args) {
if (installPatch()) {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
}
catch (Exception ignore) { }
JOptionPane.showMessageDialog(null, "The application cannot start right away since some critical files have been changed, " +
"please restart it manually.");
return;
@@ -418,7 +418,7 @@ public interface PsiElement extends UserDataHolder, Iconable {
* @param value the user data object to attach.
* @see #getCopyableUserData(com.intellij.openapi.util.Key)
*/
<T> void putCopyableUserData(Key<T> key, T value);
<T> void putCopyableUserData(Key<T> key, @Nullable T value);
/**
* Passes the declarations contained in this PSI element and its children
@@ -73,12 +73,7 @@ public class FilePatternPackageSet extends PatternBasedPackageSet {
}
private boolean fileMatcher(VirtualFile virtualFile, ProjectFileIndex fileIndex, VirtualFile projectBaseDir){
if (myModulePattern != null) {
final VirtualFile contentRoot = fileIndex.getContentRootForFile(virtualFile);
return myFilePattern.matcher(VfsUtil.getRelativePath(virtualFile, contentRoot, '/')).matches();
} else {
return myFilePattern.matcher(getRelativePath(virtualFile, fileIndex, true, projectBaseDir)).matches();
}
return myFilePattern.matcher(getRelativePath(virtualFile, fileIndex, true, projectBaseDir)).matches();
}
public static boolean matchesModule(final Pattern moduleGroupPattern,
@@ -191,6 +186,10 @@ public class FilePatternPackageSet extends PatternBasedPackageSet {
final ProjectFileIndex index,
final boolean useFQName,
VirtualFile projectBaseDir) {
final VirtualFile contentRootForFile = index.getContentRootForFile(virtualFile);
if (contentRootForFile != null) {
return VfsUtil.getRelativePath(virtualFile, contentRootForFile, '/');
}
final Module module = index.getModuleForFile(virtualFile);
if (module != null) {
if (projectBaseDir != null) {
@@ -201,10 +200,6 @@ public class FilePatternPackageSet extends PatternBasedPackageSet {
}
return virtualFile.getPath();
} else {
final VirtualFile contentRootForFile = index.getContentRootForFile(virtualFile);
if (contentRootForFile != null) {
return VfsUtil.getRelativePath(virtualFile, contentRootForFile, '/');
}
return getLibRelativePath(virtualFile, index);
}
}
@@ -57,7 +57,9 @@ public class SerializationManagerImpl extends SerializationManager implements Ap
public SerializationManagerImpl() {
myFile.getParentFile().mkdirs();
try {
myNameStorage = new PersistentStringEnumerator(myFile);
// we need to cache last id -> String mappings due to StringRefs and stubs indexing that initially creates stubs (doing enumerate on String)
// and then index them (valueOf), also similar string items are expected to be enumerated during stubs processing
myNameStorage = new PersistentStringEnumerator(myFile, true);
}
catch (IOException e) {
myNameStorageCrashed.set(true);
@@ -94,7 +96,7 @@ public class SerializationManagerImpl extends SerializationManager implements Ap
}
}
}
myNameStorage = new PersistentStringEnumerator(myFile);
myNameStorage = new PersistentStringEnumerator(myFile, true);
mySerializerToId.clear();
myIdToSerializer.clear();
@@ -16,6 +16,7 @@
package com.intellij.application.options;
import com.intellij.lang.Language;
import com.intellij.openapi.application.ApplicationBundle;
import com.intellij.openapi.options.Configurable;
import com.intellij.psi.codeStyle.CodeStyleSettings;
import com.intellij.psi.codeStyle.CodeStyleSettingsProvider;
@@ -35,20 +36,7 @@ public class CommonCodeStyleSettingsProvider extends CodeStyleSettingsProvider {
@Override
public String getConfigurableDisplayName() {
StringBuilder nameBuilder = new StringBuilder();
boolean isFirst = true;
for (Language language : LanguageCodeStyleSettingsProvider.getLanguagesWithSharedPreview()) {
if (isFirst) {
isFirst = false;
}
else {
nameBuilder.append('/');
}
nameBuilder.append(language.getDisplayName());
}
if (nameBuilder.length() > 0) nameBuilder.append(' ');
nameBuilder.append("Formatting");
return nameBuilder.toString();
return ApplicationBundle.message("title.other.languages");
}
@Override
@@ -58,7 +46,7 @@ public class CommonCodeStyleSettingsProvider extends CodeStyleSettingsProvider {
@Override
public DisplayPriority getPriority() {
return DisplayPriority.KEY_LANGUAGE_SETTINGS;
return DisplayPriority.OTHER_SETTINGS;
}
}
@@ -501,7 +501,7 @@ public class CodeCompletionHandlerBase implements CodeInsightActionHandler {
final Project project = hostFile.getProject();
if (autopopup) {
final CompletionPhase.AutoPopupAlarm phase = new CompletionPhase.AutoPopupAlarm(false, hostEditor);
final CompletionPhase.AutoPopupAlarm phase = new CompletionPhase.AutoPopupAlarm(true, hostEditor);
CompletionServiceImpl.setCompletionPhase(phase);
CompletionAutoPopupHandler.runLaterWithCommitted(project, hostDocument, new Runnable() {
@@ -340,7 +340,10 @@ public class CompletionProgressIndicator extends ProgressIndicatorBase implement
}
}
myLookup.show();
if (!myLookup.showLookup()) {
myLookup.hide();
return;
}
justShown = true;
}
myLookup.refreshUi();
@@ -599,7 +602,7 @@ public class CompletionProgressIndicator extends ProgressIndicatorBase implement
}
public void scheduleRestart() {
if (isAutopopupCompletion() && hideAutopopupIfMeaningless()) {
if (isAutopopupCompletion() && (!myLookup.isShown() || hideAutopopupIfMeaningless())) {
AutoPopupController.getInstance(getProject()).scheduleAutoPopup(myEditor, null);
return;
}
@@ -55,7 +55,9 @@ public class CompletionServiceImpl extends CompletionService{
public void projectClosing(Project project) {
CompletionProgressIndicator indicator = getCurrentCompletion();
if (indicator != null && indicator.getProject() == project) {
LookupManager.getInstance(project).hideActiveLookup();
LookupManager.getInstance(indicator.getProject()).hideActiveLookup();
setCompletionPhase(CompletionPhase.NoCompletion);
} else if (indicator == null) {
setCompletionPhase(CompletionPhase.NoCompletion);
}
}
@@ -351,7 +351,7 @@ public abstract class PassExecutorService implements Disposable {
catch (ProcessCanceledException e) {
log(myUpdateProgress, myPass, "Canceled ");
myUpdateProgress.cancel(e); //in case when some smartasses throw PCE just for fun
myUpdateProgress.cancel(e); //in case when some smart asses throw PCE just for fun
}
catch (RuntimeException e) {
myUpdateProgress.cancel(e);
@@ -71,7 +71,7 @@ public class CompletionAutoPopupHandler extends TypedHandlerDelegate {
}
if (!Character.isLetter(charTyped) && charTyped != '_') {
if (CompletionServiceImpl.isPhase(CompletionPhase.EmptyAutoPopup.class)) {
if (CompletionServiceImpl.isPhase(CompletionPhase.EmptyAutoPopup.class, CompletionPhase.AutoPopupAlarm.class)) {
CompletionServiceImpl.setCompletionPhase(CompletionPhase.NoCompletion);
}
return Result.CONTINUE;
@@ -800,14 +800,14 @@ public class LookupImpl extends LightweightHint implements LookupEx, Disposable
return myShown;
}
public void show(){
public boolean showLookup() {
ApplicationManager.getApplication().assertIsDispatchThread();
checkValid();
LOG.assertTrue(!myShown);
myShown = true;
myStampShown = System.currentTimeMillis();
if (ApplicationManager.getApplication().isUnitTestMode()) return;
if (ApplicationManager.getApplication().isUnitTestMode()) return true;
myAdComponent.showRandomText();
@@ -817,7 +817,9 @@ public class LookupImpl extends LightweightHint implements LookupEx, Disposable
Point p = calculatePosition(getComponent());
HintManagerImpl.getInstanceImpl().showEditorHint(this, myEditor, p, HintManager.HIDE_BY_ESCAPE | HintManager.UPDATE_BY_SCROLLING, 0, false,
HintManagerImpl.createHintHint(myEditor, p, this, HintManager.UNDER).setAwtTooltip(false));
LOG.assertTrue(isVisible(), "!visible, disposed=" + myDisposed);
if (!isVisible()) return false;
LOG.assertTrue(myList.isShowing(), "!showing, disposed=" + myDisposed);
final JLayeredPane layeredPane = getComponent().getRootPane().getLayeredPane();
@@ -834,6 +836,7 @@ public class LookupImpl extends LightweightHint implements LookupEx, Disposable
});
layoutStatusIcons();
return true;
}
public boolean mayBeNoticed() {
@@ -113,7 +113,7 @@ public class LookupManagerImpl extends LookupManager {
}
final LookupImpl lookup = createLookup(editor, items, prefix, arranger);
lookup.show();
lookup.showLookup();
return lookup;
}
@@ -74,7 +74,7 @@ public class ListTemplatesHandler implements CodeInsightActionHandler {
final LookupImpl lookup = (LookupImpl)LookupManager.getInstance(project).createLookup(editor, items, prefix, LookupArranger.DEFAULT);
lookup.addLookupListener(new MyLookupAdapter(project, editor, null));
lookup.show();
lookup.showLookup();
}
private static String computePrefix(TemplateImpl template, String argument) {
@@ -96,7 +96,7 @@ public class ListTemplatesHandler implements CodeInsightActionHandler {
}
lookup.addLookupListener(new MyLookupAdapter(project, editor, template2Argument));
lookup.show();
lookup.showLookup();
}
public boolean startInWriteAction() {
@@ -559,7 +559,7 @@ public class ScopeEditorPanel {
}
append(node.toString(), SimpleTextAttributes.REGULAR_ATTRIBUTES);
final String locationString = node.getComment();
if (locationString != null) {
if (!StringUtil.isEmpty(locationString)) {
append(" (" + locationString + ")", SimpleTextAttributes.GRAY_ATTRIBUTES);
}
}
@@ -1068,7 +1068,7 @@ public class PsiBuilderImpl extends UserDataHolderBase implements PsiBuilder {
curMarker = marker;
final CompositeElement childNode = createComposite(marker);
curNode.rawAddChildren(childNode);
curNode.rawAddChildrenWithoutNotifications(childNode);
curNode = childNode;
item = marker.myFirstChild != null ? marker.myFirstChild : marker.myDoneMarker;
@@ -1080,7 +1080,7 @@ public class PsiBuilderImpl extends UserDataHolderBase implements PsiBuilder {
}
else if (item instanceof ErrorItem) {
final CompositeElement errorElement = Factory.createErrorElement(((ErrorItem)item).myMessage);
curNode.rawAddChildren(errorElement);
curNode.rawAddChildrenWithoutNotifications(errorElement);
}
else if (item instanceof DoneMarker) {
curMarker = (StartMarker)((DoneMarker)item).myStart.myParent;
@@ -1101,7 +1101,7 @@ public class PsiBuilderImpl extends UserDataHolderBase implements PsiBuilder {
if (start < end || myLexTypes[curToken] instanceof ILeafElementType) { // Empty token. Most probably a parser directive like indent/dedent in Python
final IElementType type = myLexTypes[curToken];
final TreeElement leaf = createLeaf(type, start, end);
curNode.rawAddChildren(leaf);
curNode.rawAddChildrenWithoutNotifications(leaf);
}
curToken++;
}
@@ -1113,7 +1113,7 @@ public class PsiBuilderImpl extends UserDataHolderBase implements PsiBuilder {
final int start = myLexStarts[startMarker.myLexemeIndex];
final int end = myLexStarts[startMarker.myDoneMarker.myLexemeIndex];
final TreeElement leaf = createLeaf(startMarker.myType, start, end);
ast.rawAddChildren(leaf);
ast.rawAddChildrenWithoutNotifications(leaf);
return startMarker.myDoneMarker.myLexemeIndex;
}
@@ -86,6 +86,11 @@ public class GeneralColorsPage implements ColorSettingsPage, InspectionColorSett
new AttributesDescriptor(OptionsBundle.message("options.java.attribute.descriptor.unmatched.brace"), CodeInsightColors.UNMATCHED_BRACE_ATTRIBUTES),
new AttributesDescriptor(OptionsBundle.message("options.general.color.descriptor.todo.defaults"), CodeInsightColors.TODO_DEFAULT_ATTRIBUTES),
new AttributesDescriptor(OptionsBundle.message("options.java.color.descriptor.full.coverage"), CodeInsightColors.LINE_FULL_COVERAGE),
new AttributesDescriptor(OptionsBundle.message("options.java.color.descriptor.partial.coverage"),
CodeInsightColors.LINE_PARTIAL_COVERAGE),
new AttributesDescriptor(OptionsBundle.message("options.java.color.descriptor.none.coverage"), CodeInsightColors.LINE_NONE_COVERAGE)
};
private static final ColorDescriptor[] COLOR_DESCRIPTORS = {
@@ -17,7 +17,6 @@
package com.intellij.openapi.paths;
import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiReference;
import com.intellij.psi.impl.source.resolve.reference.impl.providers.FileReferenceSet;
@@ -47,9 +46,6 @@ public class StaticPathReferenceProvider extends PathReferenceProviderBase {
final @NotNull List<PsiReference> references,
final boolean soft) {
if (StringUtil.isEmpty(text)) {
return true;
}
FileReferenceSet set = new FileReferenceSet(text, psiElement, offset, null, true, myEndingSlashNotAllowed, mySuitableFileTypes) {
protected boolean isUrlEncoded() {
return true;
@@ -33,7 +33,6 @@ import com.intellij.openapi.vfs.impl.BulkVirtualFileListenerAdapter;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.messages.MessageBus;
import com.intellij.util.messages.MessageBusConnection;
import org.jetbrains.annotations.Nullable;
import java.io.IOException;
@@ -81,7 +80,7 @@ public class PushedFilePropertiesUpdater {
public void fileCreated(final VirtualFileEvent event) {
final VirtualFile file = event.getFile();
final FilePropertyPusher[] pushers = file.isDirectory() ? myPushers : myFilePushers;
pushRecursively(file, pushers);
pushRecursively(file, project, pushers);
}
@Override
@@ -91,7 +90,7 @@ public class PushedFilePropertiesUpdater {
for (FilePropertyPusher pusher : pushers) {
file.putUserData(pusher.getFileDataKey(), null);
}
pushRecursively(file, pushers);
pushRecursively(file, project, pushers);
}
}));
for (final FilePropertyPusher pusher : myPushers) {
@@ -101,7 +100,7 @@ public class PushedFilePropertiesUpdater {
}
public void pushRecursively(VirtualFile file, Project project) {
PushedFilePropertiesUpdater.this.pushRecursively(file, pusher);
PushedFilePropertiesUpdater.this.pushRecursively(file, project, pusher);
}
});
}
@@ -109,63 +108,66 @@ public class PushedFilePropertiesUpdater {
});
}
private void pushRecursively(final VirtualFile dir, final FilePropertyPusher... pushers) {
final Object[] values = new Object[pushers.length];
VirtualFile parent = dir.getParent();
for (int i = 0, pushersLength = pushers.length; i < pushersLength; i++) {
FilePropertyPusher pusher = pushers[i];
if (parent != null) {
values[i] = parent.getUserData(pusher.getFileDataKey());
}
if (values[i] == null) {
values[i] = pusher.getDefaultValue();
}
}
iterateContentUnderDirectory(dir, values, pushers);
}
public void pushAll(final FilePropertyPusher... pushers) {
for (Module module : ModuleManager.getInstance(myProject).getModules()) {
final Object[] values = new Object[pushers.length];
for (int i = 0; i < values.length; i++) {
values[i] = pushers[i].getImmediateValue(module);
if (values[i] == null) {
values[i] = pushers[i].getDefaultValue();
}
}
for (VirtualFile root : ModuleRootManager.getInstance(module).getContentRoots()) {
iterateContentUnderDirectory(root, values, pushers);
}
}
}
private void iterateContentUnderDirectory(VirtualFile root,
final Object[] values,
final FilePropertyPusher[] pushers) {
FileIndex index = ProjectRootManager.getInstance(myProject).getFileIndex();
index.iterateContentUnderDirectory(root, new ContentIterator() {
public void pushRecursively(final VirtualFile dir, final Project project, final FilePropertyPusher... pushers) {
if (pushers.length == 0) return;
ProjectRootManager.getInstance(project).getFileIndex().iterateContentUnderDirectory(dir, new ContentIterator() {
public boolean processFile(final VirtualFile fileOrDir) {
final boolean isDir = fileOrDir.isDirectory();
for (int i = 0, pushersLength = pushers.length; i < pushersLength; i++) {
final FilePropertyPusher<Object> pusher = pushers[i];
for (FilePropertyPusher<Object> pusher : pushers) {
if (!isDir && (pusher.pushDirectoriesOnly() || !pusher.acceptsFile(fileOrDir))) continue;
values[i] = findAndUpdateValue(myProject, fileOrDir, pusher, values[i]);
findAndUpdateValue(project, fileOrDir, pusher, null);
}
return true;
}
});
}
@Nullable
public static <T> T findAndUpdateValue(final Project project,
final VirtualFile fileOrDir,
final FilePropertyPusher<T> pusher,
final T parentValue) {
final T immediateValue = pusher.getImmediateValue(project, fileOrDir);
final T value = immediateValue != null ? immediateValue : parentValue;
private static <T> T findPusherValuesUpwards(final Project project, final VirtualFile dir, FilePropertyPusher<T> pusher, T moduleValue) {
final T value = pusher.getImmediateValue(project, dir);
if (value != null) return value;
if (moduleValue != null) return moduleValue;
final VirtualFile parent = dir.getParent();
if (parent != null) return findPusherValuesUpwards(project, parent, pusher);
return pusher.getDefaultValue();
}
private static <T> T findPusherValuesUpwards(final Project project, final VirtualFile dir, FilePropertyPusher<T> pusher) {
final T userValue = dir.getUserData(pusher.getFileDataKey());
if (userValue != null) return userValue;
final T value = pusher.getImmediateValue(project, dir);
if (value != null) return value;
final VirtualFile parent = dir.getParent();
if (parent != null) return findPusherValuesUpwards(project, parent, pusher);
return pusher.getDefaultValue();
}
public void pushAll(final FilePropertyPusher... pushers) {
for (Module module : ModuleManager.getInstance(myProject).getModules()) {
final Object[] moduleValues = new Object[pushers.length];
for (int i = 0; i < moduleValues.length; i++) {
moduleValues[i] = pushers[i].getImmediateValue(module);
}
final ModuleRootManager rootManager = ModuleRootManager.getInstance(module);
final ModuleFileIndex index = rootManager.getFileIndex();
for (VirtualFile root : rootManager.getContentRoots()) {
index.iterateContentUnderDirectory(root, new ContentIterator() {
public boolean processFile(final VirtualFile fileOrDir) {
final boolean isDir = fileOrDir.isDirectory();
for (int i = 0, pushersLength = pushers.length; i < pushersLength; i++) {
final FilePropertyPusher<Object> pusher = pushers[i];
if (!isDir && (pusher.pushDirectoriesOnly() || !pusher.acceptsFile(fileOrDir))) continue;
findAndUpdateValue(myProject, fileOrDir, pusher, moduleValues[i]);
}
return true;
}
});
}
}
}
public static <T> void findAndUpdateValue(final Project project, final VirtualFile fileOrDir, final FilePropertyPusher<T> pusher, final T moduleValue) {
final T value = findPusherValuesUpwards(project, fileOrDir, pusher, moduleValue);
updateValue(fileOrDir, value, pusher);
return value;
}
private static <T> void updateValue(final VirtualFile fileOrDir, final T value, final FilePropertyPusher<T> pusher) {
@@ -16,6 +16,7 @@
package com.intellij.packageDependencies.ui;
import com.intellij.ide.projectView.impl.ProjectRootsUtil;
import com.intellij.ide.projectView.impl.nodes.ProjectViewDirectoryHelper;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.ProjectFileIndex;
@@ -44,13 +45,17 @@ public class DirectoryNode extends PackageDependenciesNode {
private boolean myCompactPackages = true;
private String myFQName = null;
private VirtualFile myVDirectory;
//private static final Logger LOG = Logger.getInstance("#com.intellij.packageDependencies.ui.DirectoryNode");
private final VirtualFile myVDirectory;
public DirectoryNode(VirtualFile aDirectory, Project project, boolean compactPackages, boolean showFQName) {
public DirectoryNode(VirtualFile aDirectory,
Project project,
boolean compactPackages,
boolean showFQName,
VirtualFile baseDir, final VirtualFile[] contentRoots) {
super(project);
myVDirectory = aDirectory;
final ProjectFileIndex index = ProjectRootManager.getInstance(project).getFileIndex();
final ProjectRootManager projectRootManager = ProjectRootManager.getInstance(project);
final ProjectFileIndex index = projectRootManager.getFileIndex();
String dirName = aDirectory.getName();
if (showFQName) {
final VirtualFile contentRoot = index.getContentRootForFile(myVDirectory);
@@ -75,6 +80,20 @@ public class DirectoryNode extends PackageDependenciesNode {
myFQName = FilePatternPackageSet.getLibRelativePath(myVDirectory, index);
}
dirName = myFQName;
} else {
if (contentRoots.length > 1 && ProjectRootsUtil.isModuleContentRoot(myVDirectory, project)) {
if (baseDir != null) {
if (myVDirectory != baseDir) {
if (VfsUtil.isAncestor(baseDir, myVDirectory, false)) {
dirName = VfsUtil.getRelativePath(myVDirectory, baseDir, '/');
} else {
dirName = myVDirectory.getPresentableUrl();
}
}
} else {
dirName = myVDirectory.getPresentableUrl();
}
}
}
myDirName = dirName;
myCompactPackages = compactPackages;
@@ -108,7 +127,6 @@ public class DirectoryNode extends PackageDependenciesNode {
}
public String getFQName() {
final StringBuffer buf = new StringBuffer();
final ProjectFileIndex index = ProjectRootManager.getInstance(myProject).getFileIndex();
VirtualFile directory = myVDirectory;
VirtualFile contentRoot = index.getContentRootForFile(directory);
@@ -118,11 +136,7 @@ public class DirectoryNode extends PackageDependenciesNode {
if (contentRoot == null) {
return "";
}
while (directory != null && contentRoot != directory) {
buf.insert(0, directory.getName() + "/");
directory = directory.getParent();
}
return buf.toString();
return VfsUtil.getRelativePath(directory, contentRoot, '/');
}
public PsiElement getPsiElement() {
@@ -75,9 +75,13 @@ public class FileTreeModelBuilder {
private int myMarkedFileCount = 0;
private JTree myTree;
protected final VirtualFile myBaseDir;
protected VirtualFile[] myContentRoots;
public FileTreeModelBuilder(Project project, Marker marker, DependenciesPanel.DependencyPanelSettings settings) {
myProject = project;
myBaseDir = myProject.getBaseDir();
myContentRoots = ProjectRootManager.getInstance(myProject).getContentRoots();
final boolean multiModuleProject = ModuleManager.getInstance(myProject).getModules().length > 1;
myShowModules = settings.UI_SHOW_MODULES && multiModuleProject;
myFlattenPackages = settings.UI_FLATTEN_PACKAGES;
@@ -434,7 +438,8 @@ public class FileTreeModelBuilder {
final VirtualFile sourceRoot = fileIndex.getSourceRootForFile(virtualFile);
final VirtualFile contentRoot = fileIndex.getContentRootForFile(virtualFile);
directoryNode = new DirectoryNode(virtualFile, myProject, myCompactEmptyMiddlePackages, myFlattenPackages);
directoryNode = new DirectoryNode(virtualFile, myProject, myCompactEmptyMiddlePackages, myFlattenPackages, myBaseDir,
myContentRoots);
myModuleDirNodes.put(virtualFile, (DirectoryNode)directoryNode);
final VirtualFile directory = virtualFile.getParent();
@@ -29,6 +29,7 @@ import com.intellij.psi.PsiManager;
import com.intellij.util.IconUtil;
import com.intellij.util.ui.EmptyIcon;
import com.intellij.util.ui.tree.TreeUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
@@ -46,11 +47,11 @@ public class PackageDependenciesNode extends DefaultMutableTreeNode implements N
private boolean myHasMarked = false;
private boolean myEquals;
protected Color myColor = null;
protected final static Color NOT_CHANGED = new Color(0, 0, 0);
protected static final Color NOT_CHANGED = new Color(0, 0, 0);
protected Project myProject;
private boolean mySorted;
public PackageDependenciesNode(Project project) {
public PackageDependenciesNode(@NotNull Project project) {
myProject = project;
}
@@ -135,7 +136,7 @@ public class PackageDependenciesNode extends DefaultMutableTreeNode implements N
if (hasUnmarked && !myHasUnmarked || hasMarked && !myHasMarked) {
myHasUnmarked |= hasUnmarked;
myHasMarked |= hasMarked;
PackageDependenciesNode parent = ((PackageDependenciesNode)getParent());
PackageDependenciesNode parent = (PackageDependenciesNode)getParent();
if (parent != null) {
parent.updateMarked(myHasUnmarked, myHasMarked);
}
@@ -34,6 +34,7 @@ import com.intellij.psi.impl.source.resolve.reference.impl.providers.FileReferen
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.util.*;
import com.intellij.util.Processor;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.FactoryMap;
import com.intellij.util.containers.HashMap;
import com.intellij.util.containers.MultiMap;
@@ -61,9 +62,9 @@ public class FileIncludeManagerImpl extends FileIncludeManager {
@Override
public boolean process(FileIncludeInfo info) {
if (compileTimeOnly != info.runtimeOnly) {
PsiFileSystemItem virtualFile = resolveFileInclude(info, file);
if (virtualFile != null) {
files.add(virtualFile.getVirtualFile());
PsiFileSystemItem item = resolveFileInclude(info, file);
if (item != null) {
ContainerUtil.addIfNotNull(files, item.getVirtualFile());
}
}
return true;
@@ -323,7 +323,7 @@ public abstract class PsiFileImpl extends ElementBase implements PsiFileEx, PsiF
final CompositeElement xxx = ASTFactory.composite(myElementType);
assert xxx instanceof FileElement : "BUMM";
treeElement = (FileElement)xxx;
treeElement.rawAddChildren(contentLeaf);
treeElement.rawAddChildrenWithoutNotifications(contentLeaf);
}
if (CacheUtil.isCopy(this)) {
@@ -23,6 +23,7 @@ import com.intellij.lang.ASTNode;
import com.intellij.lang.LanguageFormatting;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.actionSystem.IdeActions;
import com.intellij.openapi.actionSystem.PlatformDataKeys;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.command.CommandProcessor;
import com.intellij.openapi.diagnostic.Logger;
@@ -48,6 +49,7 @@ import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiUtilBase;
import com.intellij.testFramework.LightVirtualFile;
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -241,7 +243,7 @@ public class CodeFormatterFacade {
* @param startOffset start offset of the first line to check for wrapping (inclusive)
* @param endOffset end offset of the first line to check for wrapping (exclusive)
*/
private void wrapLongLinesIfNecessary(@NotNull PsiFile file, @Nullable final Document document, final int startOffset,
private void wrapLongLinesIfNecessary(@NotNull final PsiFile file, @Nullable final Document document, final int startOffset,
final int endOffset)
{
if (!mySettings.WRAP_LONG_LINES || file.getViewProvider().isLockedByPsiOperations() || document == null) {
@@ -272,7 +274,7 @@ public class CodeFormatterFacade {
final CaretModel caretModel = editorToUse.getCaretModel();
final int caretOffset = caretModel.getOffset();
final RangeMarker caretMarker = editorToUse.getDocument().createRangeMarker(caretOffset, caretOffset);
doWrapLongLinesIfNecessary(editorToUse, editorToUse.getDocument(), startOffset, endOffset);
doWrapLongLinesIfNecessary(editorToUse, file.getProject(), editorToUse.getDocument(), startOffset, endOffset);
if (caretMarker.isValid() && caretModel.getOffset() != caretMarker.getStartOffset()) {
caretModel.moveToOffset(caretMarker.getStartOffset());
}
@@ -288,7 +290,8 @@ public class CodeFormatterFacade {
}
}
private void doWrapLongLinesIfNecessary(@NotNull final Editor editor, @NotNull Document document, int startOffset, int endOffset) {
private void doWrapLongLinesIfNecessary(@NotNull final Editor editor, @NotNull final Project project, @NotNull Document document,
int startOffset, int endOffset) {
// Normalization.
int startOffsetToUse = Math.min(document.getTextLength(), Math.max(0, startOffset));
int endOffsetToUse = Math.min(document.getTextLength(), Math.max(0, endOffset));
@@ -395,7 +398,21 @@ public class CodeFormatterFacade {
continue;
}
editor.getCaretModel().moveToOffset(wrapOffset);
final DataContext dataContext = DataManager.getInstance().getDataContext(editor.getComponent());
// There is a possible case that formatting is performed from project view and editor is not opened yet. The problem is that
// its data context doesn't contain information about project then. So, we explicitly support that here (see IDEA-72791).
final DataContext baseDataContext = DataManager.getInstance().getDataContext(editor.getComponent());
final DataContext dataContext = new DataContext() {
@Override
public Object getData(@NonNls String dataId) {
Object result = baseDataContext.getData(dataId);
if (result == null && PlatformDataKeys.PROJECT.is(dataId)) {
result = project;
}
return result;
}
};
SelectionModel selectionModel = editor.getSelectionModel();
int startSelectionOffset = 0;
@@ -144,13 +144,8 @@ public class FileReference implements FileReferenceOwner, PsiPolyVariantReferenc
protected ResolveResult[] innerResolve(boolean caseSensitive) {
final String referenceText = getText();
final TextRange range = getRangeInElement();
if (range.isEmpty()) {
final PsiElement element = getElement();
final String s = element.getText();
if (s.length() > range.getEndOffset() && s.charAt(range.getEndOffset()) == '#') {
return new ResolveResult[] { new PsiElementResolveResult(element.getContainingFile())};
}
if (referenceText.isEmpty() && myIndex == 0) {
return new ResolveResult[] { new PsiElementResolveResult(getElement().getContainingFile())};
}
final Collection<PsiFileSystemItem> contexts = getContexts();
final Collection<ResolveResult> result = new THashSet<ResolveResult>(RESOLVE_RESULT_HASHING_STRATEGY);
@@ -401,6 +396,9 @@ public class FileReference implements FileReferenceOwner, PsiPolyVariantReferenc
public PsiElement bindToElement(@NotNull final PsiElement element, final boolean absolute) throws IncorrectOperationException {
if (!(element instanceof PsiFileSystemItem)) throw new IncorrectOperationException("Cannot bind to element, should be instanceof PsiFileSystemItem: " + element);
// handle empty reference that resolves to current file
if (getCanonicalText().isEmpty() && element == getElement().getContainingFile()) return getElement();
final PsiFileSystemItem fileSystemItem = (PsiFileSystemItem)element;
VirtualFile dstVFile = fileSystemItem.getVirtualFile();
if (dstVFile == null) throw new IncorrectOperationException("Cannot bind to non-physical element:" + element);
@@ -75,7 +75,7 @@ public class CompositeElement extends TreeElement {
clone.myModificationsCount = 0;
clone.myWrapper = null;
for (ASTNode child = rawFirstChild(); child != null; child = child.getTreeNext()) {
clone.rawAddChildren((TreeElement)child.clone());
clone.rawAddChildrenWithoutNotifications((TreeElement)child.clone());
}
clone.clearCaches();
}
@@ -88,7 +88,7 @@ public class CompositeElement extends TreeElement {
while(compositeElement != null) {
compositeElement.clearCaches();
if (!(compositeElement instanceof PsiElement)) {
final PsiElement psi = compositeElement.getPsi();
final PsiElement psi = compositeElement.myWrapper;
if (psi instanceof ASTDelegatePsiElement) {
((ASTDelegatePsiElement)psi).subtreeChanged();
}
@@ -133,7 +133,7 @@ public class CompositeElement extends TreeElement {
myModificationsCount++;
myHC = -1;
clearRelativeOffsets(rawFirstChild());
}
@@ -231,7 +231,14 @@ public class CompositeElement extends TreeElement {
@NotNull
public char[] textToCharArray() {
int startStamp = myModificationsCount;
final int len = getTextLength();
if (startStamp != myModificationsCount) {
throw new AssertionError("Tree changed while calculating text");
}
char[] buffer = new char[len];
final int endOffset;
try {
@@ -239,7 +246,7 @@ public class CompositeElement extends TreeElement {
}
catch (ArrayIndexOutOfBoundsException e) {
@NonNls String msg = "Underestimated text length: " + len;
msg += diagnoseTextInconsistency(new String(buffer));
msg += diagnoseTextInconsistency(new String(buffer), startStamp);
try {
int length = AstBufferUtil.toBuffer(this, new char[len], 0);
msg += ";\n repetition gives success (" + length + ")";
@@ -251,14 +258,16 @@ public class CompositeElement extends TreeElement {
}
if (endOffset != len) {
@NonNls String msg = "len=" + len + ";\n endOffset=" + endOffset;
msg += diagnoseTextInconsistency(new String(buffer, 0, endOffset));
msg += diagnoseTextInconsistency(new String(buffer, 0, endOffset), startStamp);
throw new AssertionError(msg);
}
return buffer;
}
private String diagnoseTextInconsistency(String text) {
@NonNls String msg = ";\n buffer=" + text;
private String diagnoseTextInconsistency(String text, int startStamp) {
@NonNls String msg = "";
msg += ";\n changed=" + (startStamp != myModificationsCount);
msg += ";\n buffer=" + text;
msg += ";\n this=" + this;
int shitStart = textMatches(text, 0);
msg += ";\n matches until " + shitStart;
@@ -596,6 +605,7 @@ public class CompositeElement extends TreeElement {
void setFirstChildNode(TreeElement firstChild) {
this.firstChild = firstChild;
clearRelativeOffsets(firstChild);
}
void setLastChildNode(TreeElement lastChild) {
@@ -753,11 +763,17 @@ public class CompositeElement extends TreeElement {
myWrapper = psi;
}
public void rawAddChildren(@NotNull TreeElement first) {
public final void rawAddChildren(@NotNull TreeElement first) {
rawAddChildrenWithoutNotifications(first);
subtreeChanged();
}
public void rawAddChildrenWithoutNotifications(TreeElement first) {
final TreeElement last = getLastChildNode();
if (last == null){
first.rawRemoveUpToWithoutNotifications(null);
setFirstChildNode(first);
first.setTreePrev(null);
while(true){
final TreeElement treeNext = first.getTreeNext();
first.setTreeParent(this);
@@ -768,7 +784,7 @@ public class CompositeElement extends TreeElement {
first.setTreeParent(this);
}
else {
last.rawInsertAfterMe(first);
last.rawInsertAfterMeWithoutNotifications(first);
}
DebugUtil.checkTreeStructure(this);
@@ -175,7 +175,7 @@ public class LazyParseableElement extends CompositeElement {
myText = null;
if (parsedNode == null) return;
rawAddChildren((TreeElement)parsedNode);
rawAddChildrenWithoutNotifications((TreeElement)parsedNode);
//if (getNotCachedLength() != text.length()) {
// if (ApplicationManagerEx.getApplicationEx().isInternal()) {
@@ -194,11 +194,11 @@ public class LazyParseableElement extends CompositeElement {
}
@Override
public void rawAddChildren(@NotNull TreeElement first) {
public void rawAddChildrenWithoutNotifications(@NotNull TreeElement first) {
if (myText() != null) {
LOG.error("Mutating collapsed chameleon");
}
super.rawAddChildren(first);
super.rawAddChildrenWithoutNotifications(first);
}
@Override
@@ -28,6 +28,7 @@ import com.intellij.psi.tree.IElementType;
import com.intellij.util.CharTable;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public abstract class TreeElement extends ElementBase implements ASTNode, Cloneable {
public static final TreeElement[] EMPTY_ARRAY = new TreeElement[0];
@@ -227,6 +228,9 @@ public abstract class TreeElement extends ElementBase implements ASTNode, Clonea
}
setTreePrev(firstNew);
firstNew.setTreeNext(this);
if (p != null) {
p.subtreeChanged();
}
}
else anchorPrev.rawInsertAfterMe(firstNew);
@@ -234,7 +238,16 @@ public abstract class TreeElement extends ElementBase implements ASTNode, Clonea
}
public void rawInsertAfterMe(@NotNull TreeElement firstNew) {
firstNew.rawRemoveUpToLast();
rawInsertAfterMeWithoutNotifications(firstNew);
final CompositeElement parent = getTreeParent();
if (parent != null) {
parent.subtreeChanged();
}
}
protected final void rawInsertAfterMeWithoutNotifications(TreeElement firstNew) {
firstNew.rawRemoveUpToWithoutNotifications(null);
final CompositeElement p = getTreeParent();
final TreeElement treeNext = getTreeNext();
firstNew.setTreePrev(this);
@@ -288,12 +301,17 @@ public abstract class TreeElement extends ElementBase implements ASTNode, Clonea
public void rawReplaceWithList(TreeElement firstNew) {
if (firstNew != null){
rawInsertAfterMe(firstNew);
rawInsertAfterMeWithoutNotifications(firstNew);
}
rawRemove();
}
protected void invalidate() {
CompositeElement parent = getTreeParent();
if (parent != null) {
parent.subtreeChanged();
}
// invalidate replaced element
setTreeNext(null);
setTreePrev(null);
@@ -306,7 +324,18 @@ public abstract class TreeElement extends ElementBase implements ASTNode, Clonea
}
// remove nodes from this[including] to end[excluding] from the parent
public void rawRemoveUpTo(TreeElement end) {
public void rawRemoveUpTo(@Nullable TreeElement end) {
CompositeElement parent = getTreeParent();
rawRemoveUpToWithoutNotifications(end);
if (parent != null) {
parent.subtreeChanged();
}
}
// remove nodes from this[including] to end[excluding] from the parent
protected final void rawRemoveUpToWithoutNotifications(TreeElement end) {
if(this == end) return;
final CompositeElement parent = getTreeParent();
@@ -47,6 +47,7 @@ public class InjectedFileViewProvider extends SingleRootFileViewProvider {
return false;
}
};
private boolean myPatchingLeaves;
InjectedFileViewProvider(@NotNull PsiManager psiManager,
@NotNull VirtualFileWindow virtualFile,
@@ -64,6 +65,7 @@ public class InjectedFileViewProvider extends SingleRootFileViewProvider {
public void rootChanged(PsiFile psiFile) {
super.rootChanged(psiFile);
if (!isPhysical()) return; // injected PSI change happened inside reparse; ignore
if (myPatchingLeaves) return;
List<PsiLanguageInjectionHost.Shred> shreds;
synchronized (myLock) {
@@ -171,4 +173,8 @@ public class InjectedFileViewProvider extends SingleRootFileViewProvider {
public String toString() {
return "Injected file '"+getVirtualFile().getName()+"' " + (isValid() ? "" : " invalid") + (isPhysical() ? "" : " nonphysical");
}
public void setPatchingLeaves(boolean patchingLeaves) {
myPatchingLeaves = patchingLeaves;
}
}
@@ -226,6 +226,8 @@ public class MultiHostRegistrarImpl implements MultiHostRegistrar {
String documentText = documentWindow.getText();
assert outChars.toString().equals(parsedNode.getText()) : exceptionContext("Before patch: doc:\n'" + documentText + "'\n---PSI:\n'" + parsedNode.getText() + "'\n---chars:\n'"+outChars+"'");
viewProvider.setPatchingLeaves(true);
try {
patchLeafs(parsedNode, escapers, place);
}
@@ -235,10 +237,13 @@ public class MultiHostRegistrarImpl implements MultiHostRegistrar {
catch (RuntimeException e) {
throw new RuntimeException(exceptionContext("Patch error"), e);
}
finally {
viewProvider.setPatchingLeaves(false);
}
assert parsedNode.getText().equals(documentText) : exceptionContext("After patch: doc:\n'" + documentText + "'\n---PSI:\n'" + parsedNode.getText() + "'\n---chars:\n'"+outChars+"'");
virtualFile.setContent(null, documentWindow.getText(), false);
cacheEverything(place, documentWindow, viewProvider, psiFile, pointer);
PsiFile cachedPsiFile = documentManager.getCachedPsiFile(documentWindow);
@@ -119,7 +119,7 @@ public class TextFieldWithAutoCompletion extends EditorTextField {
lookup.setAdvertisementText(advertisementText);
lookup.refreshUi();
}
lookup.show();
lookup.showLookup();
}
public void setAdvertisementText(@Nullable String text) {
@@ -188,7 +188,7 @@ public class LazyRangeMarkerFactory extends AbstractProjectComponent {
offset = lineStart;
int col = 0;
while (offset < lineEnd && col < column) {
col += (docText.charAt(offset) == '\t' ? tabSize : 1);
col += docText.charAt(offset) == '\t' ? tabSize : 1;
offset++;
}
}
@@ -43,7 +43,8 @@ public class LogModel {
}
void addNotification(Notification notification) {
if (notification.isImportant() || NotificationsConfiguration.getSettings(notification.getGroupId()).getDisplayType() != NotificationDisplayType.NONE) {
NotificationDisplayType type = NotificationsConfiguration.getSettings(notification.getGroupId()).getDisplayType();
if (notification.isImportant() || (type != NotificationDisplayType.NONE && type != NotificationDisplayType.TOOL_WINDOW)) {
synchronized (myNotifications) {
myNotifications.add(notification);
}
@@ -22,6 +22,7 @@ import com.intellij.openapi.Disposable;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.components.ApplicationComponent;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ProjectManager;
import com.intellij.openapi.startup.StartupManager;
import com.intellij.openapi.ui.MessageType;
import com.intellij.openapi.ui.popup.*;
@@ -178,6 +179,9 @@ public class NotificationsManagerImpl extends NotificationsManager implements No
(toolWindowId == null || project == null || !Arrays.asList(ToolWindowManager.getInstance(project).getToolWindowIds()).contains(toolWindowId))) {
type = NotificationDisplayType.BALLOON;
}
if (type == NotificationDisplayType.BALLOON && ProjectManager.getInstance().getOpenProjects().length == 0) {
type = NotificationDisplayType.STICKY_BALLOON;
}
switch (type) {
case NONE:
@@ -21,7 +21,6 @@ import com.intellij.openapi.editor.ex.DocumentEx;
import com.intellij.openapi.editor.ex.RangeMarkerEx;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.UserDataHolderBase;
import com.intellij.util.DistributedCounter;
import com.intellij.util.Processor;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
@@ -33,7 +32,7 @@ public class RangeMarkerImpl extends UserDataHolderBase implements RangeMarkerEx
protected RangeMarkerTree.RMNode myNode;
private final long myId;
private static final DistributedCounter counter = new DistributedCounter();
private static final StripedIDGenerator counter = new StripedIDGenerator();
protected RangeMarkerImpl(@NotNull DocumentEx document, int start, int end, boolean register) {
this(document, start, end, register, false, false);
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.util;
package com.intellij.openapi.editor.impl;
import java.util.concurrent.atomic.AtomicLong;
@@ -21,10 +21,10 @@ import java.util.concurrent.atomic.AtomicLong;
* Low-contention counter.
* Repeated calls to {@link #next()} return numbers which are unique across all calling threads, and which are increasing over calls within one thread.
*/
public class DistributedCounter {
public class StripedIDGenerator {
private static final int CHUNK_SIZE = 1000;
private final AtomicLong nextChunkStart = new AtomicLong();
// must not ne static
// must not be static since we might want to have several instances of this class
private final ThreadLocal<NextPair> localCounter = new ThreadLocal<NextPair>();
private static class NextPair {
long nextId;
@@ -45,7 +45,7 @@ public class CheckForUpdateAction extends AnAction implements DumbAware {
ProgressManager.getInstance().run(new Task.Backgroundable(project, "Checking for updates", false) {
@Override
public void run(@NotNull ProgressIndicator indicator) {
final CheckForUpdateResult result = UpdateChecker.checkForUpdates();
final CheckForUpdateResult result = UpdateChecker.checkForUpdates(true);
final List<PluginDownloader> updatedPlugins = UpdateChecker.updatePlugins(true, settingsConfigurable);
ApplicationManager.getApplication().invokeLater(new Runnable() {
@@ -287,12 +287,11 @@ public final class UpdateChecker {
}
@NotNull
public static CheckForUpdateResult doCheckForUpdates() {
public static CheckForUpdateResult doCheckForUpdates(final UpdateSettings settings) {
ApplicationInfo appInfo = ApplicationInfo.getInstance();
BuildNumber currentBuild = appInfo.getBuild();
int majorVersion = Integer.parseInt(appInfo.getMajorVersion());
final UpdatesXmlLoader loader = new UpdatesXmlLoader(getUpdateUrl(), getInstallationUID(), null);
final UpdateSettings settings = UpdateSettings.getInstance();
final UpdatesInfo info;
try {
info = loader.loadUpdatesInfo();
@@ -309,19 +308,48 @@ public final class UpdateChecker {
}
@NotNull
public static CheckForUpdateResult checkForUpdates() {
return checkForUpdates(false);
}
@NotNull
public static CheckForUpdateResult checkForUpdates(final boolean disregardIgnoredBuilds) {
if (LOG.isDebugEnabled()) {
LOG.debug("enter: auto checkForUpdates()");
}
final UpdateSettings settings = UpdateSettings.getInstance();
UserUpdateSettings settings = UpdateSettings.getInstance();
if (disregardIgnoredBuilds) {
settings = new UserUpdateSettings() {
@NotNull
@Override
public List<String> getKnownChannelsIds() {
return UpdateSettings.getInstance().getKnownChannelsIds();
}
final CheckForUpdateResult result = doCheckForUpdates();
@Override
public List<String> getIgnoredBuildNumbers() {
return Collections.emptyList();
}
@Override
public void setKnownChannelIds(List<String> ids) {
UpdateSettings.getInstance().setKnownChannelIds(ids);
}
@NotNull
@Override
public ChannelStatus getSelectedChannelStatus() {
return UpdateSettings.getInstance().getSelectedChannelStatus();
}
};
}
final CheckForUpdateResult result = doCheckForUpdates(UpdateSettings.getInstance());
if (result.getState() == UpdateStrategy.State.LOADED) {
settings.LAST_TIME_CHECKED = System.currentTimeMillis();
UpdateSettings.getInstance().LAST_TIME_CHECKED = System.currentTimeMillis();
settings.setKnownChannelIds(result.getAllChannelsIds());
}
@@ -289,6 +289,7 @@ public class IdeFrameImpl extends JFrame implements IdeFrame, DataProvider {
myProject = project;
if (project != null) {
ProjectFrameBounds.getInstance(project); // make sure the service is initialized and its state will be saved
if (myRootPane != null) {
myRootPane.installNorthComponents(project);
}
@@ -0,0 +1,60 @@
/*
* 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.wm.impl;
import com.intellij.openapi.components.PersistentStateComponent;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.components.State;
import com.intellij.openapi.components.Storage;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.wm.WindowManager;
import java.awt.*;
/**
* @author yole
*/
@State(
name = "ProjectFrameBounds",
storages = { @Storage(
file = "$WORKSPACE_FILE$") }
)
public class ProjectFrameBounds implements PersistentStateComponent<Rectangle> {
public static ProjectFrameBounds getInstance(Project project) {
return ServiceManager.getService(project, ProjectFrameBounds.class);
}
private final Project myProject;
private Rectangle myBounds;
public ProjectFrameBounds(Project project) {
myProject = project;
}
@Override
public Rectangle getState() {
return WindowManager.getInstance().getFrame(myProject).getBounds();
}
@Override
public void loadState(Rectangle state) {
myBounds = state;
}
public Rectangle getBounds() {
return myBounds;
}
}
@@ -540,7 +540,11 @@ public final class WindowManagerImpl extends WindowManagerEx implements Applicat
else {
frame = new IdeFrameImpl((ApplicationInfoEx)ApplicationInfo.getInstance(), ActionManagerEx.getInstanceEx(), UISettings.getInstance(),
DataManager.getInstance(), ApplicationManager.getApplication(), ArrayUtil.EMPTY_STRING_ARRAY);
if (myFrameBounds != null) {
final Rectangle bounds = ProjectFrameBounds.getInstance(project).getBounds();
if (bounds != null) {
frame.setBounds(bounds);
}
else if (myFrameBounds != null) {
frame.setBounds(myFrameBounds);
}
frame.setExtendedState(myFrameExtendedState);
@@ -529,3 +529,4 @@ insert.override.annotation=Insert @&Override annotation
auto.import=Auto Import
checkbox.collapse.suppress.warnings=<html>@SuppressWarnings</html>
checkbox.collapse.end.of.line.comments=<html>End of line comments sequence</html>
title.other.languages=Other Languages
@@ -224,4 +224,6 @@
<toolWindow id="Event Log" anchor="bottom" secondary="true"
factoryClass="com.intellij.notification.EventLog$FactoryItself"/>
<projectService serviceInterface="com.intellij.openapi.wm.impl.ProjectFrameBounds"
serviceImplementation="com.intellij.openapi.wm.impl.ProjectFrameBounds"/>
</extensions>
@@ -12,6 +12,7 @@ import java.util.Arrays;
* Time: 1:34 PM
*/
abstract class IntToIntBtree {
static final int VERSION = 1;
static final boolean doSanityCheck = false;
static final boolean doDump = false;
private static final int ROUND_FACTOR = 1048576;
@@ -35,7 +36,7 @@ abstract class IntToIntBtree {
private final byte[] buffer;
private boolean isLarge = true;
private final ISimpleStorage storage;
private final boolean offloadToSiblingsBeforeSplit = false; // TODO till effective insertion to page
private final boolean offloadToSiblingsBeforeSplit = false;
private boolean indexNodeIsHashTable = true;
final int metaDataLeafPageLength;
final int hashPageCapacity;
@@ -184,7 +185,7 @@ abstract class IntToIntBtree {
int usedPercent = (int)((count * 100L) / leafNodesCapacity);
int usedPercent2 = (int)((count * 100L) / leafNodesCapacity2);
IOStatistics.dump("pagecount:" + pagesCount + ", height:" + height + ", movedMembers:"+movedMembersCount +
", hash steps:" + maxStepsSearchedInHash + ", avg search in hash:" + (totalHashStepsSearched / hashSearchRequests) +
", hash steps:" + maxStepsSearchedInHash + ", avg search in hash:" + (hashSearchRequests != 0 ? totalHashStepsSearched / hashSearchRequests:0) +
", leaf pages used:" + usedPercent + "%, leaf pages used if max children: " + usedPercent2 + "%" );
}
@@ -279,6 +280,7 @@ abstract class IntToIntBtree {
static class BtreeIndexNodeView extends BtreePage {
static final int INTERIOR_SIZE = 8;
static final int KEY_OFFSET = 4;
static final int MIN_ITEMS_TO_SHARE = 20;
private boolean isIndexLeaf;
private boolean isIndexLeafSet;
@@ -448,19 +450,62 @@ abstract class IntToIntBtree {
return keys;
}
private int splitNode(int parentAddress) {
if (doSanityCheck) {
myAssert(isFull());
dump("before split:"+isIndexLeaf());
static class HashLeafData {
final BtreeIndexNodeView nodeView;
final int[] keys;
final TIntIntHashMap values;
HashLeafData(BtreeIndexNodeView _nodeView, int recordCount) {
nodeView = _nodeView;
final IntToIntBtree btree = _nodeView.btree;
nodeView.getBytes(nodeView.indexToOffset(0), btree.buffer, 0, btree.pageSize - btree.metaDataLeafPageLength);
keys = new int[recordCount];
values = new TIntIntHashMap(recordCount);
int keyNumber = 0;
for(int i = 0; i < btree.hashPageCapacity; ++i) {
if (nodeView.hashGetState(i) == HASH_FULL) {
int key = Bits.getInt(btree.buffer, i * INTERIOR_SIZE + KEY_OFFSET);
keys[keyNumber++] = key;
values.put(key, Bits.getInt(btree.buffer, i * INTERIOR_SIZE));
}
}
Arrays.sort(keys);
}
void clean() {
final IntToIntBtree btree = nodeView.btree;
for(int i = 0; i < btree.hashPageCapacity; ++i) {
nodeView.hashSetState(i, HASH_FREE);
}
}
}
private int splitNode(int parentAddress) {
final boolean indexLeaf = isIndexLeaf();
if (doSanityCheck) {
myAssert(isFull());
dump("before split:"+indexLeaf);
}
final boolean hashedLeaf = isHashedLeaf();
final short recordCount = getChildrenCount();
BtreeIndexNodeView parent = null;
HashLeafData hashLeafData = null;
if (parentAddress != 0) {
parent = new BtreeIndexNodeView(btree);
parent.setAddress(parentAddress);
if (btree.offloadToSiblingsBeforeSplit) {
if (doOffloadToSiblings(parent)) return parentAddress;
if (hashedLeaf) {
hashLeafData = new HashLeafData(this, recordCount);
if (doOffloadToSiblingsWhenHashed(parent, hashLeafData)) return parentAddress;
} else {
if (doOffloadToSiblingsSorted(parent)) return parentAddress;
}
}
}
@@ -469,56 +514,70 @@ abstract class IntToIntBtree {
BtreeIndexNodeView newIndexNode = new BtreeIndexNodeView(btree);
newIndexNode.setAddress(btree.nextPage(false));
boolean indexLeaf = isIndexLeaf();
newIndexNode.setIndexLeaf(indexLeaf);
int nextPage = getNextPage();
setNextPage(newIndexNode.address);
newIndexNode.setNextPage(nextPage);
final short recordCount = getChildrenCount();
int medianKey = -1;
int medianKey;
if (indexLeaf && hashedLeaf) {
if (hashLeafData == null) hashLeafData = new HashLeafData(this, recordCount);
final int[] keys = hashLeafData.keys;
if (indexLeaf && isHashedLeaf()) {
TIntIntHashMap map = new TIntIntHashMap(recordCount);
getBytes(indexToOffset(0), btree.buffer, 0, btree.pageSize - btree.metaDataLeafPageLength);
int[] keys = new int[recordCount];
int keyNumber = 0;
for(int i = 0; i < btree.hashPageCapacity; ++i) {
if (hashGetState(i) == HASH_FULL) {
int key = Bits.getInt(btree.buffer, i * INTERIOR_SIZE + KEY_OFFSET);
keys[keyNumber++] = key;
map.put(key, Bits.getInt(btree.buffer, i * INTERIOR_SIZE));
hashSetState(i, HASH_FREE);
boolean defaultSplit = true;
//if (keys[keys.length - 1] < newValue && btree.height <= 3 && false) {
// btree.root.setAddress(btree.root.address);
// if (btree.height == 2 && btree.root.search(keys[0]) == btree.root.getChildrenCount() - 1) {
// defaultSplit = false;
// } else if (btree.height == 3 &&
// btree.root.search(keys[0]) == -btree.root.getChildrenCount() &&
// parent.search(keys[0]) == parent.getChildrenCount() - 1
// ) {
// defaultSplit = false;
// }
//
// if (!defaultSplit) {
// newIndexNode.setChildrenCount((short)0);
// newIndexNode.insert(newValue, 0);
// ++btree.count;
// medianKey = newValue;
// }
//}
if (defaultSplit) {
hashLeafData.clean();
final TIntIntHashMap map = hashLeafData.values;
final int avg = keys.length / 2;
medianKey = keys[avg];
--btree.hashedPagesCount;
setChildrenCount((short)0);
newIndexNode.setChildrenCount((short)0);
for(int i = 0; i < avg; ++i) {
int key = keys[i];
insert(key, map.get(key));
key = keys[avg + i];
newIndexNode.insert(key, map.get(key));
}
/*setHashedLeaf(false);
setChildrenCount((short)keys.length);
--btree.hashedPagesCount;
btree.movedMembersCount += keys.length;
for(int i = 0; i < keys.length; ++i) {
int key = keys[i];
setKeyAt(i, key);
setAddressAt(i, map.get(key));
}
return parentAddress;*/
}
Arrays.sort(keys);
final int avg = keys.length / 2;
medianKey = keys[avg];
--btree.hashedPagesCount;
setChildrenCount((short)0);
newIndexNode.setChildrenCount((short)0);
for(int i = 0; i < avg; ++i) {
insert(keys[i], map.get(keys[i]));
newIndexNode.insert(keys[avg + i], map.get(keys[avg + i]));
}
/*setHashedLeaf(false);
setChildrenCount((short)keys.length);
--btree.hashedPagesCount;
btree.movedMembersCount += keys.length;
for(int i = 0; i < keys.length; ++i) {
int key = keys[i];
setKeyAt(i, key);
setAddressAt(i, map.get(key));
}
return parentAddress;*/
} else {
short recordCountInNewNode = (short)(recordCount - maxIndex);
newIndexNode.setChildrenCount(recordCountInNewNode);
@@ -595,56 +654,157 @@ abstract class IntToIntBtree {
return parentAddress;
}
private boolean doOffloadToSiblings(BtreeIndexNodeView parent) {
int indexInParent = isIndexLeaf() ? parent.search(keyAt(0)) : -1;
BtreeIndexNodeView sibling = new BtreeIndexNodeView(btree);
private boolean doOffloadToSiblingsWhenHashed(BtreeIndexNodeView parent, final HashLeafData hashLeafData) {
int indexInParent = parent.search(hashLeafData.keys[0]);
if (indexInParent >= 0) {
BtreeIndexNodeView sibling = new BtreeIndexNodeView(btree);
sibling.setAddress(-parent.addressAt(indexInParent));
int numberOfKeysToMove = (sibling.getMaxChildrenCount() - sibling.getChildrenCount()) / 2;
if (!sibling.isFull() && numberOfKeysToMove > MIN_ITEMS_TO_SHARE) {
if (doSanityCheck) {
sibling.dump("Offloading to left sibling");
parent.dump("parent before");
}
final int childrenCount = getChildrenCount();
final int[] keys = hashLeafData.keys;
final TIntIntHashMap map = hashLeafData.values;
for(int i = 0; i < numberOfKeysToMove; ++i) {
final int key = keys[i];
sibling.insert(key, map.get(key));
}
if (doSanityCheck) {
sibling.dump("Left sibling after");
}
parent.setKeyAt(indexInParent, keys[numberOfKeysToMove]);
setChildrenCount((short)0);
--btree.hashedPagesCount;
hashLeafData.clean();
for(int i = numberOfKeysToMove; i < childrenCount; ++i) {
final int key = keys[i];
insert(key, map.get(key));
}
} else if (indexInParent + 1 < parent.getChildrenCount()) {
insertToRightSiblingWhenHashed(parent, hashLeafData, indexInParent, sibling);
}
} else if (indexInParent == -1) {
insertToRightSiblingWhenHashed(parent, hashLeafData, 0, new BtreeIndexNodeView(btree));
}
if (!isFull()) {
sync();
parent.sync();
if (indexInParent > 0) {
if (doSanityCheck) {
dump("old node after split:");
parent.dump("Parent node after split");
}
return true;
}
return false;
}
private void insertToRightSiblingWhenHashed(BtreeIndexNodeView parent,
HashLeafData hashLeafData,
int indexInParent,
BtreeIndexNodeView sibling) {
sibling.setAddress(-parent.addressAt(indexInParent + 1));
int numberOfKeysToMove = (sibling.getMaxChildrenCount() - sibling.getChildrenCount()) / 2;
if (!sibling.isFull() && numberOfKeysToMove > MIN_ITEMS_TO_SHARE) {
if (doSanityCheck) {
sibling.dump("Offloading to right sibling");
parent.dump("parent before");
}
final int[] keys = hashLeafData.keys;
final TIntIntHashMap map = hashLeafData.values;
final int childrenCount = getChildrenCount();
final int lastChildIndex = childrenCount - numberOfKeysToMove;
for(int i = lastChildIndex; i < childrenCount; ++i) {
final int key = keys[i];
sibling.insert(key, map.get(key));
}
if (doSanityCheck) {
sibling.dump("Right sibling after");
}
parent.setKeyAt(indexInParent, keys[lastChildIndex]);
setChildrenCount((short)0);
--btree.hashedPagesCount;
hashLeafData.clean();
for(int i = 0; i < lastChildIndex; ++i) {
final int key = keys[i];
insert(key, map.get(key));
}
}
}
private boolean doOffloadToSiblingsSorted(BtreeIndexNodeView parent) {
boolean indexLeaf = isIndexLeaf();
if (!indexLeaf) return false; // TODO
int indexInParent = parent.search(keyAt(0));
if (indexInParent >= 0) {
if (doSanityCheck) {
myAssert(parent.keyAt(indexInParent) == keyAt(0));
myAssert(parent.addressAt(indexInParent + 1) == -address);
}
int siblingAddress = parent.addressAt(indexInParent);
sibling.setAddress(-siblingAddress);
BtreeIndexNodeView sibling = new BtreeIndexNodeView(btree);
sibling.setAddress(-parent.addressAt(indexInParent));
if (!sibling.isFull() && sibling.getChildrenCount() + 1 != sibling.getMaxChildrenCount()) {
final int toMove = (sibling.getMaxChildrenCount() - sibling.getChildrenCount()) / 2;
if (toMove > 0) {
if (doSanityCheck) {
sibling.dump("Offloading to left sibling");
parent.dump("parent before");
}
sibling.insert(keyAt(0), addressAt(0));
for(int i = 0; i < toMove; ++i) sibling.insert(keyAt(i), addressAt(i));
if (doSanityCheck) {
sibling.dump("Left sibling after");
}
parent.setKeyAt(indexInParent, keyAt(1));
parent.setKeyAt(indexInParent, keyAt(toMove));
int indexOfLastChildToMove = (int)getChildrenCount() - toMove;
btree.movedMembersCount += indexOfLastChildToMove;
int indexOflastChildToMove = getChildrenCount() - 1;
if (btree.isLarge) {
final int bytesToMove = indexOflastChildToMove * INTERIOR_SIZE;
getBytes(indexToOffset(1), btree.buffer, 0, bytesToMove);
final int bytesToMove = indexOfLastChildToMove * INTERIOR_SIZE;
getBytes(indexToOffset(toMove), btree.buffer, 0, bytesToMove);
putBytes(indexToOffset(0), btree.buffer, 0, bytesToMove);
}
else {
for (int i = 0; i < indexOflastChildToMove; ++i) {
setAddressAt(i, addressAt(i + 1));
setKeyAt(i, keyAt(i + 1));
for (int i = 0; i < indexOfLastChildToMove; ++i) {
setAddressAt(i, addressAt(i + toMove));
setKeyAt(i, keyAt(i + toMove));
}
}
setChildrenCount((short)indexOflastChildToMove);
setChildrenCount((short)indexOfLastChildToMove);
}
else if (indexInParent + 1 < parent.getChildrenCount()) {
insertToRightSibling(parent, indexInParent + 1, sibling);
insertToRightSiblingWhenSorted(parent, indexInParent + 1, sibling);
}
// TODO: move members in non leaf level + handle cases below
} /*else if (indexInParent == -1) {
insertToRightSibling(parent, 0, sibling);
} else {
int a = 1;
}*/
} else if (indexInParent == -1) {
insertToRightSiblingWhenSorted(parent, 0, new BtreeIndexNodeView(btree));
}
if (!isFull()) {
sync();
@@ -659,19 +819,19 @@ abstract class IntToIntBtree {
return false;
}
private void insertToRightSibling(BtreeIndexNodeView parent, int indexInParent, BtreeIndexNodeView sibling) {
int siblingAddress;
siblingAddress = parent.addressAt(indexInParent + 1);
sibling.setAddress(-siblingAddress);
private void insertToRightSiblingWhenSorted(BtreeIndexNodeView parent, int indexInParent, BtreeIndexNodeView sibling) {
sibling.setAddress(-parent.addressAt(indexInParent + 1));
int toMove = (sibling.getMaxChildrenCount() - sibling.getChildrenCount()) / 2;
if (!sibling.isFull() && sibling.getChildrenCount() + 1 != sibling.getMaxChildrenCount()) {
if (toMove > 0) {
if (doSanityCheck) {
sibling.dump("Offloading to right sibling");
parent.dump("parent before");
}
int lastChildIndex = getChildrenCount() - 1;
sibling.insert(keyAt(lastChildIndex), addressAt(lastChildIndex));
int childrenCount = getChildrenCount();
int lastChildIndex = childrenCount - toMove;
for(int i = lastChildIndex; i < childrenCount; ++i) sibling.insert(keyAt(i), addressAt(i));
if (doSanityCheck) {
sibling.dump("Right sibling after");
}
@@ -682,6 +842,11 @@ abstract class IntToIntBtree {
private void dump(String s) {
if (doDump) {
immediateDump(s);
}
}
private void immediateDump(String s) {
short maxIndex = getChildrenCount();
System.out.println(s + " @" + address);
for(int i = 0; i < maxIndex; ++i) {
@@ -695,7 +860,6 @@ abstract class IntToIntBtree {
System.out.println();
}
}
}
private int locate(int valueHC, boolean split) {
int searched = 0;
@@ -62,7 +62,7 @@ public class PersistentBTreeEnumerator<Data> extends PersistentEnumeratorBase<Da
private final boolean myInlineKeysNoMapping;
private static final int DIRTY_MAGIC = 0xbabe1977;
private static final int VERSION = 6;
private static final int VERSION = 5 + IntToIntBtree.VERSION;
private static final int CORRECTLY_CLOSED_MAGIC = 0xebabafc + VERSION + PAGE_SIZE;
private static Version ourVersion = new Version(CORRECTLY_CLOSED_MAGIC, DIRTY_MAGIC);
@@ -15,16 +15,119 @@
*/
package com.intellij.util.io;
import com.intellij.util.containers.SLRUMap;
import java.io.File;
import java.io.IOException;
public class PersistentStringEnumerator extends PersistentEnumerator<String>{
private final SLRUMap<Integer, String> myIdToStringCache;
private final SLRUMap<Integer, Integer> myHashcodeToIdCache;
public PersistentStringEnumerator(final File file) throws IOException {
this(file, 1024 * 4);
}
public PersistentStringEnumerator(final File file, final int initialSize) throws IOException {
super(file, new EnumeratorStringDescriptor(), initialSize);
public PersistentStringEnumerator(final File file, boolean cacheLastMappings) throws IOException {
this(file, 1024 * 4, cacheLastMappings);
}
public PersistentStringEnumerator(final File file, final int initialSize) throws IOException {
this(file, initialSize, false);
}
private PersistentStringEnumerator(final File file, final int initialSize, boolean cacheLastMappings) throws IOException {
super(file, new EnumeratorStringDescriptor(), initialSize);
if (cacheLastMappings) {
myIdToStringCache = new SLRUMap<Integer, String>(8192, 8192);
myHashcodeToIdCache = new SLRUMap<Integer, Integer>(8192, 8192);
} else {
myIdToStringCache = null;
myHashcodeToIdCache = null;
}
}
@Override
public int enumerate(String value) throws IOException {
if (myHashcodeToIdCache != null && value != null) {
Integer cachedId;
synchronized (myHashcodeToIdCache) {
cachedId = myHashcodeToIdCache.get(value.hashCode());
}
if (cachedId != null) {
String s;
synchronized (myIdToStringCache) {
s = myIdToStringCache.get(cachedId.intValue());
}
if (s != null && value.equals(s)) return cachedId.intValue();
}
}
int enumerate = super.enumerate(value);
if (myHashcodeToIdCache != null && value != null) {
synchronized (myHashcodeToIdCache) {
myHashcodeToIdCache.put(value.hashCode(), enumerate);
}
}
return enumerate;
}
@Override
protected int enumerateImpl(String value, boolean saveNewValue) throws IOException {
int idx = super.enumerateImpl(value, saveNewValue);
if (myIdToStringCache != null) {
synchronized (myIdToStringCache) {
myIdToStringCache.put(idx, value);
}
}
return idx;
}
@Override
public String valueOf(int idx) throws IOException {
if (myIdToStringCache != null) {
synchronized (myIdToStringCache) {
String s = myIdToStringCache.get(idx);
if (s != null) return s;
}
}
return super.valueOf(idx);
}
@Override
protected void markCorrupted() {
super.markCorrupted();
if (myIdToStringCache != null) {
synchronized (myIdToStringCache) {
myIdToStringCache.clear();
}
}
if (myHashcodeToIdCache != null) {
synchronized (myHashcodeToIdCache) {
myHashcodeToIdCache.clear();
}
}
}
@Override
protected void doClose() throws IOException {
super.doClose();
if (myIdToStringCache != null) {
synchronized (myIdToStringCache) {
myIdToStringCache.clear();
}
}
if (myHashcodeToIdCache != null) {
synchronized (myHashcodeToIdCache) {
myHashcodeToIdCache.clear();
}
}
}
}
@@ -31,11 +31,13 @@ import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.awt.*;
import java.beans.Introspector;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.*;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
class BeanBinding implements Binding {
@@ -208,6 +210,17 @@ class BeanBinding implements Binding {
accessors = Lists.newArrayList();
if (aClass != Rectangle.class) { // special case for Rectangle.class to avoid infinite recursion during serialization due to bounds() method
collectPropertyAccessors(aClass, accessors);
}
collectFieldAccessors(aClass, accessors);
ourAccessorCache.put(aClass, new SoftReference<List<Accessor>>(accessors));
return accessors;
}
private static void collectPropertyAccessors(Class<?> aClass, List<Accessor> accessors) {
final Map<String, Pair<Method, Method>> candidates = Maps.newTreeMap(); // (name,(getter,setter))
for (Method method : aClass.getMethods()) {
if (!Modifier.isPublic(method.getModifiers())) continue;
@@ -230,7 +243,9 @@ class BeanBinding implements Binding {
accessors.add(new PropertyAccessor(candidate.getKey(), methods.first.getReturnType(), methods.first, methods.second));
}
}
}
private static void collectFieldAccessors(Class<?> aClass, List<Accessor> accessors) {
for (Field field : aClass.getFields()) {
final int modifiers = field.getModifiers();
if (Modifier.isPublic(modifiers) && !Modifier.isStatic(modifiers) &&
@@ -239,10 +254,6 @@ class BeanBinding implements Binding {
accessors.add(new FieldAccessor(field));
}
}
ourAccessorCache.put(aClass, new SoftReference<List<Accessor>>(accessors));
return accessors;
}
@Nullable
@@ -47,29 +47,33 @@ public class TooBroadThrowsInspection extends BaseInspection {
"overly.broad.throws.clause.display.name");
}
@Override @NotNull
@Override
@NotNull
protected String buildErrorString(Object... infos) {
final List<PsiClass> typesMasked = (List<PsiClass>)infos[0];
String typesMaskedString = typesMasked.get(0).getName();
final List<SmartTypePointer> typesMasked = (List<SmartTypePointer>)infos[0];
final PsiType type = typesMasked.get(0).getType();
String typesMaskedString = type != null ? type.getPresentableText() : "";
if (typesMasked.size() == 1) {
return InspectionGadgetsBundle.message(
"overly.broad.throws.clause.problem.descriptor1",
typesMaskedString);
} else {
"overly.broad.throws.clause.problem.descriptor1",
typesMaskedString);
}
else {
final int lastTypeIndex = typesMasked.size() - 1;
for (int i = 1; i < lastTypeIndex; i++) {
typesMaskedString += ", ";
typesMaskedString += typesMasked.get(i).getName();
final PsiType psiType = typesMasked.get(i).getType();
if (psiType != null) {
typesMaskedString += ", ";
typesMaskedString += psiType.getPresentableText();
}
}
final String lastTypeString =
typesMasked.get(lastTypeIndex).getName();
return InspectionGadgetsBundle.message(
"overly.broad.throws.clause.problem.descriptor2",
typesMaskedString, lastTypeString);
final PsiType psiType = typesMasked.get(lastTypeIndex).getType();
final String lastTypeString = psiType != null ? psiType.getPresentableText() : "";
return InspectionGadgetsBundle.message("overly.broad.throws.clause.problem.descriptor2", typesMaskedString, lastTypeString);
}
}
@Override
@Override
public JComponent createOptionsPanel() {
return new SingleCheckboxOptionsPanel(
InspectionGadgetsBundle.message("too.broad.catch.option"),
@@ -79,23 +83,21 @@ public class TooBroadThrowsInspection extends BaseInspection {
@NotNull
@Override
protected InspectionGadgetsFix buildFix(Object... infos) {
final Collection<PsiClass> maskedExceptions =
(Collection<PsiClass>)infos[0];
final Collection<SmartTypePointer> maskedExceptions =
(Collection<SmartTypePointer>)infos[0];
final Boolean originalNeeded = (Boolean) infos[1];
return new AddThrowsClauseFix(maskedExceptions,
originalNeeded.booleanValue());
}
private static class AddThrowsClauseFix extends InspectionGadgetsFix {
private final Collection<SmartPsiElementPointer<PsiClass>> types;
private final Collection<SmartTypePointer> types;
private final boolean originalNeeded;
AddThrowsClauseFix(@NotNull Collection<PsiClass> classes,
AddThrowsClauseFix(Collection<SmartTypePointer> types,
boolean originalNeeded) {
types = new ArrayList<SmartPsiElementPointer<PsiClass>>();
for (PsiClass type : classes) {
types.add(SmartPointerManager.getInstance(type.getProject()).createSmartPsiElementPointer(type));
}
this.types = types;
this.originalNeeded = originalNeeded;
}
@@ -124,12 +126,13 @@ public class TooBroadThrowsInspection extends BaseInspection {
if (!originalNeeded) {
element.delete();
}
for (SmartPsiElementPointer<PsiClass> type : types) {
PsiClass aClass = type.getElement();
if (aClass == null) continue;
final PsiJavaCodeReferenceElement referenceElement =
factory.createReferenceExpression(aClass);
for (SmartTypePointer type : types) {
final PsiType psiType = type.getType();
if (psiType instanceof PsiClassType) {
final PsiJavaCodeReferenceElement referenceElement =
factory.createReferenceElementByType((PsiClassType)psiType);
referenceList.add(referenceElement);
}
}
}
}
@@ -172,14 +175,12 @@ public class TooBroadThrowsInspection extends BaseInspection {
continue;
}
}
final List<PsiClass> exceptionsMasked = new ArrayList<PsiClass>();
for (PsiClassType exceptionThrown : exceptionsThrown) {
final List<SmartTypePointer> exceptionsMasked = new ArrayList();
final SmartTypePointerManager pointerManager = SmartTypePointerManager.getInstance(body.getProject());
for (PsiClassType exceptionThrown : exceptionsThrown) {
if (referencedException.isAssignableFrom(exceptionThrown) &&
!exceptionsDeclared.contains(exceptionThrown)) {
PsiClass aClass = exceptionThrown.resolve();
if (aClass != null) {
exceptionsMasked.add(aClass);
}
exceptionsMasked.add(pointerManager.createSmartTypePointer(exceptionThrown));
}
}
if (!exceptionsMasked.isEmpty()) {
@@ -193,4 +194,4 @@ public class TooBroadThrowsInspection extends BaseInspection {
}
}
}
}
}
@@ -0,0 +1,5 @@
class Foo{
void foo() throws FileNotFoundException {
throw new FileNotFoundException();
}
}
@@ -0,0 +1,5 @@
class Foo{
void foo() throws IO<caret>Exception {
throw new FileNotFoundException();
}
}
@@ -0,0 +1,33 @@
/*
* 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.siyeh.ig.errorhandling;
import com.siyeh.InspectionGadgetsBundle;
import com.siyeh.ig.IGQuickFixesTestCase;
public class TooBroadThrowsInspectionTest extends IGQuickFixesTestCase {
@Override
public void setUp() throws Exception {
super.setUp();
myFixture.enableInspections(new TooBroadThrowsInspection());
myRelativePath = "toobroadthrows";
myDefaultHint = InspectionGadgetsBundle.message("overly.broad.throws.clause.quickfix2");
}
public void testNotFoundInsteadOfIOException() {
doTest();
}
}
+10 -2
View File
@@ -150,16 +150,24 @@ public class IdeaJdk extends SdkType implements JavaSdkType {
if (new File(sdkHome, "lib/rubymine.jar").exists()) {
productName = "RubyMine ";
}
else if (new File(sdkHome, "lib/pycharm.jar").exists()) {
productName = "PyCharm ";
}
else if (new File(sdkHome, "lib/webide.jar").exists()) {
productName = "WebStorm/PhpStorm ";
}
else if (new File(sdkHome, "lib/webide.jar").exists()) {
productName = "WebStorm/PhpStorm ";
}
else {
productName = "IDEA ";
}
String buildNumber = getBuildNumber(sdkHome);
return productName + (buildNumber != null ? buildNumber : "");
}
@Nullable
private static String getBuildNumber(String ideaHome) {
public static String getBuildNumber(String ideaHome) {
try {
@NonNls final String buildTxt = "/build.txt";
return FileUtil.loadFile(new File(ideaHome + buildTxt)).trim();
@@ -74,7 +74,7 @@ public class IdeaLicenseHelper {
return null;
}
public static void copyIDEALicencse(final String sandboxHome, Sdk jdk){
public static void copyIDEALicense(final String sandboxHome, Sdk jdk){
if (isIDEALicenseInSandbox(sandboxHome + File.separator + CONFIG_DIR_NAME, sandboxHome + File.separator + "system", jdk.getHomePath() + File.separator + "bin") == null){
final File ideaLicense = isIDEALicenseInSandbox(PathManager.getConfigPath(), PathManager.getSystemPath(), PathManager.getBinPath());
if (ideaLicense != null){
@@ -99,7 +99,7 @@ public class PluginRunConfiguration extends RunConfigurationBase implements Modu
final String canonicalSandbox = sandboxHome;
//copy license from running instance of idea
IdeaLicenseHelper.copyIDEALicencse(sandboxHome, ideaJdk);
IdeaLicenseHelper.copyIDEALicense(sandboxHome, ideaJdk);
final JavaCommandLineState state = new JavaCommandLineState(env) {
protected JavaParameters createJavaParameters() throws ExecutionException {
@@ -122,6 +122,28 @@ public class PluginRunConfiguration extends RunConfigurationBase implements Modu
vm.defineProperty("idea.smooth.progress", "false");
vm.defineProperty("apple.laf.useScreenMenuBar", "true");
}
String buildNumber = IdeaJdk.getBuildNumber(ideaJdk.getHomePath());
if (buildNumber != null) {
if (buildNumber.startsWith("IC")) {
vm.defineProperty("idea.platform.prefix", "Idea");
}
else if (buildNumber.startsWith("PY")) {
vm.defineProperty("idea.platform.prefix", "Python");
}
else if (buildNumber.startsWith("RM")) {
vm.defineProperty("idea.platform.prefix", "Ruby");
}
else if (buildNumber.startsWith("PS")) {
vm.defineProperty("idea.platform.prefix", "PhpStorm");
}
else if (buildNumber.startsWith("WS")) {
vm.defineProperty("idea.platform.prefix", "WebStorm");
}
else if (buildNumber.startsWith("OC")) {
vm.defineProperty("idea.platform.prefix", "CIDR");
}
}
params.setWorkingDirectory(ideaJdk.getHomePath() + File.separator + "bin" + File.separator);
@@ -222,7 +222,7 @@ public class GitPushActiveBranchesDialog extends DialogWrapper {
private GitPushActiveBranchesDialog myDialog;
public DialogInitTask(Project project, List<VirtualFile> vcsRoots, Collection<VcsException> exceptions) {
super(project, "Collection information for push", false);
super(project, "Collecting information for push", false);
myProject = project;
myVcsRoots = vcsRoots;
myExceptions = exceptions;
@@ -303,6 +303,9 @@ class GitRepositoryReader {
private GitBranchesCollection readPackedBranches() {
final Set<GitBranch> localBranches = new HashSet<GitBranch>();
final Set<GitBranch> remoteBranches = new HashSet<GitBranch>();
if (!myPackedRefsFile.exists()) {
return GitBranchesCollection.EMPTY;
}
final String content = tryLoadFile(myPackedRefsFile);
for (String line : content.split("\n")) {
@@ -354,6 +357,7 @@ class GitRepositoryReader {
throw new GitRepoStateException("Invalid format of the .git/HEAD file: \n" + headContent);
}
@NotNull
private static String tryLoadFile(final File file) {
return tryOrThrow(new Callable<String>() {
@Override
@@ -294,11 +294,9 @@ public class GitRootTracker implements VcsListener {
myNotification = new Notification(GIT_INVALID_ROOTS_ID, GitBundle.getString("root.tracker.message.title"),
GitBundle.getString("root.tracker.message"), NotificationType.ERROR,
new NotificationListener() {
public void hyperlinkUpdate(@NotNull Notification notification,
public void hyperlinkUpdate(@NotNull final Notification notification,
@NotNull HyperlinkEvent event) {
if (fixRoots()) {
notification.expire();
}
fixRoots(notification);
}
});
@@ -346,97 +344,113 @@ public class GitRootTracker implements VcsListener {
/**
* Fix mapped roots
*
* @return true if roots now in the correct state
* @param notification Expires the notification if roots are in the correct state after fix.
*/
boolean fixRoots() {
final List<VcsDirectoryMapping> vcsDirectoryMappings = new ArrayList<VcsDirectoryMapping>(myVcsManager.getDirectoryMappings());
final HashSet<String> mapped = new HashSet<String>();
final HashSet<String> removed = new HashSet<String>();
final HashSet<String> added = new HashSet<String>();
final VirtualFile baseDir = myProject.getBaseDir();
ApplicationManager.getApplication().runReadAction(new Runnable() {
public void run() {
for (Iterator<VcsDirectoryMapping> i = vcsDirectoryMappings.iterator(); i.hasNext();) {
VcsDirectoryMapping m = i.next();
String vcsName = myVcs.getName();
if (!vcsName.equals(m.getVcs())) {
continue;
}
String path = m.getDirectory();
if (path.length() == 0 && baseDir != null) {
path = baseDir.getPath();
}
VirtualFile file = lookupFile(path);
if (file != null && !mapped.add(file.getPath())) {
// eliminate duplicates
i.remove();
continue;
}
final VirtualFile actual = GitUtil.gitRootOrNull(file);
if (file == null || actual == null) {
removed.add(path);
}
else if (actual != file) {
removed.add(path);
added.add(actual.getPath());
}
}
for (String m : mapped) {
VirtualFile file = lookupFile(m);
if (file == null) {
continue;
}
addSubroots(file, added, mapped);
if (removed.contains(m)) {
continue;
}
VirtualFile root = GitUtil.gitRootOrNull(file);
assert root != null;
for (String o : mapped) {
// the mapped collection is not modified here, so order is being kept
if (o.equals(m) || removed.contains(o)) {
continue;
private void fixRoots(final Notification notification) {
ApplicationManager.getApplication().executeOnPooledThread(new Runnable() {
@Override public void run() {
final List<VcsDirectoryMapping> vcsDirectoryMappings = new ArrayList<VcsDirectoryMapping>(myVcsManager.getDirectoryMappings());
final HashSet<String> mapped = new HashSet<String>();
final HashSet<String> removed = new HashSet<String>();
final HashSet<String> added = new HashSet<String>();
collectRoots(vcsDirectoryMappings, mapped, removed, added);
final VirtualFile baseDir = myProject.getBaseDir();
ApplicationManager.getApplication().invokeLater(new Runnable() {
@Override public void run() {
if (added.isEmpty() && removed.isEmpty()) {
Messages.showInfoMessage(myProject, GitBundle.message("fix.roots.valid.message"), GitBundle.message("fix.roots.valid.title"));
notification.expire();
return;
}
if (o.startsWith(m)) {
VirtualFile otherFile = lookupFile(m);
assert otherFile != null;
VirtualFile otherRoot = GitUtil.gitRootOrNull(otherFile);
assert otherRoot != null;
if (otherRoot == root) {
removed.add(o);
}
else if (otherFile != otherRoot) {
added.add(otherRoot.getPath());
removed.add(o);
GitFixRootsDialog d = new GitFixRootsDialog(myProject, mapped, added, removed);
d.show();
if (!d.isOK()) {
return;
}
for (Iterator<VcsDirectoryMapping> i = vcsDirectoryMappings.iterator(); i.hasNext(); ) {
VcsDirectoryMapping m = i.next();
String path = m.getDirectory();
if (removed.contains(path) || (path.length() == 0 && baseDir != null && removed.contains(baseDir.getPath()))) {
i.remove();
}
}
for (String a : added) {
vcsDirectoryMappings.add(new VcsDirectoryMapping(a, myVcs.getName()));
}
myVcsManager.setDirectoryMappings(vcsDirectoryMappings);
myVcsManager.updateActiveVcss();
notification.expire();
}
}
});
}
});
if (added.isEmpty() && removed.isEmpty()) {
Messages.showInfoMessage(myProject, GitBundle.message("fix.roots.valid.message"), GitBundle.message("fix.roots.valid.title"));
return true;
}
GitFixRootsDialog d = new GitFixRootsDialog(myProject, mapped, added, removed);
d.show();
if (!d.isOK()) {
return false;
}
}
private void collectRoots(List<VcsDirectoryMapping> vcsDirectoryMappings,
HashSet<String> mapped,
HashSet<String> removed,
HashSet<String> added) {
final VirtualFile baseDir = myProject.getBaseDir();
for (Iterator<VcsDirectoryMapping> i = vcsDirectoryMappings.iterator(); i.hasNext();) {
VcsDirectoryMapping m = i.next();
String vcsName = myVcs.getName();
if (!vcsName.equals(m.getVcs())) {
continue;
}
String path = m.getDirectory();
if (removed.contains(path) || (path.length() == 0 && baseDir != null && removed.contains(baseDir.getPath()))) {
if (path.length() == 0 && baseDir != null) {
path = baseDir.getPath();
}
VirtualFile file = lookupFile(path);
if (file != null && !mapped.add(file.getPath())) {
// eliminate duplicates
i.remove();
continue;
}
final VirtualFile actual = GitUtil.gitRootOrNull(file);
if (file == null || actual == null) {
removed.add(path);
}
else if (actual != file) {
removed.add(path);
added.add(actual.getPath());
}
}
for (String a : added) {
vcsDirectoryMappings.add(new VcsDirectoryMapping(a, myVcs.getName()));
for (String m : mapped) {
VirtualFile file = lookupFile(m);
if (file == null) {
continue;
}
addSubroots(file, added, mapped);
if (removed.contains(m)) {
continue;
}
VirtualFile root = GitUtil.gitRootOrNull(file);
assert root != null;
for (String o : mapped) {
// the mapped collection is not modified here, so order is being kept
if (o.equals(m) || removed.contains(o)) {
continue;
}
if (o.startsWith(m)) {
VirtualFile otherFile = lookupFile(m);
assert otherFile != null;
VirtualFile otherRoot = GitUtil.gitRootOrNull(otherFile);
assert otherRoot != null;
if (otherRoot == root) {
removed.add(o);
}
else if (otherFile != otherRoot) {
added.add(otherRoot.getPath());
removed.add(o);
}
}
}
}
myVcsManager.setDirectoryMappings(vcsDirectoryMappings);
myVcsManager.updateActiveVcss();
return true;
}
/**
@@ -55,8 +55,7 @@ public class GithubOpenInBrowserAction extends DumbAwareAction {
final Project project = e.getData(PlatformDataKeys.PROJECT);
final VirtualFile virtualFile = e.getData(PlatformDataKeys.VIRTUAL_FILE);
if (StringUtil.isEmptyOrSpaces(GithubSettings.getInstance().getLogin()) ||
project == null || project.isDefault() || virtualFile == null ||
GithubUtil.getGithubBoundRepository(project) == null) {
project == null || project.isDefault() || virtualFile == null) {
e.getPresentation().setVisible(false);
e.getPresentation().setEnabled(false);
return;
@@ -264,8 +264,13 @@ public class GroovyCompletionContributor extends CompletionContributor {
result.addElement(LookupElementBuilder.create("if").setBold().setInsertHandler(new InsertHandler<LookupElement>() {
@Override
public void handleInsert(InsertionContext context, LookupElement item) {
TailTypes.IF_LPARENTH.processTail(context.getEditor(), context.getTailOffset());
}
if (context.getCompletionChar() != ' ') {
TailTypes.IF_LPARENTH.processTail(context.getEditor(), context.getTailOffset());
}
if (context.getCompletionChar() == '(') {
context.setAddCompletionChar(false);
}
}
}));
}
});
@@ -32,12 +32,14 @@ import org.jetbrains.plugins.groovy.lang.parser.GroovyElementTypes;
import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement;
import org.jetbrains.plugins.groovy.lang.psi.api.GroovyResolveResult;
import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.annotation.GrAnnotationNameValuePair;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrNewExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.toplevel.imports.GrImportStatement;
import org.jetbrains.plugins.groovy.lang.psi.api.types.GrCodeReferenceElement;
import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil;
import org.jetbrains.plugins.groovy.lang.psi.util.GroovyCommonClassNames;
import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil;
import java.util.Arrays;
@@ -91,15 +93,14 @@ public class GroovyInsertHandler implements InsertHandler<LookupElement> {
}
}
PsiDocumentManager docManager = PsiDocumentManager.getInstance(method.getProject());
docManager.commitDocument(document);
/*
//always use parentheses
context.commitDocument();
PsiFile psiFile = docManager.getPsiFile(document);
if (method.getParameterList().getParametersCount() > 0 && isExpressionStatement(psiFile, context.getStartOffset())) {
return;
}*/
if (context.getCompletionChar() == ' ') {
GrExpression expr = PsiTreeUtil.getParentOfType(context.getFile().findElementAt(context.getStartOffset()), GrExpression.class);
if (expr != null && PsiUtil.isExpressionStatement(expr)) {
return;
}
}
new MethodParenthesesHandler(method, true).handleInsert(context, item);
return;
@@ -24,12 +24,12 @@ import com.intellij.util.containers.hash.HashSet;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.plugins.groovy.lang.psi.GrReferenceElement;
import org.jetbrains.plugins.groovy.lang.psi.GroovyFileBase;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrField;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariable;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrAccessorMethod;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrEnumConstant;
import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.GrPropertyForCompletion;
import org.jetbrains.plugins.groovy.lang.psi.util.GroovyCommonClassNames;
import org.jetbrains.plugins.groovy.refactoring.GroovyRefactoringUtil;
import java.util.Set;
@@ -64,7 +64,7 @@ public class GrKindWeigher extends CompletionWeigher {
final GrReferenceElement parent = (GrReferenceElement)position.getParent();
if (parent.getQualifier() == null) {
if (o instanceof GrVariable && GroovyRefactoringUtil.isLocalVariable((GrVariable)o)) return NotQualifiedKind.aLocal;
if (o instanceof GrVariable && !(o instanceof GrField)) return NotQualifiedKind.aLocal;
if (o instanceof PsiClass) return NotQualifiedKind.aClass;
if (o instanceof PsiPackage) return NotQualifiedKind.aPackage;
if (isLightElement(o)) return NotQualifiedKind.anImplicitGroovyMethod;
@@ -1032,7 +1032,7 @@ public class PsiUtil {
return ((GrListOrMap)firstArg).getNamedArguments();
}
public static boolean isExpressionStatement(PsiElement expr) {
public static boolean isExpressionStatement(@NotNull PsiElement expr) {
final PsiElement parent = expr.getParent();
if (parent instanceof GrControlFlowOwner) return true;
if (parent instanceof GrExpression ||
@@ -71,6 +71,9 @@ class GrCompletionWithLibraryTest extends GroovyCompletionTestBase {
public void testEachMethodForRanges() throws Throwable {doBasicTest();}
public void testEachMethodForEnumRanges() throws Throwable {doBasicTest();}
public void testPrintlnSpace() { checkCompletion 'print<caret>', ' ', "print <caret>" }
public void testHashCodeSpace() { checkCompletion 'if ("".sub<caret>', ' ', 'if ("".subSequence() <caret>' }
public void testTwoMethodWithSameName() {
doVariantableTest "fooo", "fooo"
}
@@ -20,6 +20,7 @@ package org.jetbrains.plugins.groovy.completion;
import com.intellij.codeInsight.lookup.LookupElement
import org.jetbrains.plugins.groovy.GroovyFileType
import org.jetbrains.plugins.groovy.util.TestUtils
import com.intellij.codeInsight.CodeInsightSettings
/**
* @author Maxim.Medvedev
@@ -739,6 +740,10 @@ a.<caret>""")
checkSingleItemCompletion('def foo = "fo<caret>"', 'def foo = "foo<caret>"')
}
public void testIfSpace() { checkCompletion 'int iff; if<caret>', ' ', "int iff; if <caret>" }
public void testIfParenthesis() { checkCompletion 'int iff; if<caret>', '(', "int iff; if (<caret>)" }
public void testShowAccessor() {
assertNotNull doContainsTest("getFoo", """
class MyClass {
@@ -758,4 +763,18 @@ while(true) {
}""")
}
public void testPreferParametersToClasses() {
CodeInsightSettings.instance.COMPLETION_CASE_SENSITIVE = CodeInsightSettings.NONE
try {
myFixture.configureByText "a.groovy", "def foo(stryng) { println str<caret> }"
myFixture.completeBasic()
assert myFixture.lookupElementStrings[0] == 'stryng'
}
finally {
CodeInsightSettings.instance.COMPLETION_CASE_SENSITIVE = CodeInsightSettings.FIRST_LETTER
}
}
}
@@ -18,6 +18,7 @@ package com.intellij.uiDesigner.propertyInspector.editors;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.ui.TextFieldWithBrowseButton;
import com.intellij.ui.ListSpeedSearch;
import com.intellij.ui.ScrollPaneFactory;
import com.intellij.ui.components.JBList;
import com.intellij.uiDesigner.UIDesignerBundle;
@@ -234,10 +235,11 @@ public class ColorEditor extends PropertyEditor<ColorDescriptor> {
myDescriptorList.setCellRenderer(new ColorRenderer());
myDescriptorList.addListSelectionListener(new ListSelectionListener() {
public void valueChanged(ListSelectionEvent e) {
ColorDescriptor descriptor = (ColorDescriptor) myDescriptorList.getSelectedValue();
ColorDescriptor descriptor = (ColorDescriptor)myDescriptorList.getSelectedValue();
getColorSelectionModel().setSelectedColor(new ColorDescriptorWrapper(descriptor));
}
});
new ListSpeedSearch(myDescriptorList);
add(ScrollPaneFactory.createScrollPane(myDescriptorList), BorderLayout.CENTER);
}
@@ -230,7 +230,7 @@ orderEntry.fix.add.annotations.jar.to.classpath=Add 'annotations.jar' to classpa
static.import.method.text=Static Import Method
static.import.method.choose.method.to.import=Choose Method to Import
add.library.title.dialog=Adding library
add.library.title.dialog=Add Library to Project
add.library.title.locate.library=Locate library
add.library.description.locate.library=Locate library file which will be added as module library
add.library.title.choose.folder=Choose directory