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;
@NotNull
GlobalSearchScope getSearchScope();
+ @Nullable
+ default Sdk getAlternativeJre() {
+ return null;
+ }
+
boolean isRemote();
RemoteConnection getRemoteConnection();
*/
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;
public String getSessionName() {
return environment.getRunProfile().getName();
}
+
+ @Nullable
+ @Override
+ public Sdk getAlternativeJre() {
+ return AlternativeJreIndexHelper.getAlternativeJre(environment.getRunProfile());
+ }
}
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;
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;
//}
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);
+ }
}
}
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>>() {
--- /dev/null
+/*
+ * 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));
+ }
+}
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;
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
/*
- * 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.
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;
--- /dev/null
+/*
+ * 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();
+}
<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"/>