2020import java .nio .charset .Charset ;
2121import java .nio .file .Files ;
2222import java .nio .file .Paths ;
23- import java .util .ArrayList ;
2423import java .util .HashMap ;
2524import java .util .Map ;
2625import java .util .logging .Level ;
2726import java .util .logging .Logger ;
2827
2928import org .eclipse .core .resources .IResource ;
29+ import org .eclipse .debug .core .sourcelookup .ISourceContainer ;
3030import org .eclipse .jdt .core .IBuffer ;
3131import org .eclipse .jdt .core .IClassFile ;
3232import org .eclipse .jdt .core .IJavaElement ;
33- import org .eclipse .jdt .core .IJavaProject ;
34- import org .eclipse .jdt .core .IType ;
3533import org .eclipse .jdt .core .ITypeRoot ;
3634import org .eclipse .jdt .core .JavaCore ;
3735import org .eclipse .jdt .core .JavaModelException ;
3836import org .eclipse .jdt .core .dom .AST ;
3937import org .eclipse .jdt .core .dom .ASTParser ;
4038import org .eclipse .jdt .core .dom .CompilationUnit ;
41- import org .eclipse .jdt .core .search .IJavaSearchConstants ;
42- import org .eclipse .jdt .core .search .IJavaSearchScope ;
43- import org .eclipse .jdt .core .search .SearchEngine ;
44- import org .eclipse .jdt .core .search .SearchMatch ;
45- import org .eclipse .jdt .core .search .SearchParticipant ;
46- import org .eclipse .jdt .core .search .SearchPattern ;
47- import org .eclipse .jdt .core .search .SearchRequestor ;
4839import org .eclipse .jdt .internal .debug .core .breakpoints .ValidBreakpointLocationLocator ;
4940
5041import com .microsoft .java .debug .core .Configuration ;
@@ -58,6 +49,7 @@ public class JdtSourceLookUpProvider implements ISourceLookUpProvider {
5849 private static final Logger logger = Logger .getLogger (Configuration .LOGGER_NAME );
5950 private static final String JDT_SCHEME = "jdt" ;
6051 private static final String PATH_SEPARATOR = "/" ;
52+ private ISourceContainer [] sourceContainers = null ;
6153
6254 private HashMap <String , Object > options = new HashMap <String , Object >();
6355
@@ -67,6 +59,10 @@ public void initialize(IDebugSession debugSession, Map<String, Object> props) {
6759 throw new IllegalArgumentException ("argument is null" );
6860 }
6961 options .putAll (props );
62+ // During initialization, trigger a background job to load the source containers to improve the perf.
63+ new Thread (() -> {
64+ getSourceContainers ();
65+ }).start ();
7066 }
7167
7268 @ Override
@@ -164,17 +160,32 @@ public String[] getFullyQualifiedName(String uri, int[] lines, int[] columns) th
164160
165161 @ Override
166162 public String getSourceFileURI (String fullyQualifiedName , String sourcePath ) {
167- if (fullyQualifiedName == null ) {
168- throw new IllegalArgumentException ( "fullyQualifiedName is null" ) ;
163+ if (sourcePath == null ) {
164+ return null ;
169165 }
170- // Jdt Search Engine doesn't support searching anonymous class or local type directly.
171- // But because the inner class and anonymous class have the same java file as the enclosing type,
172- // search their enclosing type instead.
173- if (fullyQualifiedName .indexOf ("$" ) >= 0 ) {
174- return searchDeclarationFileByFqn (AdapterUtils .parseEnclosingType (fullyQualifiedName ));
175- } else {
176- return searchDeclarationFileByFqn (fullyQualifiedName );
166+
167+ Object sourceElement = JdtUtils .findSourceElement (sourcePath , getSourceContainers ());
168+ if (sourceElement instanceof IResource ) {
169+ return getFileURI ((IResource ) sourceElement );
170+ } else if (sourceElement instanceof IClassFile ) {
171+ try {
172+ IClassFile file = (IClassFile ) sourceElement ;
173+ if (file .getBuffer () != null ) {
174+ return getFileURI (file );
175+ }
176+ } catch (JavaModelException e ) {
177+ // do nothing.
178+ }
179+ }
180+ return null ;
181+ }
182+
183+ private synchronized ISourceContainer [] getSourceContainers () {
184+ if (sourceContainers == null ) {
185+ sourceContainers = JdtUtils .getSourceContainers ((String ) options .get (Constants .PROJECTNAME ));
177186 }
187+
188+ return sourceContainers ;
178189 }
179190
180191 @ Override
@@ -204,50 +215,6 @@ private String getContents(IClassFile cf) {
204215 return source ;
205216 }
206217
207- private String searchDeclarationFileByFqn (String fullyQualifiedName ) {
208- String projectName = (String ) options .get (Constants .PROJECTNAME );
209- IJavaProject project = JdtUtils .getJavaProject (projectName );
210- IJavaSearchScope searchScope = createSearchScope (project );
211- SearchPattern pattern = SearchPattern .createPattern (
212- fullyQualifiedName ,
213- IJavaSearchConstants .TYPE ,
214- IJavaSearchConstants .DECLARATIONS ,
215- SearchPattern .R_EXACT_MATCH );
216-
217- ArrayList <String > uris = new ArrayList <String >();
218-
219- SearchRequestor requestor = new SearchRequestor () {
220- @ Override
221- public void acceptSearchMatch (SearchMatch match ) {
222- Object element = match .getElement ();
223- if (element instanceof IType ) {
224- IType type = (IType ) element ;
225- if (type .isBinary ()) {
226- try {
227- // let the search engine to ignore those class files without attached source.
228- if (type .getSource () != null ) {
229- uris .add (getFileURI (type .getClassFile ()));
230- }
231- } catch (JavaModelException e ) {
232- // ignore
233- }
234- } else {
235- uris .add (getFileURI (type .getResource ()));
236- }
237- }
238- }
239- };
240- SearchEngine searchEngine = new SearchEngine ();
241- try {
242- searchEngine .search (pattern , new SearchParticipant [] {
243- SearchEngine .getDefaultSearchParticipant ()
244- }, searchScope , requestor , null /* progress monitor */ );
245- } catch (Exception e ) {
246- logger .log (Level .SEVERE , String .format ("Search engine failed: %s" , e .toString ()), e );
247- }
248- return uris .size () == 0 ? null : uris .get (0 );
249- }
250-
251218 private static String getFileURI (IClassFile classFile ) {
252219 String packageName = classFile .getParent ().getElementName ();
253220 String jarName = classFile .getParent ().getParent ().getElementName ();
@@ -288,14 +255,6 @@ private static IClassFile resolveClassFile(String uriString) {
288255 return null ;
289256 }
290257
291- private static IJavaSearchScope createSearchScope (IJavaProject project ) {
292- if (project == null ) {
293- return SearchEngine .createWorkspaceScope ();
294- }
295- return SearchEngine .createJavaSearchScope (new IJavaProject [] {project },
296- IJavaSearchScope .SOURCES | IJavaSearchScope .APPLICATION_LIBRARIES | IJavaSearchScope .SYSTEM_LIBRARIES );
297- }
298-
299258 private static String readFile (String filePath , Charset cs ) {
300259 StringBuilder builder = new StringBuilder ();
301260 try (BufferedReader bufferReader =
@@ -314,4 +273,5 @@ private static String readFile(String filePath, Charset cs) {
314273 }
315274 return builder .toString ();
316275 }
276+
317277}
0 commit comments