Merge remote-tracking branch 'origin/master'

This commit is contained in:
Vladimir Orlov
2013-12-05 14:02:38 +04:00
31 changed files with 188 additions and 431 deletions
@@ -98,7 +98,7 @@ public class KnownElementWeigher extends ProximityWeigher {
}
private static boolean isPopularJdkClass(String qname) {
return qname.startsWith(CommonClassNames.JAVA_LANG_STRING) ||
return qname.equals(CommonClassNames.JAVA_LANG_STRING) ||
qname.equals(System.class.getName()) ||
qname.equals(CommonClassNames.JAVA_LANG_EXCEPTION) ||
qname.equals(CommonClassNames.JAVA_LANG_THROWABLE) ||
@@ -37,10 +37,7 @@ import com.intellij.openapi.editor.colors.EditorColorsManager;
import com.intellij.openapi.editor.markup.TextAttributes;
import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.Pass;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.util.*;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.wm.WindowManager;
@@ -414,6 +411,12 @@ public abstract class IntroduceVariableBase extends IntroduceHandlerBase {
final PsiExpression toBeExpression = createReplacement(fakeInitializer, project, prefix, suffix, parent, rangeMarker, refIdx);
toBeExpression.accept(errorsVisitor);
if (hasErrors[0]) return null;
if (literalExpression != null) {
PsiType type = toBeExpression.getType();
if (type != null && !type.equals(literalExpression.getType())) {
return null;
}
}
final PsiReferenceExpression refExpr = PsiTreeUtil.getParentOfType(toBeExpression.findElementAt(refIdx[0]), PsiReferenceExpression.class);
if (refExpr == null) return null;
@@ -0,0 +1,5 @@
class A {
public void test() {
int i = <selection>1</selection>23 + 123;
}
}
@@ -81,7 +81,7 @@ class JavaAutoPopupTest extends CompletionAutoPopupTestCase {
les = myFixture.lookupElementStrings
assert 'iterable' in les
assert 'iter' in les
assertEquals 'iterable', lookup.currentItem.lookupString
assertEquals 'iter', lookup.currentItem.lookupString
assert lookup.focused
type 'a'
@@ -116,7 +116,7 @@ class JavaAutoPopupTest extends CompletionAutoPopupTestCase {
}
""")
type "r"
myFixture.assertPreferredCompletionItems 1, "iter", "iterable"
myFixture.assertPreferredCompletionItems 0, "iter", "iterable"
type '\b'
assertContains "iterable"
@@ -131,7 +131,7 @@ class JavaAutoPopupTest extends CompletionAutoPopupTestCase {
assertContains "iterable"
type "r"
myFixture.assertPreferredCompletionItems 1, "iter", "iterable"
myFixture.assertPreferredCompletionItems 0, "iter", "iterable"
}
public void testExplicitSelectionShouldSurvive() {
@@ -1305,7 +1305,7 @@ class Foo {
type 'e'
myFixture.assertPreferredCompletionItems 0, 'itera', 'itex'
type 'r'
myFixture.assertPreferredCompletionItems 1, 'iter', 'itera'
myFixture.assertPreferredCompletionItems 0, 'iter', 'itera'
type '\b'
myFixture.assertPreferredCompletionItems 0, 'itera', 'itex'
}
@@ -1544,7 +1544,7 @@ class Foo {
}
'''
type 'tpl'
myFixture.assertPreferredCompletionItems 1, 'tpl', 'tplMn'
myFixture.assertPreferredCompletionItems 0, 'tpl', 'tplMn'
LookupElementPresentation p = LookupElementPresentation.renderElement(myFixture.lookupElements[0])
assert p.itemText == 'tpl'
@@ -617,7 +617,7 @@ interface TxANotAnno {}
}
public void testPreferString() {
checkPreferredItems 0, 'String', 'StringBuffer', 'StringBuilder', 'System', 'Set'
checkPreferredItems 0, 'String', 'System', 'Set'
}
}
@@ -30,7 +30,6 @@ import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.impl.DebugUtil;
import com.intellij.psi.impl.PsiDocumentManagerImpl;
import com.intellij.psi.impl.TextBlock;
import com.intellij.psi.impl.source.PsiFileImpl;
import com.intellij.testFramework.LeakHunter;
import com.intellij.testFramework.LightVirtualFile;
@@ -113,15 +112,14 @@ public class PsiDocumentManagerImplTest extends PlatformTestCase {
}
public void testGetUncommittedDocuments_documentChanged_DontProcessEvents() throws Exception {
PsiFile file = getPsiManager().findFile(createFile());
final PsiFile file = getPsiManager().findFile(createFile());
final Document document = getPsiDocumentManager().getDocument(file);
final TextBlock block = TextBlock.get(file);
WriteCommandAction.runWriteCommandAction(null, new Runnable() {
@Override
public void run() {
block.performAtomically(new Runnable() {
getPsiDocumentManager().getSynchronizer().performAtomically(file, new Runnable() {
@Override
public void run() {
getPsiDocumentManager().documentChanged(new DocumentEventImpl(document, 0, "", "", document.getModificationStamp(), false));
@@ -224,6 +224,18 @@ public class IntroduceVariableTest extends LightCodeInsightTestCase {
doTest(new MockIntroduceVariableHandler("str", false, false, false, "java.lang.String"));
}
public void testSubLiteralFailure() throws Exception {
try {
doTest(new MockIntroduceVariableHandler("str", false, false, false, "int"));
}
catch (Exception e) {
assertEquals(e.getMessage(), "Error message:Cannot perform refactoring.\n" +
"Selected block should represent an expression");
return;
}
fail("Should not be able to perform refactoring");
}
public void testSubLiteralFromExpression() throws Exception {
doTest(new MockIntroduceVariableHandler("str", false, false, false, "java.lang.String"));
}
@@ -603,7 +603,7 @@ public class DocumentImpl extends UserDataHolderBase implements DocumentEx {
if (!commandProcessor.isUndoTransparentActionInProgress() &&
commandProcessor.getCurrentCommand() == null &&
myAssertThreading) {
throw new IncorrectOperationException("Must not change document outside command or undo-transparent action.");
throw new IncorrectOperationException("Must not change document outside command or undo-transparent action. See com.intellij.openapi.command.WriteCommandAction or com.intellij.openapi.command.CommandProcessor");
}
}
@@ -261,12 +261,7 @@ public class PomModelImpl extends UserDataHolderBase implements PomModel {
FileElement fileElement = ((PsiFileImpl)file).getTreeElement();
if (fileElement != null) {
String oldText = fileElement.getText();
try {
reparseFile(file, newText, oldText);
}
finally {
TextBlock.get(file).clear();
}
reparseFile(file, newText, oldText);
}
}
}
@@ -104,7 +104,6 @@ public abstract class DocumentCommitProcessor {
final boolean synchronously) {
Document document = task.document;
if (PsiDocumentManager.getInstance(task.project).isCommitted(document)) return null;
final TextBlock textBlock = TextBlock.get(file);
final long startDocModificationTimeStamp = document.getModificationStamp();
final FileElement myTreeElementBeingReparsedSoItWontBeCollected = ((PsiFileImpl)file).calcTreeElement();
final CharSequence chars = document.getCharsSequence();
@@ -135,21 +134,16 @@ public abstract class DocumentCommitProcessor {
return false; // optimistic locking failed
}
try {
CodeStyleManager.getInstance(file.getProject()).performActionWithFormatterDisabled(new Runnable() {
@Override
public void run() {
synchronized (PsiLock.LOCK) {
doActualPsiChange(file, diffLog);
}
CodeStyleManager.getInstance(file.getProject()).performActionWithFormatterDisabled(new Runnable() {
@Override
public void run() {
synchronized (PsiLock.LOCK) {
doActualPsiChange(file, diffLog);
}
});
}
});
assertAfterCommit(document, file, oldPsiText, myTreeElementBeingReparsedSoItWontBeCollected);
}
finally {
textBlock.clear();
}
assertAfterCommit(document, file, oldPsiText, myTreeElementBeingReparsedSoItWontBeCollected);
return true;
}
@@ -589,7 +589,7 @@ public abstract class PsiDocumentManagerBase extends PsiDocumentManager implemen
}
mySmartPointerManager.fastenBelts(file, event.getOffset(), null);
if (TextBlock.get(file).isLocked()) {
if (mySynchronizer.isInsideAtomicChange(file)) {
psiCause = file;
}
}
@@ -617,13 +617,11 @@ public abstract class PsiDocumentManagerBase extends PsiDocumentManager implemen
for (PsiFile file : files) {
mySmartPointerManager.unfastenBelts(file, event.getOffset());
final TextBlock textBlock = TextBlock.get(file);
if (textBlock.isLocked()) {
if (mySynchronizer.isInsideAtomicChange(file)) {
commitNecessary = false;
continue;
}
textBlock.documentChanged(event);
assert file instanceof PsiFileImpl || "mock.file".equals(file.getName()) && ApplicationManager.getApplication().isUnitTestMode() :
event +
"; file=" +
@@ -22,6 +22,7 @@ import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.ex.DocumentEx;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.*;
@@ -35,6 +36,7 @@ import java.util.*;
public class PsiToDocumentSynchronizer extends PsiTreeChangeAdapter {
private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.PsiToDocumentSynchronizer");
private static final Key<Boolean> PSI_DOCUMENT_ATOMIC_ACTION = Key.create("PSI_DOCUMENT_ATOMIC_ACTION");
private final PsiDocumentManagerBase myPsiDocumentManager;
private final MessageBus myBus;
@@ -78,13 +80,11 @@ public class PsiToDocumentSynchronizer extends PsiTreeChangeAdapter {
return;
}
TextBlock textBlock = TextBlock.get(psiFile);
if (!textBlock.isEmpty()) {
if (myPsiDocumentManager.isUncommited(document)) {
throw new IllegalStateException("Attempt to modify PSI for non-committed Document!");
}
textBlock.performAtomically(new Runnable() {
performAtomically(psiFile, new Runnable() {
@Override
public void run() {
syncAction.syncDocument(document, (PsiTreeChangeEventImpl)event);
@@ -102,6 +102,22 @@ public class PsiToDocumentSynchronizer extends PsiTreeChangeAdapter {
psiFile.getViewProvider().contentsSynchronized();
}
boolean isInsideAtomicChange(@NotNull PsiFile file) {
return file.getUserData(PSI_DOCUMENT_ATOMIC_ACTION) == Boolean.TRUE;
}
public void performAtomically(@NotNull PsiFile file, @NotNull Runnable runnable) {
assert !isInsideAtomicChange(file);
file.putUserData(PSI_DOCUMENT_ATOMIC_ACTION, Boolean.TRUE);
try {
runnable.run();
}
finally {
file.putUserData(PSI_DOCUMENT_ATOMIC_ACTION, null);
}
}
@Override
public void childAdded(@NotNull final PsiTreeChangeEvent event) {
if (!(event.getChild() instanceof ForeignLeafPsiElement)) {
@@ -1,124 +0,0 @@
/*
* Copyright 2000-2009 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.impl;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.event.DocumentEvent;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.UserDataHolderEx;
import com.intellij.psi.PsiFile;
import org.jetbrains.annotations.NotNull;
public class TextBlock {
private static final Key<TextBlock> KEY_TEXT_BLOCK = Key.create("KEY_TEXT_BLOCK");
@SuppressWarnings({"UnusedDeclaration"})
private Document myDocument; // Will hold a document on a hard reference until there's uncommitted PSI for this document.
private int myStartOffset = -1;
private int myTextEndOffset = -1;
private int myPsiEndOffset = -1;
private boolean myIsLocked = false;
public boolean isEmpty() {
return myStartOffset == -1;
}
public void clear() {
myStartOffset = -1;
myDocument = null;
}
public int getStartOffset() {
return myStartOffset;
}
public int getTextEndOffset() {
return myTextEndOffset;
}
private void lock() {
myIsLocked = true;
}
private void unlock() {
myIsLocked = false;
}
public boolean isLocked() {
return myIsLocked;
}
public int getPsiEndOffset() {
return myPsiEndOffset;
}
public void documentChanged(DocumentEvent e) {
myDocument = e.getDocument();
assert !myIsLocked;
final int offset = e.getOffset();
if (isEmpty()) {
myStartOffset = offset;
myTextEndOffset = offset + e.getNewLength();
myPsiEndOffset = offset + e.getOldLength();
}
else {
int shift = offset + e.getOldLength() - myTextEndOffset;
if (shift > 0) {
myPsiEndOffset += shift;
myTextEndOffset = offset + e.getNewLength();
}
else {
myTextEndOffset += e.getNewLength() - e.getOldLength();
}
myStartOffset = Math.min(myStartOffset, offset);
}
}
public void performAtomically(@NotNull Runnable runnable) {
assert !isLocked();
lock();
try {
runnable.run();
}
finally {
unlock();
}
}
@NotNull
public static TextBlock get(@NotNull PsiFile file) {
TextBlock textBlock = file.getUserData(KEY_TEXT_BLOCK);
if (textBlock == null){
textBlock = ((UserDataHolderEx)file).putUserDataIfAbsent(KEY_TEXT_BLOCK, new TextBlock());
}
return textBlock;
}
@Override
public String toString() {
return "TextBlock{" +
"myStartOffset=" + myStartOffset +
", myTextEndOffset=" + myTextEndOffset +
", myPsiEndOffset=" + myPsiEndOffset +
", myIsLocked=" + myIsLocked +
'}';
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
* Copyright 2000-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -31,13 +31,11 @@ import com.intellij.openapi.fileTypes.FileTypeManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ProjectManager;
import com.intellij.openapi.roots.ProjectRootManager;
import com.intellij.openapi.util.Clock;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.*;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.*;
import com.intellij.openapi.vfs.encoding.EncodingRegistry;
import com.intellij.openapi.vfs.ex.temp.TempFileSystem;
import com.intellij.openapi.vfs.newvfs.ManagingFS;
import com.intellij.openapi.vfs.newvfs.NewVirtualFile;
import com.intellij.util.NullableFunction;
@@ -151,16 +149,27 @@ public class IdeaGateway {
public RootEntry createTransientRootEntry() {
ApplicationManager.getApplication().assertReadAccessAllowed();
RootEntry root = new RootEntry();
doCreateChildren(root, Arrays.asList(ManagingFS.getInstance().getLocalRoots()), false);
doCreateChildren(root, getLocalRoots(), false);
return root;
}
@NotNull
public RootEntry createTransientRootEntryForPathOnly(@NotNull String path) {
ApplicationManager.getApplication().assertReadAccessAllowed();
RootEntry root = new RootEntry();
doCreateChildrenForPathOnly(root, path, Arrays.asList(ManagingFS.getInstance().getLocalRoots()));
doCreateChildrenForPathOnly(root, path, getLocalRoots());
return root;
}
private static List<VirtualFile> getLocalRoots() {
return ContainerUtil.filter(ManagingFS.getInstance().getLocalRoots(), new Condition<VirtualFile>() {
@Override
public boolean value(VirtualFile file) {
return !(file.getFileSystem() instanceof TempFileSystem);
}
});
}
private void doCreateChildrenForPathOnly(@NotNull DirectoryEntry parent,
@NotNull String path,
@NotNull Collection<VirtualFile> children) {
@@ -218,7 +218,7 @@ ide.mac.fix.accessibleLeak=true
projectView.showHierarchyErrors=true
projectView.hide.dot.idea=true
show.live.templates.in.completion=false
ide.completion.autopopup.select.live.templates=false
ide.completion.autopopup.select.live.templates=true
documentation.component.editor.font=false
ide.completion.show.better.matching.classes=true
@@ -1,193 +0,0 @@
package com.intellij.psi;
import com.intellij.mock.MockDocument;
import com.intellij.openapi.editor.impl.event.DocumentEventImpl;
import com.intellij.psi.impl.TextBlock;
import junit.framework.TestCase;
public class TextBlockTest extends TestCase {
private TextBlock myTextBlock;
private MockDocument myDocument;
@Override
protected void setUp() throws Exception {
super.setUp();
myDocument = new MockDocument();
myTextBlock = new TextBlock();
}
public void testIsEmpty_AfterCreate() throws Exception {
assertTrue(myTextBlock.isEmpty());
}
public void testTextInserted_Once() throws Exception {
myTextBlock.documentChanged(new DocumentEventImpl(myDocument, 10, "", "xxx", 1, false));
assertTrue(!myTextBlock.isEmpty());
assertEquals(10, myTextBlock.getStartOffset());
assertEquals(13, myTextBlock.getTextEndOffset());
assertEquals(10, myTextBlock.getPsiEndOffset());
}
public void testReset() throws Exception {
assertTrue(myTextBlock.isEmpty());
myTextBlock.documentChanged(new DocumentEventImpl(myDocument, 10, "", "xxx", 1, false));
assertTrue(!myTextBlock.isEmpty());
myTextBlock.clear();
assertTrue(myTextBlock.isEmpty());
}
public void testTextInserted_SecondNonAdjFragmentsAfter() throws Exception {
myTextBlock.documentChanged(new DocumentEventImpl(myDocument, 10, "", "xxx", 1, false));
myTextBlock.documentChanged(new DocumentEventImpl(myDocument, 20, "", "xxx", 1, false));
assertTrue(!myTextBlock.isEmpty());
assertEquals(10, myTextBlock.getStartOffset());
assertEquals(23, myTextBlock.getTextEndOffset());
assertEquals(17, myTextBlock.getPsiEndOffset());
}
public void testTextInserted_SecondNonAdjFragmentsBefore() throws Exception {
myTextBlock.documentChanged(new DocumentEventImpl(myDocument, 10, "", "xxx", 1, false));
myTextBlock.documentChanged(new DocumentEventImpl(myDocument, 5, "", "xxx", 1, false));
assertTrue(!myTextBlock.isEmpty());
assertEquals(5, myTextBlock.getStartOffset());
assertEquals(16, myTextBlock.getTextEndOffset());
assertEquals(10, myTextBlock.getPsiEndOffset());
}
public void testTextInserted_SecondAdjFragmentsAfter() throws Exception {
myTextBlock.documentChanged(new DocumentEventImpl(myDocument, 10, "", "xxx", 1, false));
myTextBlock.documentChanged(new DocumentEventImpl(myDocument, 13, "", "xxx", 1, false));
assertTrue(!myTextBlock.isEmpty());
assertEquals(10, myTextBlock.getStartOffset());
assertEquals(16, myTextBlock.getTextEndOffset());
assertEquals(10, myTextBlock.getPsiEndOffset());
}
public void testTextInserted_SecondAdjFragmentsBefore() throws Exception {
myTextBlock.documentChanged(new DocumentEventImpl(myDocument, 10, "", "xxx", 1, false));
myTextBlock.documentChanged(new DocumentEventImpl(myDocument, 10, "", "xxx", 1, false));
assertTrue(!myTextBlock.isEmpty());
assertEquals(10, myTextBlock.getStartOffset());
assertEquals(16, myTextBlock.getTextEndOffset());
assertEquals(10, myTextBlock.getPsiEndOffset());
}
public void testTextDeleted_Once() throws Exception {
myTextBlock.documentChanged(new DocumentEventImpl(myDocument, 10, "xxx", "", 1, false));
assertTrue(!myTextBlock.isEmpty());
assertEquals(10, myTextBlock.getStartOffset());
assertEquals(10, myTextBlock.getTextEndOffset());
assertEquals(13, myTextBlock.getPsiEndOffset());
}
public void testTextDeleted_SecondNonAdjFragmentAfter() throws Exception {
myTextBlock.documentChanged(new DocumentEventImpl(myDocument, 10, "xxx", "", 1, false));
myTextBlock.documentChanged(new DocumentEventImpl(myDocument, 17, "xxx", "", 1, false));
assertTrue(!myTextBlock.isEmpty());
assertEquals(10, myTextBlock.getStartOffset());
assertEquals(17, myTextBlock.getTextEndOffset());
assertEquals(23, myTextBlock.getPsiEndOffset());
}
public void testTextDeleted_SecondNonAdjFragmentBefore() throws Exception {
myTextBlock.documentChanged(new DocumentEventImpl(myDocument, 10, "xxx", "", 1, false));
myTextBlock.documentChanged(new DocumentEventImpl(myDocument, 5, "xxx", "", 1, false));
assertTrue(!myTextBlock.isEmpty());
assertEquals(5, myTextBlock.getStartOffset());
assertEquals(7, myTextBlock.getTextEndOffset());
assertEquals(13, myTextBlock.getPsiEndOffset());
}
public void testTextDeleted_SecondAdjFragment() throws Exception {
myTextBlock.documentChanged(new DocumentEventImpl(myDocument, 10, "xxx", "", 1, false));
myTextBlock.documentChanged(new DocumentEventImpl(myDocument, 10, "xxx", "", 1, false));
assertTrue(!myTextBlock.isEmpty());
assertEquals(10, myTextBlock.getStartOffset());
assertEquals(10, myTextBlock.getTextEndOffset());
assertEquals(16, myTextBlock.getPsiEndOffset());
}
public void testTextChanged_ChangedToTheSameSize_Once1() throws Exception {
myTextBlock.documentChanged(new DocumentEventImpl(myDocument, 10, "xxx", "xxx", 1, false));
assertTrue(!myTextBlock.isEmpty());
assertEquals(10, myTextBlock.getStartOffset());
assertEquals(13, myTextBlock.getTextEndOffset());
assertEquals(13, myTextBlock.getPsiEndOffset());
}
public void testTextChanged_ChangedToTheSameSize_Once2() throws Exception {
myTextBlock.documentChanged(new DocumentEventImpl(myDocument, 0, "xxx", "yyy", 1, false));
assertTrue(!myTextBlock.isEmpty());
assertEquals(0, myTextBlock.getStartOffset());
assertEquals(3, myTextBlock.getTextEndOffset());
assertEquals(3, myTextBlock.getPsiEndOffset());
}
public void testTextChanged_ChangedToTheSameSize_SecondNonAdjFragmentAfter() throws Exception {
myTextBlock.documentChanged(new DocumentEventImpl(myDocument, 10, "xxx", "xxx", 1, false));
myTextBlock.documentChanged(new DocumentEventImpl(myDocument, 20, "xxx", "xxx", 1, false));
assertTrue(!myTextBlock.isEmpty());
assertEquals(10, myTextBlock.getStartOffset());
assertEquals(23, myTextBlock.getTextEndOffset());
assertEquals(23, myTextBlock.getPsiEndOffset());
}
public void testTextChanged_ChangedToTheSameSize_SecondNonAdjFragmentBefore() throws Exception {
myTextBlock.documentChanged(new DocumentEventImpl(myDocument, 10, "xxx", "xxx", 1, false));
myTextBlock.documentChanged(new DocumentEventImpl(myDocument, 5, "xxx", "xxx", 1, false));
assertTrue(!myTextBlock.isEmpty());
assertEquals(5, myTextBlock.getStartOffset());
assertEquals(13, myTextBlock.getTextEndOffset());
assertEquals(13, myTextBlock.getPsiEndOffset());
}
public void testTextChanged_ChangedToTheSameSize_SecondNonFragmentAfter() throws Exception {
myTextBlock.documentChanged(new DocumentEventImpl(myDocument, 10, "xxx", "xxx", 1, false));
myTextBlock.documentChanged(new DocumentEventImpl(myDocument, 13, "xxx", "xxx", 1, false));
assertTrue(!myTextBlock.isEmpty());
assertEquals(10, myTextBlock.getStartOffset());
assertEquals(16, myTextBlock.getTextEndOffset());
assertEquals(16, myTextBlock.getPsiEndOffset());
}
public void testTextChanged_ChangedToTheSameSize_SecondNonFragmentBefore() throws Exception {
myTextBlock.documentChanged(new DocumentEventImpl(myDocument, 10, "xxx", "xxx", 1, false));
myTextBlock.documentChanged(new DocumentEventImpl(myDocument, 7, "xxx", "xxx", 1, false));
assertTrue(!myTextBlock.isEmpty());
assertEquals(7, myTextBlock.getStartOffset());
assertEquals(13, myTextBlock.getTextEndOffset());
assertEquals(13, myTextBlock.getPsiEndOffset());
}
public void testTextChanged_ChangedToLessSize() throws Exception {
myTextBlock.documentChanged(new DocumentEventImpl(myDocument, 10, "xxx", "xx", 1, false));
assertTrue(!myTextBlock.isEmpty());
assertEquals(10, myTextBlock.getStartOffset());
assertEquals(12, myTextBlock.getTextEndOffset());
assertEquals(13, myTextBlock.getPsiEndOffset());
}
public void testTextChanged_ChangedToGreaterSize() throws Exception {
myTextBlock.documentChanged(new DocumentEventImpl(myDocument, 10, "xxx", "xxxx", 1, false));
assertTrue(!myTextBlock.isEmpty());
assertEquals(10, myTextBlock.getStartOffset());
assertEquals(14, myTextBlock.getTextEndOffset());
assertEquals(13, myTextBlock.getPsiEndOffset());
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2012 JetBrains s.r.o.
* Copyright 2000-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,11 +17,11 @@ package com.intellij.testFramework.vcs;
import com.intellij.execution.process.CapturingProcessHandler;
import com.intellij.execution.process.ProcessOutput;
import com.intellij.openapi.diagnostic.LogUtil;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.CharsetToolkit;
import com.intellij.util.EnvironmentUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -107,10 +107,11 @@ public class TestClientRunner {
}
if (result.isTimeout()) {
String processList = EnvironmentUtil.getProcessList();
String processList = LogUtil.getProcessList();
handler.destroyProcess();
throw new RuntimeException("Timeout waiting for VCS client to finish execution:\n" + processList);
}
return result;
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2012 JetBrains s.r.o.
* Copyright 2000-2013 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.
@@ -15,9 +15,14 @@
*/
package com.intellij.openapi.diagnostic;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.util.ExceptionUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.IOException;
public class LogUtil {
private LogUtil() { }
@@ -33,4 +38,17 @@ public class LogUtil {
logger.debug(String.format(format, args));
}
}
public static String getProcessList() {
try {
@SuppressWarnings("SpellCheckingInspection") Process process = new ProcessBuilder()
.command(SystemInfo.isWindows ? new String[]{System.getenv("windir") + "\\system32\\tasklist.exe", "/v"} : new String[]{"ps", "a"})
.redirectErrorStream(true)
.start();
return FileUtil.loadTextAndClose(process.getInputStream());
}
catch (IOException e) {
return ExceptionUtil.getThrowableText(e);
}
}
}
@@ -22,7 +22,6 @@ import com.intellij.openapi.util.AtomicNotNullLazyValue;
import com.intellij.openapi.util.NotNullLazyValue;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.io.StreamUtil;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.concurrency.FixedFuture;
@@ -33,7 +32,6 @@ import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.TestOnly;
import java.io.File;
import java.io.IOException;
import java.util.*;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
@@ -198,17 +196,6 @@ public class EnvironmentUtil {
return Collections.unmodifiableMap(newEnv);
}
public static String getProcessList() {
String diagnostics;
try {
Process p = Runtime.getRuntime().exec(SystemInfo.isWindows ? System.getenv("windir") +"\\system32\\tasklist.exe /v" : "ps a");
diagnostics = StreamUtil.readText(p.getInputStream());
}
catch (IOException e) {
diagnostics = ExceptionUtil.getThrowableText(e);
}
return diagnostics;
}
private static class ProcessKiller {
private final Process myProcess;
@@ -353,7 +353,7 @@ string.concatenation.ignore.exceptions.option=Ignore for throwable arguments
string.concatenation.ignore.constant.initializers.option=Ignore for initializers of constants
ignore.in.annotations=Ignore in annotations
ignore.in.tostring=Ignore inside toString() methods
ignore.as.initial.capacity=Ignore initial capacity argument when constructing StringBuilders and Collections
ignore.as.initial.capacity=Ignore initial capacity for StringBuilders and Collections
string.equalsignorecase.call.display.name=Call to 'String.equalsIgnoreCase()'
string.equalsignorecase.call.problem.descriptor=<code>String.#ref()</code> using internationalized strings #loc
string.equals.call.display.name=Call to 'String.equals()'
@@ -72,7 +72,7 @@ public class MagicNumberInspectionBase extends BaseInspection {
if (!ClassUtils.isPrimitiveNumericType(type) || PsiType.CHAR.equals(type)) {
return;
}
if (isSpecialCaseLiteral(expression) || ExpressionUtils.isDeclaredConstant(expression)) {
if (isSpecialCaseLiteral(expression) || isFinalVariableInitialization(expression)) {
return;
}
if (ignoreInHashCode) {
@@ -87,18 +87,8 @@ public class MagicNumberInspectionBase extends BaseInspection {
return;
}
}
if (ignoreInitialCapacity) {
final PsiExpressionList expressionList = PsiTreeUtil.getParentOfType(expression, PsiExpressionList.class, true, PsiMember.class);
if (expressionList != null) {
final PsiElement parent = expressionList.getParent();
if (parent instanceof PsiNewExpression) {
final PsiNewExpression newExpression = (PsiNewExpression)parent;
if (TypeUtils.expressionHasTypeOrSubtype(newExpression, CommonClassNames.JAVA_LANG_ABSTRACT_STRING_BUILDER,
CommonClassNames.JAVA_UTIL_MAP, CommonClassNames.JAVA_UTIL_COLLECTION) != null) {
return;
}
}
}
if (ignoreInitialCapacity && isInitialCapacity(expression)) {
return;
}
final PsiElement parent = expression.getParent();
if (parent instanceof PsiPrefixExpression) {
@@ -109,6 +99,21 @@ public class MagicNumberInspectionBase extends BaseInspection {
}
}
private boolean isInitialCapacity(PsiLiteralExpression expression) {
final PsiElement element =
PsiTreeUtil.skipParentsOfType(expression, PsiTypeCastExpression.class, PsiParenthesizedExpression.class, PsiPrefixExpression.class);
if (!(element instanceof PsiExpressionList)) {
return false;
}
final PsiElement parent = element.getParent();
if (!(parent instanceof PsiNewExpression)) {
return false;
}
final PsiNewExpression newExpression = (PsiNewExpression)parent;
return TypeUtils.expressionHasTypeOrSubtype(newExpression, CommonClassNames.JAVA_LANG_ABSTRACT_STRING_BUILDER,
CommonClassNames.JAVA_UTIL_MAP, CommonClassNames.JAVA_UTIL_COLLECTION) != null;
}
private boolean isSpecialCaseLiteral(PsiLiteralExpression expression) {
final Object object = ExpressionUtils.computeConstantExpression(expression);
if (object instanceof Integer) {
@@ -129,5 +134,31 @@ public class MagicNumberInspectionBase extends BaseInspection {
}
return false;
}
public boolean isFinalVariableInitialization(PsiExpression expression) {
final PsiElement parent =
PsiTreeUtil.skipParentsOfType(expression, PsiTypeCastExpression.class, PsiParenthesizedExpression.class, PsiPrefixExpression.class);
final PsiVariable variable;
if (!(parent instanceof PsiVariable)) {
if (!(parent instanceof PsiAssignmentExpression)) {
return false;
}
final PsiAssignmentExpression assignmentExpression = (PsiAssignmentExpression)parent;
final PsiExpression lhs = assignmentExpression.getLExpression();
if (!(lhs instanceof PsiReferenceExpression)) {
return false;
}
final PsiReferenceExpression referenceExpression = (PsiReferenceExpression)lhs;
final PsiElement target = referenceExpression.resolve();
if (!(target instanceof PsiVariable)) {
return false;
}
variable = (PsiVariable)target;
}
else {
variable = (PsiVariable)parent;
}
return variable.hasModifierProperty(PsiModifier.FINAL);
}
}
}
@@ -60,7 +60,8 @@ public class NoopMethodInAbstractClassInspection extends BaseInspection {
if (!containingClass.hasModifierProperty(PsiModifier.ABSTRACT)) {
return;
}
if (method.hasModifierProperty(PsiModifier.ABSTRACT) || method.hasModifierProperty(PsiModifier.NATIVE)) {
if (method.hasModifierProperty(PsiModifier.ABSTRACT) || method.hasModifierProperty(PsiModifier.NATIVE) ||
method.hasModifierProperty(PsiModifier.FINAL)) {
return;
}
if (!MethodUtils.isEmpty(method)) {
@@ -1,20 +1,20 @@
package com.siyeh.igtest.abstraction.magic_number;
import java.util.Set;
import java.util.HashSet;
import java.util.List;
import java.util.ArrayList;
@Size(max = 15)
public class MagicNumber
{
private static final int s_foo = 400;
private int m_foo = 400;
private int m_foo = -400;
private static int s_foo2 = 400;
private final int m_foo2 = 400;
private static final Set s_set = new HashSet(400);
private final int m_foo2 = -(-(400));
private static final List s_set = new ArrayList(400);
public static void main(String[] args)
{
final Set set = new HashSet(400);
final List set = new ArrayList(400);
set.toString();
}
@@ -36,6 +36,10 @@ public class MagicNumber
result = 29 * result + m_foo2;
return result;
}
void foo() {
final int value = 101 * 55;
}
}
@interface Size {
int max();
@@ -4,21 +4,7 @@
<file>MagicNumber.java</file>
<line>10</line>
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">&quot;Magic number&quot;</problem_class>
<description>Magic number &lt;code&gt;400&lt;/code&gt; #loc</description>
</problem>
<problem>
<file>MagicNumber.java</file>
<line>17</line>
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">&quot;Magic number&quot;</problem_class>
<description>Magic number &lt;code&gt;400&lt;/code&gt; #loc</description>
</problem>
<problem>
<file>MagicNumber.java</file>
<line>12</line>
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">&quot;Magic number&quot;</problem_class>
<description>Magic number &lt;code&gt;400&lt;/code&gt; #loc</description>
<description>Magic number &lt;code&gt;-400&lt;/code&gt; #loc</description>
</problem>
<problem>
@@ -27,4 +13,18 @@
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">&quot;Magic number&quot;</problem_class>
<description>Magic number &lt;code&gt;400&lt;/code&gt; #loc</description>
</problem>
<problem>
<file>MagicNumber.java</file>
<line>41</line>
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Magic number</problem_class>
<description>Magic number &lt;code&gt;101&lt;/code&gt; #loc</description>
</problem>
<problem>
<file>MagicNumber.java</file>
<line>41</line>
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Magic number</problem_class>
<description>Magic number &lt;code&gt;55&lt;/code&gt; #loc</description>
</problem>
</problems>
@@ -5,4 +5,6 @@ abstract class NoopMethodInAbstractClass {
void foo() {}
native int bar();
final void noop() {}
}
@@ -8,6 +8,7 @@ public class MagicNumberInspectionTest extends IGInspectionTestCase {
final MagicNumberInspection tool = new MagicNumberInspection();
tool.ignoreInHashCode = true;
tool.ignoreInAnnotations = true;
tool.ignoreInitialCapacity = true;
doTest("com/siyeh/igtest/abstraction/magic_number", tool);
}
}
@@ -36,7 +36,7 @@ public class DataProviderSearcher extends QueryExecutorBase<PsiReference, Method
final PsiAnnotation annotation = AnnotationUtil.findAnnotation(method, DataProvider.class.getName());
if (annotation == null) return;
final PsiAnnotationMemberValue dataProviderMethodName = annotation.findAttributeValue("name");
final PsiAnnotationMemberValue dataProviderMethodName = annotation.findDeclaredAttributeValue("name");
if (dataProviderMethodName != null) {
final String providerName = StringUtil.unquoteString(dataProviderMethodName.getText());
queryParameters.getOptimizer().searchWord(providerName, queryParameters.getScope(), UsageSearchContext.IN_STRINGS, true, method);
@@ -98,7 +98,7 @@ public class TestNGReferenceContributor extends PsiReferenceContributor {
for (PsiMethod method : methods) {
PsiAnnotation dataProviderAnnotation = AnnotationUtil.findAnnotation(method, DataProvider.class.getName());
if (dataProviderAnnotation != null) {
final PsiAnnotationMemberValue dataProviderMethodName = dataProviderAnnotation.findAttributeValue("name");
final PsiAnnotationMemberValue dataProviderMethodName = dataProviderAnnotation.findDeclaredAttributeValue("name");
if (dataProviderMethodName != null && val.equals(StringUtil.unquoteString(dataProviderMethodName.getText()))) {
return method;
}
@@ -129,8 +129,7 @@ public class TestNGReferenceContributor extends PsiReferenceContributor {
}
final PsiAnnotation dataProviderAnnotation = AnnotationUtil.findAnnotation(method, DataProvider.class.getName());
if (dataProviderAnnotation != null) {
boolean nameFoundInAttributes = false;
final PsiAnnotationMemberValue memberValue = dataProviderAnnotation.findAttributeValue("name");
final PsiAnnotationMemberValue memberValue = dataProviderAnnotation.findDeclaredAttributeValue("name");
if (memberValue != null) {
list.add(LookupValueFactory.createLookupValue(StringUtil.unquoteString(memberValue.getText()), null));
list.add(LookupValueFactory.createLookupValue(method.getName(), null));
@@ -144,7 +143,7 @@ public class TestNGReferenceContributor extends PsiReferenceContributor {
private PsiClass getProviderClass(final PsiClass topLevelClass) {
final PsiAnnotation annotation = PsiTreeUtil.getParentOfType(getElement(), PsiAnnotation.class);
if (annotation != null) {
final PsiAnnotationMemberValue value = annotation.findAttributeValue("dataProviderClass");
final PsiAnnotationMemberValue value = annotation.findDeclaredAttributeValue("dataProviderClass");
if (value instanceof PsiClassObjectAccessExpression) {
final PsiTypeElement operand = ((PsiClassObjectAccessExpression)value).getOperand();
final PsiClass psiClass = PsiUtil.resolveClassInType(operand.getType());
@@ -72,7 +72,7 @@ public class DependsOnMethodInspection extends BaseJavaLocalInspectionTool
List<ProblemDescriptor> problemDescriptors = new ArrayList<ProblemDescriptor>();
for (PsiAnnotation annotation : annotations) {
final PsiAnnotationMemberValue value = annotation.findAttributeValue("dependsOnMethods");
final PsiAnnotationMemberValue value = annotation.findDeclaredAttributeValue("dependsOnMethods");
if (value != null) {
String text = value.getText();
if (value instanceof PsiReferenceExpression) {
@@ -55,7 +55,7 @@ public class ExpectedExceptionNeverThrownTestNGInspection extends BaseJavaLocalI
if (annotation == null) {
return;
}
final PsiAnnotationMemberValue value = annotation.findAttributeValue("expectedExceptions");
final PsiAnnotationMemberValue value = annotation.findDeclaredAttributeValue("expectedExceptions");
if (!(value instanceof PsiClassObjectAccessExpression)) {
return;
}
@@ -314,7 +314,7 @@ public class TestNGUtil
}
public static boolean isAnnotatedWithParameter(PsiAnnotation annotation, String parameter, Set<String> values) {
final PsiAnnotationMemberValue attributeValue = annotation.findAttributeValue(parameter);
final PsiAnnotationMemberValue attributeValue = annotation.findDeclaredAttributeValue(parameter);
if (attributeValue != null) {
Collection<String> matches = extractValuesFromParameter(attributeValue);
for (String s : matches) {
@@ -374,7 +374,7 @@ public class TestNGUtil
final PsiAnnotation annotation,
final PsiDocCommentOwner commentOwner) {
if (annotation != null) {
final PsiAnnotationMemberValue value = annotation.findAttributeValue(parameter);
final PsiAnnotationMemberValue value = annotation.findDeclaredAttributeValue(parameter);
if (value != null) {
results.addAll(extractValuesFromParameter(value));
}