Merge remote-tracking branch 'origin/master'

This commit is contained in:
Dmitry Batkovich
2015-10-22 14:50:43 +03:00
20 changed files with 228 additions and 229 deletions
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
* Copyright 2000-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -27,16 +27,16 @@ import org.jetbrains.annotations.Nullable;
import java.util.List;
class ConvertReturnStatementsVisitor implements ReturnStatementsVisitor {
private final PsiElementFactory myFactory;
private final PsiMethod myMethod;
private final DeclarationSearcher mySearcher;
@NotNull private final PsiElementFactory myFactory;
@NotNull private final PsiMethod myMethod;
@NotNull private final DeclarationSearcher mySearcher;
@NotNull private final String myDefaultValue;
private PsiReturnStatement myLatestReturn;
private final String myDefaultValue;
public ConvertReturnStatementsVisitor(final PsiElementFactory factory, final PsiMethod method, final PsiType targetType) {
ConvertReturnStatementsVisitor(@NotNull PsiElementFactory factory, @NotNull PsiMethod method, @NotNull PsiType targetType) {
myFactory = factory;
myMethod = method;
mySearcher = new DeclarationSearcher(myMethod, targetType);
mySearcher = new DeclarationSearcher(method, targetType);
myDefaultValue = PsiTypesUtil.getDefaultValueOfType(targetType);
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
* Copyright 2000-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -22,17 +22,15 @@ import org.jetbrains.annotations.Nullable;
import java.util.HashMap;
import java.util.Map;
public class DeclarationSearcher {
class DeclarationSearcher {
private final PsiMethod myMethod;
private final PsiType myTargetType;
private final Map<PsiElement, PsiVariable> cache;
private final Map<PsiElement, PsiVariable> cache = new HashMap<PsiElement, PsiVariable>();
public DeclarationSearcher(final PsiMethod method, final PsiType targetType) {
DeclarationSearcher(@NotNull PsiMethod method, @NotNull PsiType targetType) {
myMethod = method;
myTargetType = targetType;
cache = new HashMap<PsiElement, PsiVariable>();
}
@Nullable
@@ -57,6 +55,7 @@ public class DeclarationSearcher {
@Nullable
private PsiVariable getLocalDeclaration(@NotNull PsiElement endPositionElement) {
final PsiElement parent = endPositionElement.getParent();
if (parent == null) return null;
// reuse of cache is possible IF requests are done up-to-down. otherwise - not first declaration can be returned
final PsiVariable cachedCandidate = cache.get(parent);
@@ -145,15 +145,15 @@ public class MethodReturnTypeFix extends LocalQuickFixAndIntentionActionOnPsiEle
// to clearly separate data
private static class ReturnStatementAdder {
private final PsiElementFactory factory;
private final PsiType myTargetType;
@NotNull private final PsiElementFactory factory;
@NotNull private final PsiType myTargetType;
private ReturnStatementAdder(@NotNull final PsiElementFactory factory, @NotNull final PsiType targetType) {
this.factory = factory;
myTargetType = targetType;
}
public PsiReturnStatement addReturnForMethod(final PsiFile file, final PsiMethod method) {
private PsiReturnStatement addReturnForMethod(final PsiFile file, final PsiMethod method) {
final PsiModifierList modifiers = method.getModifierList();
if (modifiers.hasModifierProperty(PsiModifier.ABSTRACT) || method.getBody() == null) {
return null;
@@ -170,7 +170,7 @@ public class MethodReturnTypeFix extends LocalQuickFixAndIntentionActionOnPsiEle
return null; //must be an error
}
PsiReturnStatement returnStatement;
if (controlFlow != null && ControlFlowUtil.processReturns(controlFlow, visitor)) {
if (ControlFlowUtil.processReturns(controlFlow, visitor)) {
// extra return statement not needed
// get latest modified return statement and select...
returnStatement = visitor.getLatestReturn();
@@ -319,7 +319,9 @@ class SliceUtil {
PsiExpression rExpression = ((PsiAssignmentExpression)parentExpr).getRExpression();
PsiType rtype = rExpression.getType();
PsiType ftype = field.getType();
if (TypeConversionUtil.isAssignable(parentSubstitutor.substitute(ftype), parentSubstitutor.substitute(rtype))) {
PsiType subFType = parentSubstitutor.substitute(ftype);
PsiType subRType = parentSubstitutor.substitute(rtype);
if (subFType != null && subRType != null && TypeConversionUtil.isAssignable(subFType, subRType)) {
return handToProcessor(rExpression, processor, parent, parentSubstitutor, parent.indexNesting, "");
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
* Copyright 2000-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -57,6 +57,7 @@ public class PsiTypesUtil {
private PsiTypesUtil() { }
@NotNull
public static String getDefaultValueOfType(PsiType type) {
if (type instanceof PsiArrayType) {
int count = type.getArrayDimensions() - 1;
@@ -79,17 +80,10 @@ public class PsiTypesUtil {
}
return buffer.toString();
}
else if (type instanceof PsiPrimitiveType) {
if (PsiType.BOOLEAN.equals(type)) {
return PsiKeyword.FALSE;
}
else {
return "0";
}
}
else {
return PsiKeyword.NULL;
if (type instanceof PsiPrimitiveType) {
return PsiType.BOOLEAN.equals(type) ? PsiKeyword.FALSE : "0";
}
return PsiKeyword.NULL;
}
/**
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<problems>
<problem>
<file>testSimple_0.iml</file>
<file>testSimple.iml</file>
<problem_class>Unused library</problem_class>
<description>Unused library 'JUnit'</description>
</problem>
@@ -40,6 +40,7 @@ import com.intellij.openapi.roots.ContentEntry;
import com.intellij.openapi.roots.ModifiableRootModel;
import com.intellij.openapi.roots.ModuleRootManager;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.*;
@@ -544,8 +545,16 @@ public abstract class CodeInsightTestCase extends PsiTestCase {
String fullPath = getTestDataPath() + filePath;
allowRootAccess(fullPath);
final VirtualFile vFile = LocalFileSystem.getInstance().findFileByPath(fullPath.replace(File.separatorChar, '/'));
String vfsPath = FileUtil.toSystemIndependentName(fullPath);
VirtualFile vFile = LocalFileSystem.getInstance().findFileByPath(vfsPath);
assertNotNull("file " + fullPath + " not found", vFile);
String realVfsPath = vFile.getPath();
if (!SystemInfo.isFileSystemCaseSensitive && !vfsPath.equals(realVfsPath) &&
vfsPath.equalsIgnoreCase(realVfsPath)) {
fail("Please correct case-sensitivity of path to prevent test failure on case-sensitive file systems:\n" +
" path " + vfsPath + "\n" +
"real path " + realVfsPath);
}
return vFile;
}
@@ -66,9 +66,9 @@ public class GeneralHighlightingPass extends ProgressableTextEditorHighlightingP
private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.daemon.impl.GeneralHighlightingPass");
private static final String PRESENTABLE_NAME = DaemonBundle.message("pass.syntax");
private static final Key<Boolean> HAS_ERROR_ELEMENT = Key.create("HAS_ERROR_ELEMENT");
static final Condition<PsiFile> SHOULD_HIGHIGHT_FILTER = new Condition<PsiFile>() {
static final Condition<PsiFile> SHOULD_HIGHLIGHT_FILTER = new Condition<PsiFile>() {
@Override
public boolean value(PsiFile file) {
public boolean value(@NotNull PsiFile file) {
return HighlightingLevelManager.getInstance(file.getProject()).shouldHighlight(file);
}
};
@@ -198,7 +198,7 @@ public class GeneralHighlightingPass extends ProgressableTextEditorHighlightingP
List<ProperTextRange> insideRanges = new ArrayList<ProperTextRange>();
List<ProperTextRange> outsideRanges = new ArrayList<ProperTextRange>();
Divider.divideInsideAndOutside(getFile(), myRestrictRange.getStartOffset(), myRestrictRange.getEndOffset(), myPriorityRange, insideElements, insideRanges, outsideElements,
outsideRanges, false, SHOULD_HIGHIGHT_FILTER);
outsideRanges, false, SHOULD_HIGHLIGHT_FILTER);
// put file element always in outsideElements
if (!insideElements.isEmpty() && insideElements.get(insideElements.size()-1) instanceof PsiFile) {
PsiElement file = insideElements.remove(insideElements.size() - 1);
@@ -157,7 +157,7 @@ public abstract class GlobalSearchScope extends SearchScope implements ProjectAw
@NonNls
@Override
public String toString() {
return "UnionToLocal: (" + GlobalSearchScope.this.toString() + ", " + scope + ")";
return "UnionToLocal: (" + GlobalSearchScope.this + ", " + scope + ")";
}
};
}
@@ -446,7 +446,7 @@ public abstract class GlobalSearchScope extends SearchScope implements ProjectAw
});
myNestingLevel = 1 + nested[0];
if (myNestingLevel > 1000) {
throw new IllegalStateException("Too many scopes combined: " + myNestingLevel + StringUtil.first(toString(), 500, true));
throw new IllegalStateException("Too many scopes combined: " + myNestingLevel + StringUtil.last(toString(), 500, true));
}
}
@@ -82,7 +82,7 @@ public class InjectedGeneralHighlightingPass extends GeneralHighlightingPass imp
List<ProperTextRange> outsideRanges = new ArrayList<ProperTextRange>();
//TODO: this thing is just called TWICE with same arguments eating CPU on huge files :(
Divider.divideInsideAndOutside(myFile, myRestrictRange.getStartOffset(), myRestrictRange.getEndOffset(), myPriorityRange, inside, insideRanges, outside,
outsideRanges, false, SHOULD_HIGHIGHT_FILTER);
outsideRanges, false, SHOULD_HIGHLIGHT_FILTER);
// all infos for the "injected fragment for the host which is inside" are indeed inside
@@ -440,7 +440,7 @@ class PassExecutorService implements Disposable {
return;
}
if (!myUpdateProgress.isCanceled()) {
if (!myUpdateProgress.isCanceled() && !myProject.isDisposed()) {
myPass.collectInformation(myUpdateProgress);
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
* Copyright 2000-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,7 +16,6 @@
package com.intellij.ide;
import com.intellij.ide.dnd.LinuxDragAndDropSupport;
import com.intellij.openapi.application.AccessToken;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.diagnostic.Logger;
@@ -25,6 +24,7 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ProjectManager;
import com.intellij.openapi.project.ProjectManagerAdapter;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.CharsetToolkit;
import com.intellij.openapi.vfs.LocalFileSystem;
@@ -162,33 +162,29 @@ public class PsiCopyPasteManager {
public PsiElement[] getElements() {
if (myElements == null) return PsiElement.EMPTY_ARRAY;
int validElementsCount = 0;
ApplicationManager.getApplication().runReadAction(new Runnable() {
@Override
public void run() {
int validElementsCount = 0;
for (PsiElement element : myElements) {
if (element.isValid()) {
validElementsCount++;
}
}
final AccessToken token = ApplicationManager.getApplication().acquireReadActionLock();
try {
for (PsiElement element : myElements) {
if (element.isValid()) {
validElementsCount++;
if (validElementsCount != myElements.length) {
PsiElement[] validElements = new PsiElement[validElementsCount];
int j = 0;
for (PsiElement element : myElements) {
if (element.isValid()) {
validElements[j++] = element;
}
}
myElements = validElements;
}
}
if (validElementsCount == myElements.length) {
return myElements;
}
PsiElement[] validElements = new PsiElement[validElementsCount];
int j=0;
for (PsiElement element : myElements) {
if (element.isValid()) {
validElements[j++] = element;
}
}
myElements = validElements;
}
finally {
token.finish();
}
});
return myElements;
}
@@ -261,33 +257,31 @@ public class PsiCopyPasteManager {
@Nullable
private String getDataAsText() {
final AccessToken token = ApplicationManager.getApplication().acquireReadActionLock();
try {
final List<String> names = new ArrayList<String>();
for (PsiElement element : myDataProxy.getElements()) {
if (element instanceof PsiNamedElement) {
String name = ((PsiNamedElement)element).getName();
if (name != null) {
names.add(name);
return ApplicationManager.getApplication().runReadAction(new Computable<String>() {
@Override
public String compute() {
final List<String> names = new ArrayList<String>();
for (PsiElement element : myDataProxy.getElements()) {
if (element instanceof PsiNamedElement) {
String name = ((PsiNamedElement)element).getName();
if (name != null) {
names.add(name);
}
}
}
return names.isEmpty() ? null : StringUtil.join(names, "\n");
}
return names.isEmpty() ? null : StringUtil.join(names, "\n");
}
finally {
token.finish();
}
});
}
@Nullable
private List<File> getDataAsFileList() {
final AccessToken token = ApplicationManager.getApplication().acquireReadActionLock();
try {
return asFileList(myDataProxy.getElements());
}
finally {
token.finish();
}
return ApplicationManager.getApplication().runReadAction(new Computable<List<File>>() {
@Override
public List<File> compute() {
return asFileList(myDataProxy.getElements());
}
});
}
@Override
@@ -1166,103 +1166,107 @@ public class SearchEverywhereAction extends AnAction implements CustomComponentA
}
@Override
protected void customizeCellRenderer(JList list, Object value, int index, boolean selected, boolean hasFocus) {
protected void customizeCellRenderer(JList list, final Object value, int index, final boolean selected, boolean hasFocus) {
setPaintFocusBorder(false);
setIcon(EmptyIcon.ICON_16);
AccessToken token = ApplicationManager.getApplication().acquireReadActionLock();
try {
if (value instanceof PsiElement) {
String name = myClassModel.getElementName(value);
assert name != null;
append(name);
} else if (value instanceof ChooseRunConfigurationPopup.ItemWrapper) {
final ChooseRunConfigurationPopup.ItemWrapper wrapper = (ChooseRunConfigurationPopup.ItemWrapper)value;
append(wrapper.getText());
setIcon(wrapper.getIcon());
setLocationString(ourShiftIsPressed.get() ? "Run" : "Debug");
myLocationIcon = ourShiftIsPressed.get() ? AllIcons.Toolwindows.ToolWindowRun : AllIcons.Toolwindows.ToolWindowDebugger;
} else if (isVirtualFile(value)) {
final VirtualFile file = (VirtualFile)value;
if (file instanceof VirtualFilePathWrapper) {
append(((VirtualFilePathWrapper)file).getPresentablePath());
} else {
append(file.getName());
ApplicationManager.getApplication().runReadAction(new Runnable() {
@Override
public void run() {
if (value instanceof PsiElement) {
String name = myClassModel.getElementName(value);
assert name != null;
append(name);
}
setIcon(IconUtil.getIcon(file, Iconable.ICON_FLAG_READ_STATUS, myProject));
}
else if (isActionValue(value)) {
final GotoActionModel.ActionWrapper actionWithParentGroup = value instanceof GotoActionModel.ActionWrapper ? (GotoActionModel.ActionWrapper)value : null;
final AnAction anAction = actionWithParentGroup == null ? (AnAction)value : actionWithParentGroup.getAction();
final Presentation templatePresentation = anAction.getTemplatePresentation();
Icon icon = templatePresentation.getIcon();
if (anAction instanceof ActivateToolWindowAction) {
final String id = ((ActivateToolWindowAction)anAction).getToolWindowId();
ToolWindow toolWindow = ToolWindowManager.getInstance(myProject).getToolWindow(id);
if (toolWindow != null) {
icon = toolWindow.getIcon();
else if (value instanceof ChooseRunConfigurationPopup.ItemWrapper) {
final ChooseRunConfigurationPopup.ItemWrapper wrapper = (ChooseRunConfigurationPopup.ItemWrapper)value;
append(wrapper.getText());
setIcon(wrapper.getIcon());
setLocationString(ourShiftIsPressed.get() ? "Run" : "Debug");
myLocationIcon = ourShiftIsPressed.get() ? AllIcons.Toolwindows.ToolWindowRun : AllIcons.Toolwindows.ToolWindowDebugger;
}
else if (isVirtualFile(value)) {
final VirtualFile file = (VirtualFile)value;
if (file instanceof VirtualFilePathWrapper) {
append(((VirtualFilePathWrapper)file).getPresentablePath());
}
else {
append(file.getName());
}
setIcon(IconUtil.getIcon(file, Iconable.ICON_FLAG_READ_STATUS, myProject));
}
else if (isActionValue(value)) {
final GotoActionModel.ActionWrapper actionWithParentGroup =
value instanceof GotoActionModel.ActionWrapper ? (GotoActionModel.ActionWrapper)value : null;
final AnAction anAction = actionWithParentGroup == null ? (AnAction)value : actionWithParentGroup.getAction();
final Presentation templatePresentation = anAction.getTemplatePresentation();
Icon icon = templatePresentation.getIcon();
if (anAction instanceof ActivateToolWindowAction) {
final String id = ((ActivateToolWindowAction)anAction).getToolWindowId();
ToolWindow toolWindow = ToolWindowManager.getInstance(myProject).getToolWindow(id);
if (toolWindow != null) {
icon = toolWindow.getIcon();
}
}
append(templatePresentation.getText());
if (actionWithParentGroup != null) {
final String groupName = actionWithParentGroup.getGroupName();
append(templatePresentation.getText());
if (actionWithParentGroup != null) {
final String groupName = actionWithParentGroup.getGroupName();
if (!StringUtil.isEmpty(groupName)) {
setLocationString(groupName);
}
}
final String groupName = actionWithParentGroup == null ? null : actionWithParentGroup.getGroupName();
if (!StringUtil.isEmpty(groupName)) {
setLocationString(groupName);
}
}
final String groupName = actionWithParentGroup == null ? null : actionWithParentGroup.getGroupName();
if (!StringUtil.isEmpty(groupName)) {
setLocationString(groupName);
}
if (icon != null && icon.getIconWidth() <= 16 && icon.getIconHeight() <= 16) {
setIcon(IconUtil.toSize(icon, 16, 16));
}
}
else if (isSetting(value)) {
String text = getSettingText((OptionDescription)value);
SimpleTextAttributes attrs = SimpleTextAttributes.REGULAR_ATTRIBUTES;
if (value instanceof Changeable && ((Changeable)value).hasChanged()) {
if (selected) {
attrs = SimpleTextAttributes.REGULAR_BOLD_ATTRIBUTES;
} else {
SimpleTextAttributes base = SimpleTextAttributes.LINK_BOLD_ATTRIBUTES;
attrs = base.derive(SimpleTextAttributes.STYLE_BOLD, base.getFgColor(), null, null);
if (icon != null && icon.getIconWidth() <= 16 && icon.getIconHeight() <= 16) {
setIcon(IconUtil.toSize(icon, 16, 16));
}
}
append(text, attrs);
final String id = ((OptionDescription)value).getConfigurableId();
final String name = myConfigurables.get(id);
if (name != null) {
setLocationString(name);
else if (isSetting(value)) {
String text = getSettingText((OptionDescription)value);
SimpleTextAttributes attrs = SimpleTextAttributes.REGULAR_ATTRIBUTES;
if (value instanceof Changeable && ((Changeable)value).hasChanged()) {
if (selected) {
attrs = SimpleTextAttributes.REGULAR_BOLD_ATTRIBUTES;
}
else {
SimpleTextAttributes base = SimpleTextAttributes.LINK_BOLD_ATTRIBUTES;
attrs = base.derive(SimpleTextAttributes.STYLE_BOLD, base.getFgColor(), null, null);
}
}
append(text, attrs);
final String id = ((OptionDescription)value).getConfigurableId();
final String name = myConfigurables.get(id);
if (name != null) {
setLocationString(name);
}
}
}
else if (value instanceof OptionsTopHitProvider) {
append("#" + ((OptionsTopHitProvider)value).getId());
}
else {
ItemPresentation presentation = null;
if (value instanceof ItemPresentation) {
presentation = (ItemPresentation)value;
else if (value instanceof OptionsTopHitProvider) {
append("#" + ((OptionsTopHitProvider)value).getId());
}
else if (value instanceof NavigationItem) {
presentation = ((NavigationItem)value).getPresentation();
}
if (presentation != null) {
final String text = presentation.getPresentableText();
append(text == null ? value.toString() : text);
final String location = presentation.getLocationString();
if (!StringUtil.isEmpty(location)) {
setLocationString(location);
else {
ItemPresentation presentation = null;
if (value instanceof ItemPresentation) {
presentation = (ItemPresentation)value;
}
else if (value instanceof NavigationItem) {
presentation = ((NavigationItem)value).getPresentation();
}
if (presentation != null) {
final String text = presentation.getPresentableText();
append(text == null ? value.toString() : text);
final String location = presentation.getLocationString();
if (!StringUtil.isEmpty(location)) {
setLocationString(location);
}
Icon icon = presentation.getIcon(false);
if (icon != null) setIcon(icon);
}
Icon icon = presentation.getIcon(false);
if (icon != null) setIcon(icon);
}
}
}
finally {
token.finish();
}
});
}
public void recalculateWidth() {
@@ -66,6 +66,8 @@ public class ProjectImpl extends PlatformComponentManagerImpl implements Project
public static final String NAME_FILE = ".name";
public static final Key<Long> CREATION_TIME = Key.create("ProjectImpl.CREATION_TIME");
public static final Key<String> CREATION_TRACE = Key.create("ProjectImpl.CREATION_TRACE");
@TestOnly
public static final String LIGHT_PROJECT_NAME = "light_temp";
private ProjectManager myProjectManager;
private MyProjectManagerListener myProjectManagerListener;
@@ -103,7 +105,7 @@ public class ProjectImpl extends PlatformComponentManagerImpl implements Project
}
// light project may be changed later during test, so we need to remember its initial state
myLight = ApplicationManager.getApplication().isUnitTestMode() && filePath.contains("light_temp_");
myLight = ApplicationManager.getApplication().isUnitTestMode() && filePath.contains(LIGHT_PROJECT_NAME);
}
@Override
@@ -61,6 +61,7 @@ import com.intellij.openapi.project.ModuleAdapter;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ProjectManager;
import com.intellij.openapi.project.ex.ProjectManagerEx;
import com.intellij.openapi.project.impl.ProjectImpl;
import com.intellij.openapi.project.impl.ProjectManagerImpl;
import com.intellij.openapi.projectRoots.Sdk;
import com.intellij.openapi.roots.ModuleRootManager;
@@ -241,7 +242,7 @@ public abstract class LightPlatformTestCase extends UsefulTestCase implements Da
token.finish();
}
final File projectFile = FileUtil.createTempFile("light_temp_", ProjectFileType.DOT_DEFAULT_EXTENSION);
final File projectFile = FileUtil.createTempFile(ProjectImpl.LIGHT_PROJECT_NAME, ProjectFileType.DOT_DEFAULT_EXTENSION);
LocalFileSystem.getInstance().refreshAndFindFileByIoFile(projectFile);
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
@@ -110,7 +110,7 @@ public abstract class PlatformTestCase extends UsefulTestCase implements DataPro
protected boolean myAssertionsInTestDetected;
protected static final Logger LOG = Logger.getInstance("#com.intellij.testFramework.PlatformTestCase");
public static Thread ourTestThread;
private static TestCase ourTestCase = null;
private static TestCase ourTestCase;
public static final long DEFAULT_TEST_TIME = 300L;
public static long ourTestTime = DEFAULT_TEST_TIME;
private EditorListenerTracker myEditorListenerTracker;
@@ -191,6 +191,9 @@ public abstract class PlatformTestCase extends UsefulTestCase implements DataPro
@Override
protected void setUp() throws Exception {
super.setUp();
File tempDir = new File(FileUtilRt.getTempDirectory());
myFilesToDelete.add(tempDir);
if (ourTestCase != null) {
String message = "Previous test " + ourTestCase + " hasn't called tearDown(). Probably overridden without super call.";
ourTestCase = null;
@@ -307,7 +310,7 @@ public abstract class PlatformTestCase extends UsefulTestCase implements DataPro
}
protected File getIprFile() throws IOException {
File tempFile = FileUtil.createTempFile(getName() + "_", ProjectFileType.DOT_DEFAULT_EXTENSION);
File tempFile = FileUtil.createTempFile(getName(), ProjectFileType.DOT_DEFAULT_EXTENSION);
myFilesToDelete.add(tempFile);
return tempFile;
}
@@ -139,7 +139,7 @@ public abstract class UsefulTestCase extends TestCase {
String testName = FileUtil.sanitizeFileName(getTestName(true));
if (StringUtil.isEmptyOrSpaces(testName)) testName = "";
testName = new File(testName).getName(); // in case the test name contains file separators
myTempDir = FileUtil.toSystemDependentName(ORIGINAL_TEMP_DIR + "/" + TEMP_DIR_MARKER + testName + "_"+ RNG.nextInt(1000));
myTempDir = new File(ORIGINAL_TEMP_DIR, TEMP_DIR_MARKER + testName).getPath();
FileUtil.resetCanonicalTempPathCache(myTempDir);
}
ApplicationInfoImpl.setInPerformanceTest(isPerformanceTest());
@@ -315,7 +315,7 @@ public class FileUtilRt {
}
private static class FilesToDeleteHolder {
public static final Queue<String> ourFilesToDelete = createFilesToDelete();
private static final Queue<String> ourFilesToDelete = createFilesToDelete();
private static Queue<String> createFilesToDelete() {
final ConcurrentLinkedQueue<String> queue = new ConcurrentLinkedQueue<String>();
@@ -387,62 +387,47 @@ public class FileUtilRt {
prefix = (prefix + "___").substring(0, 3);
}
if (suffix == null) {
suffix = ".tmp";
suffix = "";
}
// normalize and use only the file name from the prefix
prefix = new File(prefix).getName();
int exceptionsCount = 0;
int i = 0;
while (true) {
try {
// If there was an IOException, there's no reason to do sequential search - fallback to random
final File temp = createTemp(prefix, suffix, dir, isDirectory, exceptionsCount > 0);
return normalizeFile(temp);
File f = calcName(dir, prefix, suffix, i);
boolean success = isDirectory ? f.mkdir() : f.createNewFile();
if (!success) {
throw new IOException("Unable to create temporary file " + f);
}
return normalizeFile(f);
}
catch (IOException e) { // Win32 createFileExclusively access denied
if (++exceptionsCount >= 100) {
throw e;
}
}
i++; // for some reason the file1 can't be created (previous file1 was deleted but got locked by anti-virus?). try file2.
if (i > 2) {
i = 2 + (int)(System.nanoTime() % 998); // generate random suffix if too many failures
}
}
}
@NotNull
private static File createTemp(@NotNull String prefix,
@NotNull String suffix,
@NotNull File directory,
boolean isDirectory,
boolean randomName) throws IOException {
// Fallback to the original File.createTempFile
if (randomName) {
@SuppressWarnings("SSBasedInspection")
File res = File.createTempFile(prefix, suffix, directory);
if (isDirectory) {
if (!res.delete() || !res.mkdir()) {
throw new IOException("Cannot create directory: " + res);
}
}
return res;
private static File calcName(@NotNull File dir, @NotNull String prefix, @NotNull String suffix, int i) throws IOException {
prefix += i == 0 ? "" : i;
if (prefix.endsWith(".") && suffix.startsWith(".")) {
prefix = prefix.substring(0, prefix.length() - 1);
}
// normalize and use only the file name from the prefix
prefix = new File(prefix).getName();
File f;
int i = 0;
do {
String name = prefix + i + suffix;
f = new File(directory, name);
if (!name.equals(f.getName())) {
throw new IOException("Unable to create temporary file " + f + " for name " + name);
}
i++;
String name = prefix + suffix;
File f = new File(dir, name);
if (!name.equals(f.getName())) {
throw new IOException("Unable to create temporary file " + f + " for name " + name);
}
while (f.exists());
boolean success = isDirectory ? f.mkdir() : f.createNewFile();
if (!success) {
throw new IOException("Unable to create temporary file " + f);
}
return f;
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
* Copyright 2000-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -18,12 +18,14 @@ package com.intellij.spellchecker.compress;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.TestOnly;
import java.util.Arrays;
public final class Alphabet {
private final char[] letters;
private int lastIndexUsed;
private static final int MAX_INDEX = UnitBitSet.MAX_UNIT_VALUE;
public char getLetter(int position) {
char getLetter(int position) {
return letters[position];
}
@@ -40,7 +42,7 @@ public final class Alphabet {
@param forceAdd - if set to true - letter will be added to the alphabet if not present yet
@return index of the letter or -1 if letter was not found and could not be added (due to forceAdd property value)
*/
public int getNextIndex(int startFrom, char letter, boolean forceAdd) {
private int getNextIndex(int startFrom, char letter, boolean forceAdd) {
for (int i = startFrom; i <= lastIndexUsed; i++) {
if (i == letters.length) return -1;
if (letters[i] != 0 && letters[i] == letter) {
@@ -53,7 +55,7 @@ public final class Alphabet {
return add(letter);
}
public int getLastIndexUsed() {
int getLastIndexUsed() {
return lastIndexUsed;
}
@@ -69,7 +71,7 @@ public final class Alphabet {
this(MAX_INDEX);
}
Alphabet(int maxIndex) {
private Alphabet(int maxIndex) {
assert maxIndex <= MAX_INDEX : "alphabet is too long";
letters = new char[maxIndex];
}
@@ -83,4 +85,9 @@ public final class Alphabet {
add(alphabet.charAt(i));
}
}
@Override
public String toString() {
return "Letters[" + lastIndexUsed + "]: '" + Arrays.toString(Arrays.copyOf(letters, lastIndexUsed))+"'";
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
* Copyright 2000-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,25 +19,25 @@ import org.jetbrains.annotations.NotNull;
import java.util.Arrays;
public class UnitBitSet {
public static final int MAX_CHARS_IN_WORD = 64;
public static final int MAX_UNIT_VALUE = 255;
class UnitBitSet {
static final int MAX_CHARS_IN_WORD = 64;
static final int MAX_UNIT_VALUE = 255;
final byte[] b;
private final Alphabet alpha;
public UnitBitSet(@NotNull byte[] indices, @NotNull Alphabet alphabet) {
UnitBitSet(@NotNull byte[] indices, @NotNull Alphabet alphabet) {
b = indices;
alpha = alphabet;
}
public int getUnitValue(int number) {
int getUnitValue(int number) {
final int r = b[number] & 0xFF;
assert r >= 0 && r <= MAX_UNIT_VALUE : "invalid unit value";
return r;
}
public void setUnitValue(int number, int value) {
void setUnitValue(int number, int value) {
assert value >= 0 : "unit value is negative" + value;
assert value <= MAX_UNIT_VALUE : "unit value is too big";
b[number] = (byte)value;
@@ -45,8 +45,7 @@ public class UnitBitSet {
@Override
public boolean equals(Object obj) {
if (!(obj instanceof UnitBitSet)) return false;
return Arrays.equals(b, ((UnitBitSet)obj).b);
return obj instanceof UnitBitSet && Arrays.equals(b, ((UnitBitSet)obj).b);
}
@Override
@@ -61,7 +60,7 @@ public class UnitBitSet {
@NotNull
public byte[] pack() {
int meaningfulBits = 32 - Integer.numberOfLeadingZeros(alpha.getLastIndexUsed());
assert meaningfulBits <= 8 && meaningfulBits >= 1 : meaningfulBits + ": "+alpha.getLastIndexUsed();
assert meaningfulBits <= 8 && meaningfulBits >= 1 : meaningfulBits + ": "+alpha;
byte[] result = new byte[(b.length * meaningfulBits + 7) / 8];
int byteNumber = 0;
@@ -87,7 +86,7 @@ public class UnitBitSet {
@NotNull
public static String decode(@NotNull byte[] packed, @NotNull Alphabet alphabet) {
int meaningfulBits = 32 - Integer.numberOfLeadingZeros(alphabet.getLastIndexUsed());
assert meaningfulBits <= 8;
assert meaningfulBits <= 8 : alphabet;
StringBuilder result = new StringBuilder(packed.length * 8 / meaningfulBits);
@@ -105,7 +104,7 @@ public class UnitBitSet {
curByte >>>= meaningfulBits;
bitOffset += meaningfulBits;
assert bitOffset <= 8;
assert bitOffset <= 8 : alphabet;
if (bitOffset + meaningfulBits > 8) {
if (++byteIndex == packed.length) break;
int leftOverBits = 8 - bitOffset;
@@ -116,9 +115,9 @@ public class UnitBitSet {
return result.toString();
}
public static int getFirstLetterIndex(byte firstPackedByte, @NotNull Alphabet alphabet) {
static int getFirstLetterIndex(byte firstPackedByte, @NotNull Alphabet alphabet) {
int meaningfulBits = 32 - Integer.numberOfLeadingZeros(alphabet.getLastIndexUsed());
assert meaningfulBits <= 8;
assert meaningfulBits <= 8 : alphabet;
int index = firstPackedByte & ((1 << meaningfulBits) - 1);
return index;