Merge remote-tracking branch 'origin/master'

This commit is contained in:
Vladimir.Orlov
2015-12-02 06:56:34 +03:00
19 changed files with 242 additions and 251 deletions
@@ -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.
@@ -20,6 +20,7 @@ import com.intellij.openapi.util.Comparing;
import com.intellij.psi.*;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiUtil;
import com.siyeh.ig.psiutils.TypeUtils;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -124,13 +125,20 @@ public class SillyAssignmentInspectionBase extends BaseJavaBatchLocalInspectionT
private static PsiExpression deparenthesizeRExpr(PsiExpression rExpression, PsiVariable variable) {
rExpression = PsiUtil.skipParenthesizedExprDown(rExpression);
if (rExpression instanceof PsiTypeCastExpression) {
final PsiTypeElement castTypeElement = ((PsiTypeCastExpression)rExpression).getCastType();
if (castTypeElement != null &&
castTypeElement.getType() instanceof PsiPrimitiveType &&
variable.getType().equalsToText(CommonClassNames.JAVA_LANG_OBJECT)) {
return rExpression;
final PsiTypeCastExpression typeCastExpression = (PsiTypeCastExpression)rExpression;
final PsiExpression operand = typeCastExpression.getOperand();
final PsiTypeElement castTypeElement = typeCastExpression.getCastType();
if (castTypeElement == null || operand == null) return null;
final PsiType castType = castTypeElement.getType();
if (castType instanceof PsiPrimitiveType) {
if (variable.getType().equalsToText(CommonClassNames.JAVA_LANG_OBJECT)) {
return rExpression;
}
else if (TypeUtils.isNarrowingConversion(operand.getType(), castType)) {
return null;
}
}
return PsiUtil.deparenthesizeExpression(rExpression);
return deparenthesizeRExpr(operand, variable);
}
return rExpression;
}
@@ -24,6 +24,7 @@ import com.intellij.psi.controlFlow.*;
import com.intellij.psi.search.LocalSearchScope;
import com.intellij.psi.search.searches.ReferencesSearch;
import com.intellij.psi.util.PsiUtil;
import com.intellij.refactoring.util.RefactoringUtil;
import com.intellij.util.IncorrectOperationException;
import com.siyeh.ig.psiutils.ParenthesesUtils;
import org.jetbrains.annotations.NonNls;
@@ -80,7 +81,7 @@ public class ConvertSwitchToIfIntention implements IntentionAction {
if (switchExpression == null) {
return;
}
final PsiType switchExpressionType = switchExpression.getType();
final PsiType switchExpressionType = RefactoringUtil.getTypeByExpressionWithExpectedType(switchExpression);
if (switchExpressionType == null) {
return;
}
@@ -110,10 +111,7 @@ public class ConvertSwitchToIfIntention implements IntentionAction {
"i", switchExpression, true);
}
expressionText = variableName;
declarationString =
switchExpressionType.getPresentableText() + ' ' +
variableName + " = " +
switchExpression.getText() + ';';
declarationString = switchExpressionType.getCanonicalText() + ' ' + variableName + " = " + switchExpression.getText() + ';';
}
else {
hadSideEffects = false;
@@ -334,7 +332,7 @@ public class ConvertSwitchToIfIntention implements IntentionAction {
for (PsiLocalVariable variable : variables) {
if (ReferencesSearch.search(variable, new LocalSearchScope(bodyStatements.toArray(new PsiElement[bodyStatements.size()]))).findFirst() != null) {
final PsiType varType = variable.getType();
ifStatementString.append(varType.getPresentableText());
ifStatementString.append(varType.getCanonicalText());
ifStatementString.append(' ');
ifStatementString.append(variable.getName());
ifStatementString.append(';');
@@ -37,4 +37,9 @@ class a {
void cf2(a aa) {
aa.f = f;
}
void m() {
double m = 1.5;
m = (double) (int) m;
}
}
@@ -0,0 +1,9 @@
// "Replace 'switch' with 'if'" "true"
class Test {
void foo(Object e) {
Class<?> i = e.getClass();
if (i.equals(RuntimeException.class)) {
} else if (i.equals(IOException.class)) {
}
}
}
@@ -0,0 +1,11 @@
// "Replace 'switch' with 'if'" "true"
class Test {
void foo(Object e) {
<caret>switch(e.getClass()) {
case RuntimeException.class:
break;
case IOException.class:
break;
}
}
}
@@ -370,7 +370,8 @@ public final class NavigationUtil {
//noinspection ConstantConditions
return ((GotoRelatedItem)value).getCustomName();
}
final PsiElement element = (PsiElement)value;
PsiElement element = (PsiElement)value;
if (!element.isValid()) return "INVALID";
return renderer.getElementText(element) + " " + renderer.getContainerText(element, null);
}
@@ -101,6 +101,9 @@ public class ProjectUtil {
if (virtualFile == null) return null;
virtualFile.refresh(false, false);
Project existing = findAndFocusExistingProjectForPath(path);
if (existing != null) return existing;
ProjectOpenProcessor strong = ProjectOpenProcessor.getStrongImportProvider(virtualFile);
if (strong != null) {
return strong.doOpenProject(virtualFile, projectToClose, forceOpenInNewFrame);
@@ -158,14 +161,10 @@ public class ProjectUtil {
return null;
}
Project[] openProjects = ProjectManager.getInstance().getOpenProjects();
for (Project project : openProjects) {
if (!project.isDefault() && isSameProject(path, project)) {
focusProjectWindow(project, false);
return project;
}
}
Project existing = findAndFocusExistingProjectForPath(path);
if (existing != null) return existing;
Project[] openProjects = ProjectManager.getInstance().getOpenProjects();
if (!forceOpenInNewFrame && openProjects.length > 0) {
int exitCode = confirmOpenNewProject(false);
if (exitCode == GeneralSettings.OPEN_PROJECT_SAME_WINDOW) {
@@ -199,6 +198,18 @@ public class ProjectUtil {
return project;
}
@Nullable
private static Project findAndFocusExistingProjectForPath(String path) {
Project[] openProjects = ProjectManager.getInstance().getOpenProjects();
for (Project project : openProjects) {
if (!project.isDefault() && isSameProject(path, project)) {
focusProjectWindow(project, false);
return project;
}
}
return null;
}
/**
* @return {@link com.intellij.ide.GeneralSettings#OPEN_PROJECT_SAME_WINDOW}
* {@link com.intellij.ide.GeneralSettings#OPEN_PROJECT_NEW_WINDOW}
@@ -233,7 +244,7 @@ public class ProjectUtil {
return confirmOpenNewProject;
}
private static boolean isSameProject(String path, @NotNull Project project) {
public static boolean isSameProject(String path, @NotNull Project project) {
IProjectStore projectStore = (IProjectStore)ServiceKt.getStateStore(project);
String toOpen = FileUtil.toSystemIndependentName(path);
@@ -31,6 +31,7 @@ import com.intellij.openapi.vfs.pointers.VirtualFilePointerContainer;
import com.intellij.openapi.vfs.pointers.VirtualFilePointerListener;
import com.intellij.openapi.vfs.pointers.VirtualFilePointerManager;
import com.intellij.util.ConcurrencyUtil;
import com.intellij.util.FileContentUtilCore;
import com.intellij.util.SmartList;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.io.URLUtil;
@@ -431,7 +432,8 @@ public class VirtualFilePointerManagerImpl extends VirtualFilePointerManager imp
}
else if (event instanceof VFilePropertyChangeEvent) {
final VFilePropertyChangeEvent change = (VFilePropertyChangeEvent)event;
if (VirtualFile.PROP_NAME.equals(change.getPropertyName())) {
if (VirtualFile.PROP_NAME.equals(change.getPropertyName())
&& event.getRequestor() != FileContentUtilCore.FORCE_RELOAD_REQUESTOR) {
VirtualFile eventFile = change.getFile();
VirtualFile parent = eventFile.getParent(); // e.g. for LightVirtualFiles
addPointersUnder(parent, true, change.getNewValue().toString(), toFireEvents);
@@ -140,7 +140,7 @@ public final class NettyUtil {
break;
}
catch (IOException e) {
if (stopCondition.value(null) || (promise != null && promise.getState() == Promise.State.REJECTED)) {
if (stopCondition.value(null) || (promise != null && promise.getState() != Promise.State.PENDING)) {
return null;
}
else if (maxAttemptCount == -1) {
@@ -1,5 +1,5 @@
<component>
<scheme name="FindView">
<scheme name="FindView" default_scheme="true">
<colors>
</colors>
@@ -22,17 +22,14 @@ import com.intellij.util.Url
// sources - is not originally specified, but canonicalized/normalized
class SourceMap(val outFile: String?, val mappings: MappingList, internal val sourceIndexToMappings: Array<MappingList?>, val sourceResolver: SourceResolver, val hasNameMappings: Boolean) {
val sources: Array<Url>
get() = sourceResolver.canonicalizedSources
get() = sourceResolver.canonicalizedUrls
fun getSourceLineByRawLocation(rawLine: Int, rawColumn: Int) = mappings.get(rawLine, rawColumn)?.sourceLine ?: -1
fun findMappingList(sourceUrls: List<Url>, sourceFile: VirtualFile?, resolver: NullableLazyValue<SourceResolver.Resolver>?): MappingList? {
var mappings = sourceResolver.findMappings(sourceUrls, this, sourceFile)
if (mappings == null && resolver != null) {
val resolverValue = resolver.value
if (resolverValue != null) {
mappings = sourceResolver.findMappings(sourceFile, this, resolverValue)
}
mappings = resolver.value?.let { sourceResolver.findMappings(sourceFile, this, it) }
}
return mappings
}
@@ -27,62 +27,35 @@ import com.intellij.util.Urls
import com.intellij.util.containers.ObjectIntHashMap
import com.intellij.util.containers.isNullOrEmpty
import com.intellij.util.io.URLUtil
import com.intellij.util.text.CaseInsensitiveStringHashingStrategy
import gnu.trove.TObjectIntHashMap
import org.jetbrains.io.LocalFileFinder
import java.io.File
open class SourceResolver(private val rawSources: List<String>, trimFileScheme: Boolean, baseFileUrl: Url?, private val sourceContents: List<String>?, baseUrlIsFile: Boolean = true) {
private val canonicalizedSourcesMap: ObjectIntHashMap<Url> = if (SystemInfo.isFileSystemCaseSensitive) ObjectIntHashMap(rawSources.size) else ObjectIntHashMap(rawSources.size, Urls.getCaseInsensitiveUrlHashingStrategy())
inline fun SourceResolver(rawSources: List<String>, sourceContents: List<String>?, urlCanonicalizer: (String) -> Url): SourceResolver {
return SourceResolver(rawSources, Array(rawSources.size) { urlCanonicalizer(rawSources[it]) }, sourceContents)
}
internal val canonicalizedSources = Array(rawSources.size) { i ->
val rawSource = rawSources[i]
val url = canonicalizeUrl(rawSource, baseFileUrl, trimFileScheme, i, baseUrlIsFile)
canonicalizedSourcesMap.put(url, i)
url
fun SourceResolver(rawSources: List<String>,
trimFileScheme: Boolean,
baseFileUrl: Url?, sourceContents: List<String>?,
baseUrlIsFile: Boolean = true): SourceResolver {
return SourceResolver(rawSources, sourceContents) { canonicalizeUrl(it, baseFileUrl, trimFileScheme, baseUrlIsFile) }
}
class SourceResolver(private val rawSources: List<String>, internal val canonicalizedUrls: Array<Url>, private val sourceContents: List<String>?) {
private val canonicalizedUrlToSourceIndex: ObjectIntHashMap<Url> = if (SystemInfo.isFileSystemCaseSensitive) ObjectIntHashMap(rawSources.size) else ObjectIntHashMap(rawSources.size, Urls.getCaseInsensitiveUrlHashingStrategy())
init {
for (i in rawSources.indices) {
canonicalizedUrlToSourceIndex.put(canonicalizedUrls[i], i)
}
}
private var absoluteLocalPathToSourceIndex: TObjectIntHashMap<String>? = null
// absoluteLocalPathToSourceIndex contains canonical paths too, but this map contains only used (specified in the source map) path
private var sourceIndexToAbsoluteLocalPath: Array<String?>? = null
// see canonicalizeUri kotlin impl and https://trac.webkit.org/browser/trunk/Source/WebCore/inspector/front-end/ParsedURL.js completeURL
protected open fun canonicalizeUrl(url: String, baseUrl: Url?, trimFileScheme: Boolean, sourceIndex: Int, baseUrlIsFile: Boolean): Url {
if (trimFileScheme && url.startsWith(StandardFileSystems.FILE_PROTOCOL_PREFIX)) {
return Urls.newLocalFileUrl(FileUtil.toCanonicalPath(VfsUtilCore.toIdeaUrl(url, true).substring(StandardFileSystems.FILE_PROTOCOL_PREFIX.length), '/'))
}
else if (baseUrl == null || url.contains(URLUtil.SCHEME_SEPARATOR) || url.startsWith("data:") || url.startsWith("blob:") || url.startsWith("javascript:")) {
return Urls.parseEncoded(url) ?: UrlImpl(url)
}
val path = canonicalizePath(url, baseUrl, baseUrlIsFile)
if (baseUrl.scheme == null && baseUrl.isInLocalFileSystem) {
return Urls.newLocalFileUrl(path)
}
// browserify produces absolute path in the local filesystem
if (isAbsolute(path)) {
val file = LocalFileFinder.findFile(path)
if (file != null) {
if (absoluteLocalPathToSourceIndex == null) {
// must be linked, on iterate original path must be first
absoluteLocalPathToSourceIndex = createStringIntMap(rawSources.size)
sourceIndexToAbsoluteLocalPath = arrayOfNulls<String>(rawSources.size)
}
absoluteLocalPathToSourceIndex!!.put(path, sourceIndex)
sourceIndexToAbsoluteLocalPath!![sourceIndex] = path
val canonicalPath = file.canonicalPath
if (canonicalPath != null && canonicalPath != path) {
absoluteLocalPathToSourceIndex!!.put(canonicalPath, sourceIndex)
}
return Urls.newLocalFileUrl(path)
}
}
return UrlImpl(baseUrl.scheme, baseUrl.authority, path, null)
interface Resolver {
fun resolve(sourceFile: VirtualFile?, map: ObjectIntHashMap<Url>): Int
}
fun getSource(entry: MappingEntry): Url? {
val index = entry.source
return if (index < 0) null else canonicalizedSources[index]
return if (index < 0) null else canonicalizedUrls[index]
}
fun getSourceContent(entry: MappingEntry): String? {
@@ -101,30 +74,21 @@ open class SourceResolver(private val rawSources: List<String>, trimFileScheme:
return if (sourceIndex < 0 || sourceIndex >= sourceContents!!.size) null else sourceContents[sourceIndex]
}
fun getSourceIndex(url: Url) = ArrayUtil.indexOf(canonicalizedSources, url)
fun getSourceIndex(url: Url) = ArrayUtil.indexOf(canonicalizedUrls, url)
fun getRawSource(entry: MappingEntry): String? {
val index = entry.source
return if (index < 0) null else rawSources[index]
}
fun getLocalFilePath(entry: MappingEntry): String? {
val index = entry.source
return if (index < 0 || sourceIndexToAbsoluteLocalPath == null) null else sourceIndexToAbsoluteLocalPath!![index]
}
interface Resolver {
fun resolve(sourceFile: VirtualFile?, map: ObjectIntHashMap<Url>): Int
}
fun findMappings(sourceFile: VirtualFile?, sourceMap: SourceMap, resolver: Resolver): MappingList? {
val index = resolver.resolve(sourceFile, canonicalizedSourcesMap)
val index = resolver.resolve(sourceFile, canonicalizedUrlToSourceIndex)
return if (index < 0) null else sourceMap.sourceIndexToMappings[index]
}
fun findMappings(sourceUrls: List<Url>, sourceMap: SourceMap, sourceFile: VirtualFile?): MappingList? {
for (sourceUrl in sourceUrls) {
val index = canonicalizedSourcesMap.get(sourceUrl)
val index = canonicalizedUrlToSourceIndex.get(sourceUrl)
if (index != -1) {
return sourceMap.sourceIndexToMappings[index]
}
@@ -139,69 +103,81 @@ open class SourceResolver(private val rawSources: List<String>, trimFileScheme:
return null
}
private fun findByFile(sourceMap: SourceMap, sourceFile: VirtualFile): MappingList? {
var mappings: MappingList? = null
if (absoluteLocalPathToSourceIndex != null && sourceFile.isInLocalFileSystem) {
mappings = getMappingsBySource(sourceMap, absoluteLocalPathToSourceIndex!!.get(sourceFile.path))
if (mappings == null) {
val sourceFileCanonicalPath = sourceFile.canonicalPath
if (sourceFileCanonicalPath != null) {
mappings = getMappingsBySource(sourceMap, absoluteLocalPathToSourceIndex!!.get(sourceFileCanonicalPath))
}
}
fun findByFile(sourceMap: SourceMap, sourceFile: VirtualFile): MappingList? {
var index = canonicalizedUrlToSourceIndex.get(Urls.newFromVirtualFile(sourceFile).trimParameters())
if (index != -1) {
return sourceMap.sourceIndexToMappings[index]
}
if (mappings == null) {
val index = canonicalizedSourcesMap.get(Urls.newFromVirtualFile(sourceFile).trimParameters())
if (sourceFile.isInLocalFileSystem) {
// local file url - without "file" scheme, just path
index = canonicalizedUrlToSourceIndex.get(Urls.newLocalFileUrl(sourceFile))
if (index != -1) {
return sourceMap.sourceIndexToMappings[index]
}
}
for (i in canonicalizedSources.indices) {
val url = canonicalizedSources[i]
if (Urls.equalsIgnoreParameters(url, sourceFile)) {
return sourceMap.sourceIndexToMappings[i]
}
val canonicalFile = sourceFile.canonicalFile
if (canonicalFile != null && canonicalFile != sourceFile && Urls.equalsIgnoreParameters(url, canonicalFile)) {
// ok, search by canonical path
val canonicalFile = sourceFile.canonicalFile
if (canonicalFile != null && canonicalFile != sourceFile) {
for (i in canonicalizedUrls.indices) {
val url = canonicalizedUrls[i]
if (Urls.equalsIgnoreParameters(url, canonicalFile)) {
return sourceMap.sourceIndexToMappings[i]
}
}
}
return mappings
return null
}
fun getLocalFilePath(entry: MappingEntry) = canonicalizedUrls.getOrNull(entry.source)?.let { if (it.isInLocalFileSystem) it.path else null }
companion object {
fun isAbsolute(path: String): Boolean {
return !path.isEmpty() && (path[0] == '/' || (SystemInfo.isWindows && (path.length > 2 && path[1] == ':')))
}
fun canonicalizePath(url: String, baseUrl: Url, baseUrlIsFile: Boolean): String {
var path = url
if (url[0] != '/') {
val basePath = baseUrl.path
if (baseUrlIsFile) {
val lastSlashIndex = basePath.lastIndexOf('/')
val pathBuilder = StringBuilder()
if (lastSlashIndex == -1) {
pathBuilder.append('/')
}
else {
pathBuilder.append(basePath, 0, lastSlashIndex + 1)
}
path = pathBuilder.append(url).toString()
}
else {
path = "$basePath/$url"
}
}
path = FileUtil.toCanonicalPath(path, '/')
return path
}
private fun getMappingsBySource(sourceMap: SourceMap, index: Int) = if (index == -1) null else sourceMap.sourceIndexToMappings[index]
fun isAbsolute(path: String) = path.firstOrNull() == '/' || (SystemInfo.isWindows && (path.length > 2 && path[1] == ':'))
}
}
private fun createStringIntMap(initialCapacity: Int) = if (SystemInfo.isFileSystemCaseSensitive) ObjectIntHashMap<String>(initialCapacity) else ObjectIntHashMap(initialCapacity, CaseInsensitiveStringHashingStrategy.INSTANCE)
fun canonicalizePath(url: String, baseUrl: Url, baseUrlIsFile: Boolean): String {
var path = url
if (url[0] != '/') {
val basePath = baseUrl.path
if (baseUrlIsFile) {
val lastSlashIndex = basePath.lastIndexOf('/')
val pathBuilder = StringBuilder()
if (lastSlashIndex == -1) {
pathBuilder.append('/')
}
else {
pathBuilder.append(basePath, 0, lastSlashIndex + 1)
}
path = pathBuilder.append(url).toString()
}
else {
path = "$basePath/$url"
}
}
return FileUtil.toCanonicalPath(path, '/')
}
// see canonicalizeUri kotlin impl and https://trac.webkit.org/browser/trunk/Source/WebCore/inspector/front-end/ParsedURL.js completeURL
fun canonicalizeUrl(url: String, baseUrl: Url?, trimFileScheme: Boolean, baseUrlIsFile: Boolean = true): Url {
if (trimFileScheme && url.startsWith(StandardFileSystems.FILE_PROTOCOL_PREFIX)) {
return Urls.newLocalFileUrl(FileUtil.toCanonicalPath(VfsUtilCore.toIdeaUrl(url, true).substring(StandardFileSystems.FILE_PROTOCOL_PREFIX.length), '/'))
}
else if (baseUrl == null || url.contains(URLUtil.SCHEME_SEPARATOR) || url.startsWith("data:") || url.startsWith("blob:") || url.startsWith("javascript:")) {
return Urls.parseEncoded(url) ?: UrlImpl(url)
}
else {
return doCanonicalize(url, baseUrl, baseUrlIsFile, true)
}
}
fun doCanonicalize(url: String, baseUrl: Url, baseUrlIsFile: Boolean, asLocalFileIfAbsoluteAndExists: Boolean): Url {
val path = canonicalizePath(url, baseUrl, baseUrlIsFile)
if ((baseUrl.scheme == null && baseUrl.isInLocalFileSystem) || (asLocalFileIfAbsoluteAndExists && SourceResolver.isAbsolute(path) && File(path).exists())) {
return Urls.newLocalFileUrl(path)
}
else {
return UrlImpl(baseUrl.scheme, baseUrl.authority, path, null)
}
}
@@ -35,50 +35,48 @@ import java.net.InetSocketAddress
import java.util.concurrent.atomic.AtomicReference
abstract class RemoteVmConnection : VmConnection<Vm>() {
private val connectCancelHandler = AtomicReference<Runnable>()
private val connectCancelHandler = AtomicReference<() -> Unit>()
abstract fun createBootstrap(address: InetSocketAddress, vmResult: org.jetbrains.concurrency.AsyncPromise<Vm>): Bootstrap
@JvmOverloads
fun open(address: InetSocketAddress, stopCondition: Condition<Void>? = null) {
setState(ConnectionStatus.WAITING_FOR_CONNECTION, "Connecting to ${address.hostName}:${address.port}")
val future = ApplicationManager.getApplication().executeOnPooledThread(object : Runnable {
override fun run() {
if (Thread.interrupted()) {
return
}
val result = org.jetbrains.concurrency.AsyncPromise<Vm>()
connectCancelHandler.set(Runnable { result.setError("Closed explicitly") })
val connectionPromise = AsyncPromise<Any?>()
connectionPromise.rejected { result.setError(it) }
result
.done {
vm = it
setState(ConnectionStatus.CONNECTED, "Connected to ${connectedAddressToPresentation(address, it)}")
startProcessing()
}
.rejected {
if (it !is ConnectException) {
Promise.logError(LOG, it)
}
setState(ConnectionStatus.CONNECTION_FAILED, it.message)
}
.processed { connectCancelHandler.set(null) }
createBootstrap(address, result).connect(address, connectionPromise, maxAttemptCount = if (stopCondition == null) NettyUtil.DEFAULT_CONNECT_ATTEMPT_COUNT else -1, stopCondition = stopCondition)
val future = ApplicationManager.getApplication().executeOnPooledThread(Runnable {
if (Thread.interrupted()) {
return@Runnable
}
val result = org.jetbrains.concurrency.AsyncPromise<Vm>()
connectCancelHandler.set({ result.setError("Closed explicitly") })
val connectionPromise = AsyncPromise<Any?>()
connectionPromise.rejected { result.setError(it) }
result
.done {
vm = it
setState(ConnectionStatus.CONNECTED, "Connected to ${connectedAddressToPresentation(address, it)}")
startProcessing()
}
.rejected {
if (it !is ConnectException) {
Promise.logError(LOG, it)
}
setState(ConnectionStatus.CONNECTION_FAILED, it.message)
}
.processed { connectCancelHandler.set(null) }
createBootstrap(address, result).connect(address, connectionPromise, maxAttemptCount = if (stopCondition == null) NettyUtil.DEFAULT_CONNECT_ATTEMPT_COUNT else -1, stopCondition = stopCondition)
})
connectCancelHandler.set(Runnable { future.cancel(true) })
connectCancelHandler.set({ future.cancel(true) })
}
protected open fun connectedAddressToPresentation(address: InetSocketAddress, vm: Vm): String = address.hostName + ":" + address.port
protected open fun connectedAddressToPresentation(address: InetSocketAddress, vm: Vm): String = "${address.hostName}:${address.port}"
override fun detachAndClose(): Promise<*> {
try {
connectCancelHandler.getAndSet(null)?.run()
connectCancelHandler.getAndSet(null)?.invoke()
}
finally {
return super.detachAndClose()
@@ -86,7 +84,7 @@ abstract class RemoteVmConnection : VmConnection<Vm>() {
}
}
fun <T> chooseDebuggee(targets: Collection<T>, selectedIndex: Int, itemToString: (T) -> String): org.jetbrains.concurrency.Promise<T> {
fun <T> chooseDebuggee(targets: Collection<T>, selectedIndex: Int, itemToString: (T) -> String): Promise<T> {
if (targets.size == 1) {
return resolvedPromise(targets.first())
}
@@ -1227,7 +1227,7 @@ implicit.numeric.conversion.ignore.widening.conversion.option=Ignore widening co
implicit.numeric.conversion.ignore.char.conversion.option=Ignore conversions from and to char
implicit.numeric.conversion.ignore.constant.conversion.option=Ignore conversions from constants and literals
implicit.numeric.conversion.problem.descriptor=Implicit numeric conversion of <code>#ref</code> from ''{0}'' to ''{1}'' #loc
implicit.numeric.conversion.convert.quickfix=Convert to ''{0}'' literal
implicit.numeric.conversion.convert.quickfix=Convert to ''{0}''
implicit.numeric.conversion.make.explicit.quickfix=Make conversion explicit
long.literals.ending.with.lowercase.l.replace.quickfix=Replace 'l' with 'L'
non.reproducible.math.call.replace.quickfix=Replace with 'StrictMath' call
@@ -1,5 +1,5 @@
/*
* Copyright 2003-2013 Dave Griffith, Bas Leijdekkers
* Copyright 2003-2015 Dave Griffith, Bas Leijdekkers
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -30,7 +30,7 @@ import com.siyeh.ig.PsiReplacementUtil;
import com.siyeh.ig.psiutils.ClassUtils;
import com.siyeh.ig.psiutils.ExpectedTypeUtils;
import com.siyeh.ig.psiutils.ParenthesesUtils;
import gnu.trove.TObjectIntHashMap;
import com.siyeh.ig.psiutils.TypeUtils;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -39,21 +39,6 @@ import javax.swing.*;
public class ImplicitNumericConversionInspection extends BaseInspection {
/**
* @noinspection StaticCollection
*/
private static final gnu.trove.TObjectIntHashMap<PsiType> typePrecisions = new TObjectIntHashMap<PsiType>(7);
static {
typePrecisions.put(PsiType.BYTE, 1);
typePrecisions.put(PsiType.CHAR, 2);
typePrecisions.put(PsiType.SHORT, 2);
typePrecisions.put(PsiType.INT, 3);
typePrecisions.put(PsiType.LONG, 4);
typePrecisions.put(PsiType.FLOAT, 5);
typePrecisions.put(PsiType.DOUBLE, 6);
}
@SuppressWarnings({"PublicField"})
public boolean ignoreWideningConversions = false;
@@ -105,8 +90,9 @@ public class ImplicitNumericConversionInspection extends BaseInspection {
private final String m_name;
ImplicitNumericConversionFix(PsiExpression expression, PsiType expectedType) {
if (isConvertible(expression, expectedType)) {
m_name = InspectionGadgetsBundle.message("implicit.numeric.conversion.convert.quickfix", expectedType.getCanonicalText());
final String convertedExpression = convertExpression(expression, expectedType);
if (convertedExpression != null) {
m_name = InspectionGadgetsBundle.message("implicit.numeric.conversion.convert.quickfix", convertedExpression);
}
else {
m_name = InspectionGadgetsBundle.message("implicit.numeric.conversion.make.explicit.quickfix");
@@ -132,28 +118,28 @@ public class ImplicitNumericConversionInspection extends BaseInspection {
if (expectedType == null) {
return;
}
if (isConvertible(expression, expectedType)) {
final String newExpression = convertExpression(expression, expectedType);
if (newExpression == null) {
return;
}
PsiReplacementUtil.replaceExpression(expression, newExpression);
final String convertedExpression = convertExpression(expression, expectedType);
if (convertedExpression != null) {
PsiReplacementUtil.replaceExpression(expression, convertedExpression);
}
else {
final String newExpression;
final String castExpression;
if (ParenthesesUtils.getPrecedence(expression) <= ParenthesesUtils.TYPE_CAST_PRECEDENCE) {
newExpression = '(' + expectedType.getCanonicalText() + ')' + expression.getText();
castExpression = '(' + expectedType.getCanonicalText() + ')' + expression.getText();
}
else {
newExpression = '(' + expectedType.getCanonicalText() + ")(" + expression.getText() + ')';
castExpression = '(' + expectedType.getCanonicalText() + ")(" + expression.getText() + ')';
}
PsiReplacementUtil.replaceExpression(expression, newExpression);
PsiReplacementUtil.replaceExpression(expression, castExpression);
}
}
@Nullable
@NonNls
private static String convertExpression(PsiExpression expression, PsiType expectedType) {
if (!(expression instanceof PsiLiteralExpression) && !isNegatedLiteral(expression)) {
return null;
}
final PsiType expressionType = expression.getType();
if (expressionType == null) {
return null;
@@ -192,27 +178,7 @@ public class ImplicitNumericConversionInspection extends BaseInspection {
final int length = text.length();
return text.substring(0, length - 1);
}
return null; //can't happen
}
private static boolean isConvertible(PsiExpression expression, PsiType expectedType) {
if (!(expression instanceof PsiLiteralExpression) && !isNegatedLiteral(expression)) {
return false;
}
final PsiType expressionType = expression.getType();
if (expressionType == null) {
return false;
}
if (hasLowerPrecision(expectedType, expressionType)) {
return false;
}
if (isIntegral(expressionType) && isIntegral(expectedType)) {
return true;
}
if (isIntegral(expressionType) && isFloatingPoint(expectedType)) {
return true;
}
return isFloatingPoint(expressionType) && isFloatingPoint(expectedType);
return null;
}
private static boolean isNegatedLiteral(PsiExpression expression) {
@@ -328,7 +294,7 @@ public class ImplicitNumericConversionInspection extends BaseInspection {
if (expressionType.equals(expectedType)) {
return;
}
if (ignoreWideningConversions && hasLowerPrecision(expressionType, expectedType)) {
if (ignoreWideningConversions && TypeUtils.isNarrowingConversion(expressionType, expectedType)) {
return;
}
if (ignoreCharConversions && PsiType.CHAR.equals(expectedType)) {
@@ -363,10 +329,4 @@ public class ImplicitNumericConversionInspection extends BaseInspection {
return CommonClassNames.JAVA_LANG_STRING.equals(className);
}
}
static boolean hasLowerPrecision(PsiType expressionType, PsiType expectedType) {
final int operandPrecision = typePrecisions.get(expressionType);
final int castPrecision = typePrecisions.get(expectedType);
return operandPrecision <= castPrecision;
}
}
@@ -66,10 +66,13 @@ public class TypeUtils {
return getType(CommonClassNames.JAVA_LANG_STRING, context);
}
public static boolean isNarrowingConversion(@NotNull PsiType operandType, @NotNull PsiType castType) {
final Integer operandPrecision = typePrecisions.get(operandType);
final Integer castPrecision = typePrecisions.get(castType);
return operandPrecision != null && castPrecision != null && operandPrecision.intValue() > castPrecision.intValue();
/**
* JLS 5.1.3. Narrowing Primitive Conversion
*/
public static boolean isNarrowingConversion(@Nullable PsiType sourceType, @Nullable PsiType targetType) {
final Integer sourcePrecision = typePrecisions.get(sourceType);
final Integer targetPrecision = typePrecisions.get(targetType);
return sourcePrecision != null && targetPrecision != null && targetPrecision.intValue() < sourcePrecision.intValue();
}
public static boolean isJavaLangObject(@Nullable PsiType targetType) {
@@ -1,6 +1,6 @@
<html>
<body>
Reports any cast operations between built-in numeric types which may
Reports any cast operations between primitive numeric types which may
result in loss of precision. Such casts are not necessarily a problem, but may result in difficult to
trace bugs if the loss of precision is unexpected.
<!-- tooltip end -->
@@ -9,7 +9,7 @@ Use the checkbox below to indicate that this inspection should ignore casts from
<b>int</b> to <b>char</b>.
This type of cast is often used when implementing I/O operations, because the
<b>read()</b> method of the class
<b>java.io.Reader</b> returns an <b>int</b>l
<b>java.io.Reader</b> returns an <b>int</b>.
<p>
</body>
+5 -2
View File
@@ -556,14 +556,17 @@ class PyDB:
self._lock_running_thread_ids.acquire()
try:
for t in all_threads:
thread_id = GetThreadId(t)
if getattr(t, 'is_pydev_daemon_thread', False):
pass # I.e.: skip the DummyThreads created from pydev daemon threads
elif isinstance(t, PyDBDaemonThread):
pydev_log.error_once('Error in debugger: Found PyDBDaemonThread not marked with is_pydev_daemon_thread=True.\n')
elif isThreadAlive(t):
if not self._running_thread_ids:
thread_id = GetThreadId(t, True)
curr_thread_id = GetThreadId(threadingCurrentThread())
else:
thread_id = GetThreadId(t)
program_threads_alive[thread_id] = t
if not DictContains(self._running_thread_ids, thread_id):
+22 -13
View File
@@ -195,29 +195,38 @@ class NextId:
_nextThreadId = NextId()
#=======================================================================================================================
# GetPid
#=======================================================================================================================
def GetPid():
try:
return os.getpid()
except AttributeError:
try:
#Jython does not have it!
import java.lang.management.ManagementFactory #@UnresolvedImport -- just for jython
pid = java.lang.management.ManagementFactory.getRuntimeMXBean().getName()
return pid.replace('@', '_')
except:
#ok, no pid available (will be unable to debug multiple processes)
return '000001'
#=======================================================================================================================
# GetThreadId
#=======================================================================================================================
def GetThreadId(thread):
def GetThreadId(thread, update_pydevd_id=False):
try:
if update_pydevd_id:
del thread.__pydevd_id__
return thread.__pydevd_id__
except AttributeError:
_nextThreadIdLock.acquire()
try:
#We do a new check with the lock in place just to be sure that nothing changed
if not hasattr(thread, '__pydevd_id__'):
try:
pid = os.getpid()
except AttributeError:
try:
#Jython does not have it!
import java.lang.management.ManagementFactory #@UnresolvedImport -- just for jython
pid = java.lang.management.ManagementFactory.getRuntimeMXBean().getName()
pid = pid.replace('@', '_')
except:
#ok, no pid available (will be unable to debug multiple processes)
pid = '000001'
pid = GetPid()
thread.__pydevd_id__ = 'pid%s_seq%s' % (pid, _nextThreadId())
finally:
_nextThreadIdLock.release()