mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Merge remote-tracking branch 'origin/master'
This commit is contained in:
+15
-7
@@ -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;
|
||||
}
|
||||
|
||||
+4
-6
@@ -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(';');
|
||||
|
||||
+5
@@ -37,4 +37,9 @@ class a {
|
||||
void cf2(a aa) {
|
||||
aa.f = f;
|
||||
}
|
||||
|
||||
void m() {
|
||||
double m = 1.5;
|
||||
m = (double) (int) m;
|
||||
}
|
||||
}
|
||||
|
||||
+9
@@ -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)) {
|
||||
}
|
||||
}
|
||||
}
|
||||
+11
@@ -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);
|
||||
|
||||
+3
-1
@@ -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
|
||||
}
|
||||
|
||||
+86
-110
@@ -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)
|
||||
}
|
||||
}
|
||||
+30
-32
@@ -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())
|
||||
}
|
||||
|
||||
+1
-1
@@ -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
|
||||
|
||||
+17
-57
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
+7
-4
@@ -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>
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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()
|
||||
|
||||
Reference in New Issue
Block a user