4646import org .eclipse .jdt .core .IJavaElement ;
4747import org .eclipse .jdt .core .IJavaModelMarker ;
4848import org .eclipse .jdt .core .IJavaProject ;
49+ import org .eclipse .jdt .core .IMember ;
4950import org .eclipse .jdt .core .IPackageFragment ;
5051import org .eclipse .jdt .core .IProblemRequestor ;
52+ import org .eclipse .jdt .core .ISourceRange ;
53+ import org .eclipse .jdt .core .IType ;
5154import org .eclipse .jdt .core .JavaCore ;
5255import org .eclipse .jdt .core .JavaModelException ;
5356import org .eclipse .jdt .core .WorkingCopyOwner ;
5457import org .eclipse .jdt .core .compiler .IProblem ;
5558import org .eclipse .jdt .core .dom .CompilationUnit ;
59+ import org .eclipse .jdt .core .dom .Modifier ;
5660import org .eclipse .jdt .core .manipulation .CoreASTProvider ;
5761import org .eclipse .jdt .internal .core .OpenableElementInfo ;
5862import org .eclipse .jdt .internal .core .PackageFragment ;
5963import org .eclipse .jdt .ls .core .internal .DocumentAdapter ;
64+ import org .eclipse .jdt .ls .core .internal .IConstants ;
6065import org .eclipse .jdt .ls .core .internal .JDTUtils ;
6166import org .eclipse .jdt .ls .core .internal .JavaLanguageServerPlugin ;
6267import org .eclipse .jdt .ls .core .internal .JobHelpers ;
68+ import org .eclipse .jdt .ls .core .internal .Messages ;
6369import org .eclipse .jdt .ls .core .internal .MovingAverage ;
6470import org .eclipse .jdt .ls .core .internal .ProjectUtils ;
71+ import org .eclipse .jdt .ls .core .internal .ResourceUtils ;
72+ import org .eclipse .jdt .ls .core .internal .corrections .CorrectionMessages ;
6573import org .eclipse .jdt .ls .core .internal .corrections .DiagnosticsHelper ;
6674import org .eclipse .jdt .ls .core .internal .managers .InvisibleProjectImporter ;
6775import org .eclipse .jdt .ls .core .internal .managers .ProjectsManager ;
@@ -103,6 +111,9 @@ public abstract class BaseDocumentLifeCycleHandler {
103111 */
104112 private static final long PUBLISH_DIAGNOSTICS_MAX_DEBOUNCE = 2000 ; /*ms*/
105113
114+ public static final String RENAME_REFERENCE_MARKER_ID = IConstants .PLUGIN_ID + ".renameReferenceMarker" ;
115+ public static final int RENAME_REFERENCE_PROBLEM_ID = IProblem .Syntax + 2000 ;
116+
106117 private CoreASTProvider sharedASTProvider ;
107118 private WorkspaceJob validationTimer ;
108119 private WorkspaceJob publishDiagnosticsJob ;
@@ -111,6 +122,9 @@ public abstract class BaseDocumentLifeCycleHandler {
111122 private MovingAverage movingAverageForValidation = new MovingAverage (DOCUMENT_LIFECYCLE_MAX_DEBOUNCE );
112123 private MovingAverage movingAverageForDiagnostics = new MovingAverage (PUBLISH_DIAGNOSTICS_MIN_DEBOUNCE );
113124
125+ private Map <String , List <MemberInfo >> documentMemberInfos = new HashMap <>();
126+ private Map <String , List <IMarker >> documentMarkers = new HashMap <>();
127+
114128 public BaseDocumentLifeCycleHandler (boolean delayValidation ) {
115129 this .sharedASTProvider = CoreASTProvider .getInstance ();
116130 if (delayValidation ) {
@@ -303,11 +317,18 @@ public IProblemRequestor getProblemRequestor(ICompilationUnit workingCopy) {
303317
304318 };
305319 int flags = ICompilationUnit .FORCE_PROBLEM_DETECTION | ICompilationUnit .ENABLE_BINDINGS_RECOVERY | ICompilationUnit .ENABLE_STATEMENTS_RECOVERY ;
320+ if (JavaLanguageServerPlugin .getPreferencesManager ().getPreferences ().getRenameReferencesEnabled ()) {
321+ provideRenameReferencesMarkers (unit );
322+ }
306323 unit .reconcile (ICompilationUnit .NO_AST , flags , wcOwner , monitor );
307324 }
308325
309326 public void didClose (DidCloseTextDocumentParams params ) {
310327 documentVersions .remove (params .getTextDocument ().getUri ());
328+ ICompilationUnit cu = JDTUtils .resolveCompilationUnit (params .getTextDocument ().getUri ());
329+ if (cu != null ) {
330+ this .documentMemberInfos .remove (cu .getResource ().getLocationURI ().toString ());
331+ }
311332 ISchedulingRule rule = JDTUtils .getRule (params .getTextDocument ().getUri ());
312333 try {
313334 ResourcesPlugin .getWorkspace ().run (new IWorkspaceRunnable () {
@@ -410,6 +431,9 @@ public ICompilationUnit handleOpen(DidOpenTextDocumentParams params) {
410431 // see https://github.com/redhat-developer/vscode-java/issues/274
411432 checkPackageDeclaration (uri , unit );
412433 inferInvisibleProjectSourceRoot (unit );
434+ if (JavaLanguageServerPlugin .getPreferencesManager ().getPreferences ().getRenameReferencesEnabled ()) {
435+ this .documentMemberInfos .put (unit .getResource ().getLocationURI ().toString (), this .getMemberInfos (unit ));
436+ }
413437 } catch (JavaModelException e ) {
414438 JavaLanguageServerPlugin .logException ("Error while opening document. URI: " + uri , e );
415439 }
@@ -467,6 +491,87 @@ public ICompilationUnit handleChanged(DidChangeTextDocumentParams params) {
467491 return unit ;
468492 }
469493
494+ private void provideRenameReferencesMarkers (ICompilationUnit unit ) {
495+ String uri = unit .getResource ().getLocationURI ().toString ();
496+ List <MemberInfo > memberInfos = this .getMemberInfos (unit );
497+ try {
498+ if (this .documentMemberInfos .containsKey (uri )) {
499+ // delete existing markers
500+ List <IMarker > currentMarkers = this .documentMarkers .get (uri );
501+ if (currentMarkers != null ) {
502+ unit .getResource ().deleteMarkers (RENAME_REFERENCE_MARKER_ID , false , IResource .DEPTH_ONE );
503+ currentMarkers .clear ();
504+ } else {
505+ currentMarkers = new ArrayList <>();
506+ this .documentMarkers .put (uri , currentMarkers );
507+ }
508+ List <MemberInfo > cacheMemberInfos = this .documentMemberInfos .get (uri );
509+ if (cacheMemberInfos .size () == memberInfos .size ()) {
510+ for (int i = 0 ; i < memberInfos .size (); i ++) {
511+ MemberInfo memberInfo = memberInfos .get (i );
512+ String name = memberInfo .getName ();
513+ MemberInfo cacheMemberInfo = cacheMemberInfos .get (i );
514+ if (name == null ) {
515+ this .documentMemberInfos .put (uri , memberInfos );
516+ break ;
517+ }
518+ if (cacheMemberInfo .getName ().equals (name )) {
519+ continue ;
520+ }
521+ String message = Messages .format (CorrectionMessages .LocalCorrectionsSubProcessor_manual_rename_label , new String []{ cacheMemberInfo .getName (), name });
522+ IMarker marker = ResourceUtils .createInfoMarker (RENAME_REFERENCE_MARKER_ID , unit .getResource (), message , RENAME_REFERENCE_PROBLEM_ID , memberInfo .getNameRange ().getOffset (), memberInfo .getNameRange ().getOffset () + memberInfo .getNameRange ().getLength ());
523+ marker .setAttribute ("originalName" , cacheMemberInfo .getName ());
524+ marker .setAttribute ("newName" , name );
525+ currentMarkers .add (marker );
526+ }
527+ } else {
528+ // update the storage names list
529+ this .documentMemberInfos .put (uri , memberInfos );
530+ }
531+ } else {
532+ // initialize the storage names list
533+ this .documentMemberInfos .put (uri , memberInfos );
534+ }
535+ } catch (CoreException e ) {
536+ // Do nothing
537+ }
538+ }
539+
540+ private List <MemberInfo > getMemberInfos (ICompilationUnit unit ) {
541+ List <MemberInfo > members = new ArrayList <>();
542+ try {
543+ IType [] types = unit .getAllTypes ();
544+ for (IType type : types ) {
545+ for (IJavaElement child : type .getChildren ()) {
546+ if (child instanceof IMember member && Modifier .isPublic (member .getFlags ())) {
547+ members .add (new MemberInfo (member .getElementName (), member .getNameRange ()));
548+ }
549+ }
550+ }
551+ } catch (JavaModelException e ) {
552+ // do nothing
553+ }
554+ return members ;
555+ }
556+
557+ public void cleanRenameReferenceCache (ICompilationUnit unit ) {
558+ if (unit == null ) {
559+ return ;
560+ }
561+ IResource resource = unit .getResource ();
562+ if (resource == null ) {
563+ return ;
564+ }
565+ String uri = resource .getLocationURI ().toString ();
566+ this .documentMemberInfos .remove (uri );
567+ this .documentMarkers .remove (uri );
568+ try {
569+ unit .getResource ().deleteMarkers (RENAME_REFERENCE_MARKER_ID , false , IResource .DEPTH_ONE );
570+ } catch (CoreException e ) {
571+ // do nothing
572+ }
573+ }
574+
470575 public ICompilationUnit handleClosed (DidCloseTextDocumentParams params ) {
471576 String uri = params .getTextDocument ().getUri ();
472577 ICompilationUnit unit = JDTUtils .resolveCompilationUnit (uri );
@@ -743,4 +848,22 @@ public void checkChanged() {
743848
744849 }
745850
851+ private static class MemberInfo {
852+ private String name ;
853+ private ISourceRange nameRange ;
854+
855+ public MemberInfo (String name , ISourceRange nameRange ) {
856+ this .name = name ;
857+ this .nameRange = nameRange ;
858+ }
859+
860+ public String getName () {
861+ return name ;
862+ }
863+
864+ public ISourceRange getNameRange () {
865+ return nameRange ;
866+ }
867+ }
868+
746869}
0 commit comments