mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
IDEA-29246 Debug with alternative JRE - JDK source is incorrect
This commit is contained in:
@@ -18,6 +18,7 @@ package com.intellij.debugger;
|
||||
import com.intellij.execution.ExecutionException;
|
||||
import com.intellij.execution.ExecutionResult;
|
||||
import com.intellij.execution.configurations.RemoteConnection;
|
||||
import com.intellij.openapi.projectRoots.Sdk;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -36,6 +37,11 @@ public interface DebugEnvironment {
|
||||
@NotNull
|
||||
GlobalSearchScope getSearchScope();
|
||||
|
||||
@Nullable
|
||||
default Sdk getAlternativeJre() {
|
||||
return null;
|
||||
}
|
||||
|
||||
boolean isRemote();
|
||||
|
||||
RemoteConnection getRemoteConnection();
|
||||
|
||||
@@ -15,14 +15,17 @@
|
||||
*/
|
||||
package com.intellij.debugger;
|
||||
|
||||
import com.intellij.debugger.impl.AlternativeJreIndexHelper;
|
||||
import com.intellij.debugger.impl.DebuggerManagerImpl;
|
||||
import com.intellij.debugger.settings.DebuggerSettings;
|
||||
import com.intellij.execution.ExecutionException;
|
||||
import com.intellij.execution.ExecutionResult;
|
||||
import com.intellij.execution.configurations.*;
|
||||
import com.intellij.execution.runners.ExecutionEnvironment;
|
||||
import com.intellij.openapi.projectRoots.Sdk;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class DefaultDebugEnvironment implements DebugEnvironment {
|
||||
private final GlobalSearchScope mySearchScope;
|
||||
@@ -87,4 +90,10 @@ public class DefaultDebugEnvironment implements DebugEnvironment {
|
||||
public String getSessionName() {
|
||||
return environment.getRunProfile().getName();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Sdk getAlternativeJre() {
|
||||
return AlternativeJreIndexHelper.getAlternativeJre(environment.getRunProfile());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,13 +20,16 @@ import com.intellij.debugger.NoDataException;
|
||||
import com.intellij.debugger.PositionManager;
|
||||
import com.intellij.debugger.SourcePosition;
|
||||
import com.intellij.debugger.engine.evaluation.EvaluateException;
|
||||
import com.intellij.debugger.impl.AlternativeJreIndexHelper;
|
||||
import com.intellij.debugger.impl.DebuggerUtilsEx;
|
||||
import com.intellij.debugger.jdi.VirtualMachineProxyImpl;
|
||||
import com.intellij.debugger.requests.ClassPrepareRequestor;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.project.IndexNotReadyException;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.projectRoots.Sdk;
|
||||
import com.intellij.openapi.util.Computable;
|
||||
import com.intellij.openapi.util.NullableComputable;
|
||||
import com.intellij.openapi.util.Ref;
|
||||
@@ -35,8 +38,11 @@ import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.openapi.vfs.VirtualFileManager;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.impl.compiled.ClsClassImpl;
|
||||
import com.intellij.psi.impl.java.stubs.index.JavaStubIndexKeys;
|
||||
import com.intellij.psi.search.FilenameIndex;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.psi.stubs.StubIndex;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.util.DocumentUtil;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
@@ -351,13 +357,39 @@ public class PositionManagerImpl implements PositionManager, MultiRequestPositio
|
||||
//}
|
||||
|
||||
final String originalQName = refType.name();
|
||||
final GlobalSearchScope searchScope = myDebugProcess.getSearchScope();
|
||||
PsiClass psiClass = DebuggerUtils.findClass(originalQName, project, searchScope); // try to lookup original name first
|
||||
|
||||
PsiClass psiClass = null;
|
||||
|
||||
// first check alternative jre if any
|
||||
Sdk alternativeJre = myDebugProcess.getSession().getAlternativeJre();
|
||||
if (alternativeJre != null) {
|
||||
try {
|
||||
psiClass = ContainerUtil.getFirstItem(StubIndex.getElements(JavaStubIndexKeys.CLASS_FQN,
|
||||
originalQName.hashCode(),
|
||||
project,
|
||||
AlternativeJreIndexHelper.getSearchScope(alternativeJre),
|
||||
PsiClass.class));
|
||||
|
||||
if (psiClass instanceof ClsClassImpl) { //try to find sources
|
||||
PsiFile psiSource = findSourceFile((ClsClassImpl)psiClass, alternativeJre);
|
||||
if (psiSource != null) {
|
||||
return psiSource;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (IndexNotReadyException ignored) {
|
||||
}
|
||||
}
|
||||
|
||||
if (psiClass == null) {
|
||||
int dollar = originalQName.indexOf('$');
|
||||
if (dollar > 0) {
|
||||
final String qName = originalQName.substring(0, dollar);
|
||||
psiClass = DebuggerUtils.findClass(qName, project, searchScope);
|
||||
GlobalSearchScope searchScope = myDebugProcess.getSearchScope();
|
||||
psiClass = DebuggerUtils.findClass(originalQName, project, searchScope); // try to lookup original name first
|
||||
if (psiClass == null) {
|
||||
int dollar = originalQName.indexOf('$');
|
||||
if (dollar > 0) {
|
||||
final String qName = originalQName.substring(0, dollar);
|
||||
psiClass = DebuggerUtils.findClass(qName, project, searchScope);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -393,6 +425,24 @@ public class PositionManagerImpl implements PositionManager, MultiRequestPositio
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static PsiFile findSourceFile(ClsClassImpl psiClass, Sdk alternativeJre) {
|
||||
String sourceFileName = psiClass.getSourceFileName();
|
||||
String packageName = ((PsiClassOwner)psiClass.getContainingFile()).getPackageName();
|
||||
String relativePath = packageName.isEmpty() ? sourceFileName : packageName.replace('.', '/') + '/' + sourceFileName;
|
||||
|
||||
for (VirtualFile file : AlternativeJreIndexHelper.getSourceRoots(alternativeJre)) {
|
||||
VirtualFile source = file.findFileByRelativePath(relativePath);
|
||||
if (source != null && source.isValid()) {
|
||||
PsiFile psiSource = psiClass.getManager().findFile(source);
|
||||
if (psiSource instanceof PsiClassOwner) {
|
||||
return psiSource;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public List<ReferenceType> getAllClasses(@NotNull final SourcePosition position) throws NoDataException {
|
||||
return ApplicationManager.getApplication().runReadAction(new Computable<List<ReferenceType>>() {
|
||||
|
||||
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
* Copyright 2000-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.debugger.impl;
|
||||
|
||||
import com.intellij.execution.RunManager;
|
||||
import com.intellij.execution.configurations.ConfigurationWithAlternativeJre;
|
||||
import com.intellij.execution.configurations.RunConfiguration;
|
||||
import com.intellij.execution.configurations.RunProfile;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.projectRoots.ProjectJdkTable;
|
||||
import com.intellij.openapi.projectRoots.Sdk;
|
||||
import com.intellij.openapi.roots.OrderRootType;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.psi.search.NonClasspathDirectoriesScope;
|
||||
import com.intellij.util.containers.SmartHashSet;
|
||||
import com.intellij.util.indexing.IndexableSetContributor;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author egor
|
||||
*/
|
||||
public class AlternativeJreIndexHelper extends IndexableSetContributor {
|
||||
@NotNull
|
||||
@Override
|
||||
public Set<VirtualFile> getAdditionalRootsToIndex() {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Set<VirtualFile> getAdditionalProjectRootsToIndex(@NotNull Project project) {
|
||||
SmartHashSet<VirtualFile> res = new SmartHashSet<>();
|
||||
for (RunConfiguration configuration : RunManager.getInstance(project).getAllConfigurationsList()) {
|
||||
Sdk jre = getAlternativeJre(configuration);
|
||||
if (jre != null) {
|
||||
res.addAll(getClassRoots(jre));
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static Sdk getAlternativeJre(RunProfile profile) {
|
||||
if (profile instanceof ConfigurationWithAlternativeJre) {
|
||||
ConfigurationWithAlternativeJre appConfig = (ConfigurationWithAlternativeJre)profile;
|
||||
if (appConfig.isAlternativeJrePathEnabled()) {
|
||||
return ProjectJdkTable.getInstance().findJdk(appConfig.getAlternativeJrePath());
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static Collection<VirtualFile> getClassRoots(@NotNull Sdk jre) {
|
||||
return Arrays.asList(jre.getRootProvider().getFiles(OrderRootType.CLASSES));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static Collection<VirtualFile> getSourceRoots(@NotNull Sdk jre) {
|
||||
return Arrays.asList(jre.getRootProvider().getFiles(OrderRootType.SOURCES));
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static GlobalSearchScope getSearchScope(@NotNull Sdk jre) {
|
||||
return new NonClasspathDirectoriesScope(getClassRoots(jre));
|
||||
}
|
||||
}
|
||||
@@ -33,7 +33,9 @@ import com.intellij.execution.runners.JavaPatchableProgramRunner;
|
||||
import com.intellij.execution.ui.RunContentDescriptor;
|
||||
import com.intellij.openapi.fileEditor.FileDocumentManager;
|
||||
import com.intellij.openapi.options.SettingsEditor;
|
||||
import com.intellij.openapi.project.DumbService;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.util.indexing.UnindexedFilesUpdater;
|
||||
import com.intellij.xdebugger.XDebugProcess;
|
||||
import com.intellij.xdebugger.XDebugProcessStarter;
|
||||
import com.intellij.xdebugger.XDebugSession;
|
||||
@@ -117,6 +119,11 @@ public class GenericDebuggerRunner extends JavaPatchableProgramRunner<GenericDeb
|
||||
|
||||
final DebugProcessImpl debugProcess = debuggerSession.getProcess();
|
||||
|
||||
// index alternative jdk if needed
|
||||
if (AlternativeJreIndexHelper.getAlternativeJre(env.getRunProfile()) != null) {
|
||||
DumbService.getInstance(debuggerSession.getProject()).queueTask(new UnindexedFilesUpdater(debuggerSession.getProject(), false));
|
||||
}
|
||||
|
||||
return XDebuggerManager.getInstance(env.getProject()).startSession(env, new XDebugProcessStarter() {
|
||||
@Override
|
||||
@NotNull
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2015 JetBrains s.r.o.
|
||||
* Copyright 2000-2016 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.
|
||||
@@ -45,7 +45,7 @@ import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class ApplicationConfiguration extends ModuleBasedConfiguration<JavaRunConfigurationModule>
|
||||
implements CommonJavaRunConfigurationParameters, SingleClassConfiguration, RefactoringListenerProvider {
|
||||
implements CommonJavaRunConfigurationParameters, SingleClassConfiguration, RefactoringListenerProvider, ConfigurationWithAlternativeJre {
|
||||
|
||||
public String MAIN_CLASS_NAME;
|
||||
public String VM_PARAMETERS;
|
||||
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright 2000-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.execution.configurations;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* @author egor
|
||||
*/
|
||||
public interface ConfigurationWithAlternativeJre {
|
||||
boolean isAlternativeJrePathEnabled();
|
||||
|
||||
@Nullable
|
||||
String getAlternativeJrePath();
|
||||
}
|
||||
@@ -1627,6 +1627,7 @@
|
||||
<debugger.syntheticProvider implementation="com.intellij.debugger.engine.DefaultSyntheticProvider"/>
|
||||
<debugger.sourcePositionProvider implementation="com.intellij.debugger.engine.DefaultSourcePositionProvider" order="last"/>
|
||||
<debugger.sourcePositionHighlighter implementation="com.intellij.debugger.engine.JavaSourcePositionHighlighter"/>
|
||||
<indexedRootsProvider implementation="com.intellij.debugger.impl.AlternativeJreIndexHelper"/>
|
||||
|
||||
<debugger.nodeRenderer implementation="com.intellij.debugger.ui.tree.render.ColorObjectRenderer"/>
|
||||
<debugger.nodeRenderer implementation="com.intellij.debugger.ui.tree.render.ImageObjectRenderer"/>
|
||||
|
||||
Reference in New Issue
Block a user