Giter Site home page Giter Site logo

jetbrains-research / refactorinsight Goto Github PK

View Code? Open in Web Editor NEW
97.0 13.0 9.0 24.68 MB

An IntelliJ IDEA plugin that detects refactorings in Git commits

Home Page: https://plugins.jetbrains.com/plugin/14704-refactorinsight

License: MIT License

Java 93.24% Shell 5.36% Perl 1.12% Kotlin 0.29%
refactoringminer intellijidea-plugin refactorings smart-diff jetbrains-plugin code-diff

refactorinsight's Introduction

JB Research License pipeline status Downloads

RefactorInsight Plugin

RefactorInsight Plugin

RefactorInsight is a plugin for IntelliJ IDEA that enhances the representation of code changes with refactoring information in Java and Kotlin projects.

RefactorInsight relies on RefactoringMiner and kotlinRMiner for retrieval of refactorings.

The plugin is compatible with IntelliJ IDEA 2023.3 and is available for free on JetBrains Marketplace.

Table of contents

Features

Smart diff

RefactorInsight labels code diffs with information about performed refactorings. It shows close to refactoring changes and opens the corresponding code diff by click.

Code Diff

To make reviewing bug fixes or new features easier, the plugin auto folds refactorings in code diffs and shows hints with short descriptions of each refactoring. Currently, it works for the following refactoring types: Move Method, Pull Up/Push Down Method, Extract Method, and Inline Method.

Example

Hide non-functional changes

RefactorInsight provides a possibility to collapse refactoring changes in code diffs allowing users to focus on functional changes.

To hide non-functional changes (refactorings) in the code diff, check the corresponding checkbox in the diff window settings.

Example

Refactorings in commits

To see refactorings in your Git repository, go to the Git/Log tab in IntelliJ IDEA and choose Refactorings in the drop-down list next to Show.

Example

Refactorings in pull requests

To see the refactorings in a specific pull request, go to the Pull Requests tab in IntelliJ IDEA, select any pull request and click .

PullRequests

Refactoring history of an object

To see the refactoring history of a method, class, or attribute, right-click the object's signature and select Check Refactoring History. Here is an example for a method named Repl:

RefactoringHistory

Double-click a leaf node in the tree to open the VCS log at that specific commit and see a list of detected refactorings in that commit.

Settings

By default, for performance reasons, refactorings are only retrieved from the last 100 commits in the project history. This number can be adjusted in the plugin's settings. Alternatively, you can use Mine All Refactorings on the Tools menu to go through all commits in the history of your project. The plugin also keeps track of new commits and processes them.

Build instructions

You need to install Java 17 and IntelliJ IDEA. The project structure consists of several modules:

  • common — adapters for entities from RefactoringMiner and kotlinRMiner;
  • java-impl — handlers of refactorings performed in Java;
  • kotlin-impl — handlers of refactorings performed in Kotlin;
  • plugin — UI components (actions, toggles, diffs);
  • runner — runners for refactoring detection that could be used in external plugins.

Available Run configurations could be found in Gradle → Run Configurations:

  • Build Plugin — builds the plugin;
  • Run Plugin — runs an IDE instance with pre-installed plugin.

Contribution and feedback

You are welcome to submit a bug report or suggest a feature: open an issue. Pull requests are also welcome and encouraged.

For more information about the tool on which RefactorInsight relies to identify refactorings, read RefactoringMiner 2.0.

Citing RefactorInsight

A paper about RefactorInsight was presented at ASE'21. If you use RefactorInsight in your academic work, please cite it.

@article{kurbatova2021refactorinsight,
  title={Refactorinsight: Enhancing ide representation of changes in git with refactorings information},
  author={Kurbatova, Zarina and Kovalenko, Vladimir and Savu, Ioana and Brockbernd, Bob and Andreescu, Dan 
  and Anton, Matei and Venediktov, Roman and Tikhomirova, Elena and Bryksin, Timofey},
  journal={arXiv preprint arXiv:2108.11202},
  year={2021}
}

refactorinsight's People

Contributors

aioanasavu avatar anchouls avatar bbrockbernd avatar ceddy4395 avatar e2e4b6b7 avatar elenaerratic avatar ioanasv avatar juliabeliaeva avatar mateianton avatar onewhl avatar vovak avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

refactorinsight's Issues

Plugin settings menu

I would like to suggest two things:

  • Rename the menu item to RefactorInsight instead of RefactorInsight Settings
  • Make all buttons equal in size

settings

Suggestions for improving `RefactoringHistoryToolbar`

I've noticed potential issues with the RefactoringHistoryToolbar:

  1. New instance of VcsLogUi is created on every double click on the leaf node with RefactoringInfo, this is not good performance-wise.
  2. Each time RefactoringHistoryAction is executed, new ui components are created, even though ui for the same element may exist already. RefactoringHistoryToolbar#showContent even finds the old content, but still replaces the old ui with the new one, instead of just refreshing it.

I think that that the code could be improved by extracting a class that represents one single tab with refactorings for a single element, let's call this RefactoringHistoryTab. This RefactoringHistoryTab would have one Tree instance, and one VcsLogUi (created on demand). The RefactoringHistoryAction would either find an existing RefactoringHistoryTab and focus it, or create a new one if nothing was found.

Handle new refactoring types introduced in last RefactoringMiner release

Plugin crashes when tries to process unsupported refactoring types that were introduced in the last RefactoringMiner release.
For example, CHANGE_CLASS_ACCESS_MODIFIER refactoring.
java.lang.IllegalArgumentException: No enum constant org.jetbrains.research.refactorinsight.adapters.RefactoringType.CHANGE_CLASS_ACCESS_MODIFIER at java.base/java.lang.Enum.valueOf(Enum.java:273) at org.jetbrains.research.refactorinsight.adapters.RefactoringType.valueOf(RefactoringType.java:51) at org.jetbrains.research.refactorinsight.data.InfoFactory.create(InfoFactory.java:19) at org.jetbrains.research.refactorinsight.data.RefactoringEntry.lambda$convertJavaRefactorings$1(RefactoringEntry.java:96) at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:197) at java.base/java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1625) at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:509) at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499) at java.base/java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:921) at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) at java.base/java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:682) at org.jetbrains.research.refactorinsight.data.RefactoringEntry.convertJavaRefactorings(RefactoringEntry.java:96) at org.jetbrains.research.refactorinsight.processors.CommitMiner$1.handle(CommitMiner.java:104) at org.refactoringminer.rm1.GitHistoryRefactoringMinerImpl.detectRefactorings(GitHistoryRefactoringMinerImpl.java:158) at org.refactoringminer.rm1.GitHistoryRefactoringMinerImpl.detectAtCommit(GitHistoryRefactoringMinerImpl.java:569)
We need to check what refactoring types were introduced and support them in our plugin.

Refactoring summary in a certain time frame

Dear Team
I've read the doc, but I can't find a feature for generating activity summary refactoring in vcs.
It would be great to add a feature to show the total refactoring activity in a certain time frame.
An example of the results might be seen as follows:

Refactoring Type, Total
Extract Method, 10
Extract Class, 20
Move Method, 10
...

I thought it would be nice if the results could be exported as a .csv file.
thank you

Wrong code ranges for changes

Sometimes the code ranges provided by RefactroingMiner are wrong and it leads to exceptions

java.lang.Throwable: LineFragmentImpl is invalid: LineFragmentImpl: Lines [597, 598) - [599, 598); Offsets [0, 0) - [0, 0); Inner 1
	at com.intellij.openapi.diagnostic.Logger.error(Logger.java:146)
	at com.intellij.diff.fragments.LineFragmentImpl.<init>(LineFragmentImpl.java:74)
	at org.jetbrains.research.refactorinsight.data.RefactoringLine.computeTwoSidedRanges(RefactoringLine.java:188)
	at org.jetbrains.research.refactorinsight.data.RefactoringLine.correctLines(RefactoringLine.java:114)
	at org.jetbrains.research.refactorinsight.data.diff.DiffRequestGenerator.lambda$correct$0(DiffRequestGenerator.java:64)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1540)
	at org.jetbrains.research.refactorinsight.data.diff.DiffRequestGenerator.correct(DiffRequestGenerator.java:63)
	at org.jetbrains.research.refactorinsight.data.RefactoringInfo.correctLines(RefactoringInfo.java:518)
	at org.jetbrains.research.refactorinsight.utils.Utils.check(Utils.java:241)
	at org.jetbrains.research.refactorinsight.data.RefactoringEntry.lambda$convert$2(RefactoringEntry.java:92)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1540)
	at org.jetbrains.research.refactorinsight.data.RefactoringEntry.convert(RefactoringEntry.java:92)
	at org.jetbrains.research.refactorinsight.processors.CommitMiner$2.handle(CommitMiner.java:108)
	at org.refactoringminer.rm1.GitHistoryRefactoringMinerImpl.detectRefactorings(GitHistoryRefactoringMinerImpl.java:146)
	at org.refactoringminer.rm1.GitHistoryRefactoringMinerImpl.detectAtCommit(GitHistoryRefactoringMinerImpl.java:366)
	at org.jetbrains.research.refactorinsight.processors.CommitMiner.lambda$consume$0(CommitMiner.java:102)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
	at java.base/java.lang.Thread.run(Thread.java:834)

Show refactorings in code changes before commit

It is possible to run refactoring detection in code changes before a user makes a commit.
See: RefactoringMiner documentation.

This feature will come in next release of RefactoringMiner.

Currently, we detect refactorings only in commited changes. It would be cool to show users refactorings when they inspect code changes before they commit it.

Testing tool

Summary

To eliminate bugs and discover all edge cases, create a tool which automates mining and creates diff requests. This tool wil log all errors and mined data including screenshots of the generated diff view and mining time.

Checklist

  • Make testing action
  • Auto mine commits
  • Auto generate diff requests and open diff viewer
  • Screenshot swing diff viewer
  • Log relevant data

assert: ComponentStoreImpl.doAddComponent

Product: IDEA 201.8538.31   Plugin: RefactorInsight 2020.1-1.1   OS: Mac OS X   Java: JetBrains s.r.o. 11.0.7   Reporter: Anonymous IDEA User   Date: 2020-07-13 14:58  

    

java.lang.Throwable: Conflicting component name 'MiningRefactoringsState': class services.MiningService and class org.jetbrains.research.refactorinsight.services.MiningService (componentManager=Project (name=RefactoringMiner, containerState=ACTIVE, componentStore=/Users/ioana/Desktop/RefactoringMiner) )
    at com.intellij.openapi.diagnostic.Logger.error(Logger.java:146)
    at com.intellij.configurationStore.ComponentStoreImpl.doAddComponent(ComponentStoreImpl.kt:352)
    at com.intellij.configurationStore.ComponentStoreImpl.initPersistenceStateComponent(ComponentStoreImpl.kt:137)
    at com.intellij.configurationStore.ComponentStoreImpl.initComponent(ComponentStoreImpl.kt:103)
    at com.intellij.configurationStore.ComponentStoreWithExtraComponents.initComponent(ComponentStoreWithExtraComponents.kt:50)
    at com.intellij.serviceContainer.ComponentManagerImpl.initializeComponent$intellij_platform_serviceContainer(ComponentManagerImpl.kt:358)
    at com.intellij.serviceContainer.ServiceComponentAdapter.createAndInitialize(ServiceComponentAdapter.kt:58)
    at com.intellij.serviceContainer.ServiceComponentAdapter.doCreateInstance(ServiceComponentAdapter.kt:41)
    at com.intellij.serviceContainer.BaseComponentAdapter.getInstanceUncached(BaseComponentAdapter.kt:115)
    at com.intellij.serviceContainer.BaseComponentAdapter.getInstance(BaseComponentAdapter.kt:69)
    at com.intellij.serviceContainer.ComponentManagerImpl.doGetService(ComponentManagerImpl.kt:411)
    at com.intellij.serviceContainer.ComponentManagerImpl.getService(ComponentManagerImpl.kt:394)
    at com.intellij.openapi.components.ServiceManager.getService(ServiceManager.java:24)
    at org.jetbrains.research.refactorinsight.services.MiningService.getInstance(MiningService.java:54)
    at org.jetbrains.research.refactorinsight.processors.CommitListener.repositoryChanged(CommitListener.java:15)
    at jdk.internal.reflect.GeneratedMethodAccessor441.invoke(Unknown Source)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:566)
    at com.intellij.util.messages.impl.MessageBusImpl.invokeListener(MessageBusImpl.java:541)
    at com.intellij.util.messages.impl.MessageBusConnectionImpl.deliverMessage(MessageBusConnectionImpl.java:139)
    at com.intellij.util.messages.impl.MessageBusImpl.doPumpMessages(MessageBusImpl.java:465)
    at com.intellij.util.messages.impl.MessageBusImpl.pumpWaitingBuses(MessageBusImpl.java:426)
    at com.intellij.util.messages.impl.MessageBusImpl.pumpMessages(MessageBusImpl.java:415)
    at com.intellij.util.messages.impl.MessageBusImpl.sendMessage(MessageBusImpl.java:395)
    at com.intellij.util.messages.impl.MessageBusImpl.lambda$createTopicHandler$3(MessageBusImpl.java:237)
    at com.sun.proxy.$Proxy123.dirtyUnder(Unknown Source)
    at git4idea.annotate.GitRepositoryForAnnotationsListener$1.repositoryChanged(GitRepositoryForAnnotationsListener.java:46)
    at jdk.internal.reflect.GeneratedMethodAccessor441.invoke(Unknown Source)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:566)
    at com.intellij.util.messages.impl.MessageBusImpl.invokeListener(MessageBusImpl.java:541)
    at com.intellij.util.messages.impl.MessageBusConnectionImpl.deliverMessage(MessageBusConnectionImpl.java:143)
    at com.intellij.util.messages.impl.MessageBusImpl.doPumpMessages(MessageBusImpl.java:465)
    at com.intellij.util.messages.impl.MessageBusImpl.pumpWaitingBuses(MessageBusImpl.java:426)
    at com.intellij.util.messages.impl.MessageBusImpl.pumpMessages(MessageBusImpl.java:415)
    at com.intellij.util.messages.impl.MessageBusImpl.sendMessage(MessageBusImpl.java:397)
    at com.intellij.util.messages.impl.MessageBusImpl.lambda$createTopicHandler$3(MessageBusImpl.java:237)
    at com.sun.proxy.$Proxy122.repositoryChanged(Unknown Source)
    at git4idea.repo.GitRepositoryManager.lambda$notifyListenersAsync$3(GitRepositoryManager.java:113)
    at com.intellij.util.concurrency.BoundedTaskExecutor.doRun(BoundedTaskExecutor.java:222)
    at com.intellij.util.concurrency.BoundedTaskExecutor.access$200(BoundedTaskExecutor.java:29)
    at com.intellij.util.concurrency.BoundedTaskExecutor$1.execute(BoundedTaskExecutor.java:201)
    at com.intellij.util.ConcurrencyUtil.runUnderThreadName(ConcurrencyUtil.java:210)
    at com.intellij.util.concurrency.BoundedTaskExecutor$1.run(BoundedTaskExecutor.java:190)
    at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
    at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
    at java.base/java.lang.Thread.run(Thread.java:834)

Plugin crashes after opening code diff

Steps to reproduce:

  1. runIde in 90-gutter-in-code-diffs
  2. Click on the Git tab, select any commit containing refactoring, select file with refactorings
  3. Click on plugin's toggle and on icon with two arrows to show diff
  4. Diff opens and plugins crashes with the following stacktrace:

java.lang.Throwable: Assertion failed: Should not wait for built-in server on EDT at com.intellij.openapi.diagnostic.Logger.assertTrue(Logger.java:254) at org.jetbrains.ide.BuiltInServerManagerImpl.waitForStart(BuiltInServerManagerImpl.kt:97) at com.intellij.externalProcessAuthHelper.XmlRpcHandlerService.getXmlRcpPort(XmlRpcHandlerService.java:66) at git4idea.commands.GitHandlerAuthenticationManager.prepareHttpAuth(GitHandlerAuthenticationManager.java:93) at git4idea.commands.GitHandlerAuthenticationManager.lambda$prepare$0(GitHandlerAuthenticationManager.java:60) at git4idea.GitUtil.tryRunOrClose(GitUtil.java:1034) at git4idea.commands.GitHandlerAuthenticationManager.prepare(GitHandlerAuthenticationManager.java:59) at git4idea.commands.GitImplBase.run(GitImplBase.java:161) at git4idea.commands.GitImplBase.runCommandWithoutCollectingOutput(GitImplBase.java:95) at git4idea.history.GitDetailsCollector.readRecordsFromHandler(GitDetailsCollector.kt:92) at git4idea.history.GitDetailsCollector.readFullDetailsFromHandler(GitDetailsCollector.kt:75) at git4idea.history.GitDetailsCollector.readFullDetails(GitDetailsCollector.kt:29) at git4idea.history.GitLogUtil.readFullDetails(GitLogUtil.java:197) at git4idea.history.GitHistoryUtils.history(GitHistoryUtils.java:152) at org.jetbrains.research.refactorinsight.ui.DiffHintLineMarkerProvider$MyIconGutterHandler.lambda$createComponent$0(DiffHintLineMarkerProvider.java:198) at java.desktop/javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:1972) at java.desktop/javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2313) at java.desktop/javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:405) at java.desktop/javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:262) at java.desktop/javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:279) at java.desktop/java.awt.Component.processMouseEvent(Component.java:6648) at java.desktop/javax.swing.JComponent.processMouseEvent(JComponent.java:3392) at java.desktop/java.awt.Component.processEvent(Component.java:6413) at java.desktop/java.awt.Container.processEvent(Container.java:2266) at java.desktop/java.awt.Component.dispatchEventImpl(Component.java:5022) at java.desktop/java.awt.Container.dispatchEventImpl(Container.java:2324) at java.desktop/java.awt.Component.dispatchEvent(Component.java:4854) at java.desktop/java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4948) at java.desktop/java.awt.LightweightDispatcher.processMouseEvent(Container.java:4575) at java.desktop/java.awt.LightweightDispatcher.dispatchEvent(Container.java:4516) at java.desktop/java.awt.Container.dispatchEventImpl(Container.java:2310) at java.desktop/java.awt.Window.dispatchEventImpl(Window.java:2802) at java.desktop/java.awt.Component.dispatchEvent(Component.java:4854) at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:781) at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:730) at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:724) at java.base/java.security.AccessController.doPrivileged(AccessController.java:399) at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:86) at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:97) at java.desktop/java.awt.EventQueue$5.run(EventQueue.java:754) at java.desktop/java.awt.EventQueue$5.run(EventQueue.java:752) at java.base/java.security.AccessController.doPrivileged(AccessController.java:399) at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:86) at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:751) at com.intellij.ide.IdeEventQueue.defaultDispatchEvent(IdeEventQueue.java:909) at com.intellij.ide.IdeEventQueue.dispatchMouseEvent(IdeEventQueue.java:831) at com.intellij.ide.IdeEventQueue._dispatchEvent(IdeEventQueue.java:753) at com.intellij.ide.IdeEventQueue.lambda$dispatchEvent$5(IdeEventQueue.java:437) at com.intellij.openapi.progress.impl.CoreProgressManager.computePrioritized(CoreProgressManager.java:774) at com.intellij.ide.IdeEventQueue.lambda$dispatchEvent$6(IdeEventQueue.java:436) at com.intellij.openapi.application.TransactionGuardImpl.performActivity(TransactionGuardImpl.java:113) at com.intellij.ide.IdeEventQueue.performActivity(IdeEventQueue.java:615) at com.intellij.ide.IdeEventQueue.lambda$dispatchEvent$7(IdeEventQueue.java:434) at com.intellij.openapi.application.impl.ApplicationImpl.runIntendedWriteActionOnCurrentThread(ApplicationImpl.java:813) at com.intellij.ide.IdeEventQueue.dispatchEvent(IdeEventQueue.java:480) at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:207) at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:128) at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:117) at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:113) at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:105) at java.desktop/java.awt.EventDispatchThread.run(EventDispatchThread.java:92)

Fix pull up method highlightinh

Summary

Pull up (and extract superclass) method highlighting only highlights the name. Though the whole method should be highlighted.

Make it possible to collapse refactoring changes in the diff window

  • See DiffWindow and DiffRequestGenerator classes to understand how the plugin generates diffs for refactoring changes;
  • Differentiate refactoring and non-refactoring changes in files (check ranges);
  • Close existing TODOs in refactoring-folding branch;
  • Add information about the moved method to destination class as well;
  • Check if a moved method was changed and add "moved with changes / with no changes" text to the description.

First, we should try to do it for one simple refactoring, for example, Move Method refactoring. Then, we will do it for complex refactorings that involve several files (like Extract Interface).

IOOBE: AbstractIntToIntMap.checkShortIndex

Product: IDEA Community 201.6668.121   Plugin: RefactorInsight 1.0-SNAPSHOT   OS: Windows 10   Java: JetBrains s.r.o 11.0.6   Reporter: Anonymous IDEA User   Date: 2020-07-09 16:12  

    

java.lang.IndexOutOfBoundsException: ShortSize is: 3497, but shortIndex: -1
    at com.intellij.vcs.log.graph.utils.impl.AbstractIntToIntMap.checkShortIndex(AbstractIntToIntMap.java:50)
    at com.intellij.vcs.log.graph.utils.impl.ListIntToIntMap.getLongIndex(ListIntToIntMap.java:87)
    at com.intellij.vcs.log.graph.collapsing.CollapsedGraph$CompiledGraph.getNodeId(CollapsedGraph.java:295)
    at com.intellij.vcs.log.graph.impl.facade.VisibleGraphImpl.getNodeId(VisibleGraphImpl.java:62)
    at com.intellij.vcs.log.graph.impl.facade.VisibleGraphImpl.getRowInfo(VisibleGraphImpl.java:56)
    at com.intellij.vcs.log.ui.table.GraphTableModel.getIdAtRow(GraphTableModel.java:199)
    at com.intellij.vcs.log.ui.table.GraphTableModel.getCommitId(GraphTableModel.java:230)
    at ui.windows.GitWindow.refresh(GitWindow.java:89)
    at services.MiningService$2.lambda$onFinished$0(MiningService.java:200)
    at com.intellij.openapi.application.TransactionGuardImpl$2.run(TransactionGuardImpl.java:201)
    at com.intellij.openapi.application.impl.ApplicationImpl.runIntendedWriteActionOnCurrentThread(ApplicationImpl.java:831)
    at com.intellij.openapi.application.impl.ApplicationImpl.lambda$invokeLater$4(ApplicationImpl.java:310)
    at com.intellij.openapi.application.impl.FlushQueue.doRun(FlushQueue.java:80)
    at com.intellij.openapi.application.impl.FlushQueue.runNextEvent(FlushQueue.java:128)
    at com.intellij.openapi.application.impl.FlushQueue.flushNow(FlushQueue.java:46)
    at com.intellij.openapi.application.impl.FlushQueue$FlushNow.run(FlushQueue.java:184)
    at java.desktop/java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:313)
    at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:776)
    at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:727)
    at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:721)
    at java.base/java.security.AccessController.doPrivileged(Native Method)
    at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:85)
    at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:746)
    at com.intellij.ide.IdeEventQueue.defaultDispatchEvent(IdeEventQueue.java:974)
    at com.intellij.ide.IdeEventQueue._dispatchEvent(IdeEventQueue.java:847)
    at com.intellij.ide.IdeEventQueue.lambda$null$8(IdeEventQueue.java:449)
    at com.intellij.openapi.progress.impl.CoreProgressManager.computePrioritized(CoreProgressManager.java:739)
    at com.intellij.ide.IdeEventQueue.lambda$dispatchEvent$9(IdeEventQueue.java:448)
    at com.intellij.openapi.application.impl.ApplicationImpl.runIntendedWriteActionOnCurrentThread(ApplicationImpl.java:831)
    at com.intellij.ide.IdeEventQueue.dispatchEvent(IdeEventQueue.java:496)
    at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:203)
    at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124)
    at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:113)
    at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:109)
    at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
    at java.desktop/java.awt.EventDispatchThread.run(EventDispatchThread.java:90)

Support Android Studio

It would be great to provide the opportunity to use the plugin to Android Studio users too.

Set Up CI

Summary

Set up CI to automate building and testing like in gitlab and our previous toy plugin.

Add timeout for mining a single commit

Checklist

  • use mineAtCommit method that terminates the process after a specified number of commits

  • label the timed out commits in the .xml file

  • add button for mining anyway the timed out commits

Exception while running "Mine All Refactorings"

When launching "Mine All Refactorings" in the test repository https://github.com/e2e4b6b7/example-refactorings, an exception was thrown:

java.lang.IndexOutOfBoundsException: Index: 0
	at com.intellij.util.containers.ContainerUtilRt$EmptyList.get(ContainerUtilRt.java:189)
	at org.jetbrains.research.refactorinsight.processors.CommitMiner.lambda$consume$1(CommitMiner.java:145)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
	at java.base/java.lang.Thread.run(Thread.java:834)

Add UI Icon

The R sign with pencil, already used for the refactoring tree and refactoring functionality of intellij, can be used for the refactoring toggle and toolbar.

Plugin crashes when you init a new repository that doesn't contain any commits

java.lang.IllegalArgumentException: Argument for @NotNull parameter 'commitId' of org/jetbrains/research/refactorinsight/services/MiningService.computeRefactoringHistory must not be null
	at org.jetbrains.research.refactorinsight.services.MiningService.$$$reportNull$$$0(MiningService.java)
	at org.jetbrains.research.refactorinsight.services.MiningService.computeRefactoringHistory(MiningService.java)
	at org.jetbrains.research.refactorinsight.services.MiningService$1.run(MiningService.java:154)
	at com.intellij.openapi.progress.impl.CoreProgressManager$TaskRunnable.run(CoreProgressManager.java:932)
	at com.intellij.openapi.progress.impl.CoreProgressManager.lambda$runProcessWithProgressAsync$5(CoreProgressManager.java:434)
	at com.intellij.openapi.progress.impl.ProgressRunner.lambda$null$3(ProgressRunner.java:233)
	at com.intellij.openapi.progress.impl.CoreProgressManager.lambda$runProcess$2(CoreProgressManager.java:166)
	at com.intellij.openapi.progress.impl.CoreProgressManager.registerIndicatorAndRun(CoreProgressManager.java:627)
	at com.intellij.openapi.progress.impl.CoreProgressManager.executeProcessUnderProgress(CoreProgressManager.java:572)
	at com.intellij.openapi.progress.impl.ProgressManagerImpl.executeProcessUnderProgress(ProgressManagerImpl.java:61)
	at com.intellij.openapi.progress.impl.CoreProgressManager.runProcess(CoreProgressManager.java:153)
	at com.intellij.openapi.progress.impl.ProgressRunner.lambda$submit$4(ProgressRunner.java:233)
	at java.base/java.util.concurrent.CompletableFuture$AsyncSupply.run(CompletableFuture.java:1700)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
	at java.base/java.lang.Thread.run(Thread.java:834)

Exception from the ToggleRefactoringViewAction

Method org.jetbrains.research.refactorinsight.services.WindowService#update tries to get VcsLogInternalDataKeys.MAIN_UI without checking first that it's available in the context. Similar problem was fixed in #39.

java.lang.NullPointerException
	at org.jetbrains.research.refactorinsight.services.WindowService.update(WindowService.java:70)
	at org.jetbrains.research.refactorinsight.actions.ToggleRefactoringViewAction.update(ToggleRefactoringViewAction.java:40)
	at com.intellij.openapi.actionSystem.ex.ActionUtil.performDumbAwareUpdate(ActionUtil.java:179)
	at com.intellij.ide.util.gotoByName.GotoActionModel.updateActionBeforeShow(GotoActionModel.java:371)
	at com.intellij.ide.util.gotoByName.GotoActionModel$ActionWrapper.lambda$getPresentation$0(GotoActionModel.java:712)
	at com.intellij.ide.util.gotoByName.GotoActionModel$ActionWrapper.getPresentation(GotoActionModel.java:716)
	at com.intellij.ide.util.gotoByName.GotoActionModel$GotoActionListCellRenderer.getListCellRendererComponent(GotoActionModel.java:819)
	at com.intellij.ide.actions.searcheverywhere.SearchEverywhereUI$CompositeCellRenderer.getListCellRendererComponent(SearchEverywhereUI.java:1007)
	at com.intellij.ui.ExpandedItemListCellRendererWrapper.getListCellRendererComponent(ExpandedItemListCellRendererWrapper.java:24)
	at com.intellij.ui.components.WideSelectionListUI.updateLayoutState(WideSelectionListUI.java:186)
	at java.desktop/javax.swing.plaf.basic.BasicListUI.maybeUpdateLayoutState(BasicListUI.java:1389)
	at java.desktop/javax.swing.plaf.basic.BasicListUI$Handler.valueChanged(BasicListUI.java:2785)
	at java.desktop/javax.swing.DefaultListSelectionModel.fireValueChanged(DefaultListSelectionModel.java:219)
	at java.desktop/javax.swing.DefaultListSelectionModel.fireValueChanged(DefaultListSelectionModel.java:199)
	at java.desktop/javax.swing.DefaultListSelectionModel.fireValueChanged(DefaultListSelectionModel.java:246)
	at java.desktop/javax.swing.DefaultListSelectionModel.insertIndexInterval(DefaultListSelectionModel.java:670)
	at java.desktop/javax.swing.plaf.basic.BasicListUI$Handler.intervalAdded(BasicListUI.java:2743)
	at java.desktop/javax.swing.AbstractListModel.fireIntervalAdded(AbstractListModel.java:153)
	at com.intellij.ide.actions.searcheverywhere.SearchEverywhereUI$SearchListModel.applyChange(SearchEverywhereUI.java:1242)
	at com.intellij.ide.actions.searcheverywhere.SearchEverywhereUI$SearchListModel.lambda$addElements$6(SearchEverywhereUI.java:1159)
	at java.base/java.util.HashMap.forEach(HashMap.java:1336)
	at com.intellij.ide.actions.searcheverywhere.SearchEverywhereUI$SearchListModel.addElements(SearchEverywhereUI.java:1152)
	at com.intellij.ide.actions.searcheverywhere.SearchEverywhereUI$SearchListener.elementsAdded(SearchEverywhereUI.java:1574)
	at com.intellij.ide.actions.searcheverywhere.ThrottlingListenerWrapper.lambda$new$0(ThrottlingListenerWrapper.java:38)
	at com.intellij.ide.actions.searcheverywhere.ThrottlingListenerWrapper.lambda$new$2(ThrottlingListenerWrapper.java:38)
	at com.intellij.ide.actions.searcheverywhere.ThrottlingListenerWrapper$Buffer.flush(ThrottlingListenerWrapper.java:131)
	at com.intellij.ide.actions.searcheverywhere.ThrottlingListenerWrapper.searchFinished(ThrottlingListenerWrapper.java:69)
	at com.intellij.ide.actions.searcheverywhere.MultiThreadSearcher$FullSearchResultsAccumulator.lambda$searchFinished$6(MultiThreadSearcher.java:415)
	at com.intellij.ide.actions.searcheverywhere.MultiThreadSearcher$ResultsAccumulator.lambda$runInNotificationExecutor$1(MultiThreadSearcher.java:264)
	at com.intellij.openapi.application.TransactionGuardImpl$2.run(TransactionGuardImpl.java:201)
	at com.intellij.openapi.application.impl.ApplicationImpl.runIntendedWriteActionOnCurrentThread(ApplicationImpl.java:802)
	at com.intellij.openapi.application.impl.ApplicationImpl.lambda$invokeLater$4(ApplicationImpl.java:322)
	at com.intellij.openapi.application.impl.FlushQueue.doRun(FlushQueue.java:84)
	at com.intellij.openapi.application.impl.FlushQueue.runNextEvent(FlushQueue.java:132)
	at com.intellij.openapi.application.impl.FlushQueue.flushNow(FlushQueue.java:47)
	at com.intellij.openapi.application.impl.FlushQueue$FlushNow.run(FlushQueue.java:188)
	at java.desktop/java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:313)
	at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:776)
	at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:727)
	at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:721)
	at java.base/java.security.AccessController.doPrivileged(Native Method)
	at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:85)
	at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:746)
	at com.intellij.ide.IdeEventQueue.defaultDispatchEvent(IdeEventQueue.java:967)
	at com.intellij.ide.IdeEventQueue._dispatchEvent(IdeEventQueue.java:839)
	at com.intellij.ide.IdeEventQueue.lambda$dispatchEvent$8(IdeEventQueue.java:450)
	at com.intellij.openapi.progress.impl.CoreProgressManager.computePrioritized(CoreProgressManager.java:744)
	at com.intellij.ide.IdeEventQueue.lambda$dispatchEvent$9(IdeEventQueue.java:449)
	at com.intellij.openapi.application.impl.ApplicationImpl.runIntendedWriteActionOnCurrentThread(ApplicationImpl.java:802)
	at com.intellij.ide.IdeEventQueue.dispatchEvent(IdeEventQueue.java:497)
	at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:203)
	at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124)
	at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:113)
	at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:109)
	at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
	at java.desktop/java.awt.EventDispatchThread.run(EventDispatchThread.java:90)

Similar exception happens with the ToggleLabelsAction:

java.lang.NullPointerException
	at org.jetbrains.research.refactorinsight.services.WindowService.isLabelsVisible(WindowService.java:60)
	at org.jetbrains.research.refactorinsight.actions.ToggleLabelsAction.isSelected(ToggleLabelsAction.java:15)
	at com.intellij.openapi.actionSystem.ToggleAction.update(ToggleAction.java:72)
	at com.intellij.openapi.actionSystem.ex.ActionUtil.performDumbAwareUpdate(ActionUtil.java:179)
	at com.intellij.ide.util.gotoByName.GotoActionModel.updateActionBeforeShow(GotoActionModel.java:371)
	at com.intellij.ide.util.gotoByName.GotoActionModel$ActionWrapper.lambda$getPresentation$0(GotoActionModel.java:712)
	at com.intellij.ide.util.gotoByName.GotoActionModel.lambda$updateOnEdt$4(GotoActionModel.java:521)
	at com.intellij.openapi.application.TransactionGuardImpl$2.run(TransactionGuardImpl.java:201)
	at com.intellij.openapi.application.impl.ApplicationImpl.runIntendedWriteActionOnCurrentThread(ApplicationImpl.java:802)
	at com.intellij.openapi.application.impl.ApplicationImpl.lambda$invokeLater$4(ApplicationImpl.java:322)
	at com.intellij.openapi.application.impl.FlushQueue.doRun(FlushQueue.java:84)
	at com.intellij.openapi.application.impl.FlushQueue.runNextEvent(FlushQueue.java:132)
	at com.intellij.openapi.application.impl.FlushQueue.flushNow(FlushQueue.java:47)
	at com.intellij.openapi.application.impl.FlushQueue$FlushNow.run(FlushQueue.java:188)
	at java.desktop/java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:313)
	at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:776)
	at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:727)
	at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:721)
	at java.base/java.security.AccessController.doPrivileged(Native Method)
	at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:85)
	at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:746)
	at com.intellij.ide.IdeEventQueue.defaultDispatchEvent(IdeEventQueue.java:967)
	at com.intellij.ide.IdeEventQueue._dispatchEvent(IdeEventQueue.java:839)
	at com.intellij.ide.IdeEventQueue.lambda$dispatchEvent$8(IdeEventQueue.java:450)
	at com.intellij.openapi.progress.impl.CoreProgressManager.computePrioritized(CoreProgressManager.java:744)
	at com.intellij.ide.IdeEventQueue.lambda$dispatchEvent$9(IdeEventQueue.java:449)
	at com.intellij.openapi.application.impl.ApplicationImpl.runIntendedWriteActionOnCurrentThread(ApplicationImpl.java:802)
	at com.intellij.ide.IdeEventQueue.dispatchEvent(IdeEventQueue.java:497)
	at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:203)
	at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124)
	at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:113)
	at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:109)
	at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
	at java.desktop/java.awt.EventDispatchThread.run(EventDispatchThread.java:90)

Label the commits that contain refactorings in the Log tab

Summary

It would be great to label the commits that contain refactorings.
Currently, the user can't identify the commits that contain refactorings in the Log tab.

Checklist

  • Manipulate existing VcsLogGraphTable
  • Mark commits with refactorings
  • Use Icon for marking
  • Mark unmined commits with different icon
  • Add toggle to hide labels from vcs table
  • (If possible) Align Icon on the right side of the table

Hide non-functional changes in code diff

It would be nice to have a feature that allows to hide refactorings, added/removed imports, whitespaces in code diff.
For example, we can add a checkbox to the toolbar in code diff window.
If it is selected, all refactorings and imports are hidden.
Screen Shot 2023-02-02 at 3 13 36 PM

All differences ignored with "Ignore whitespaces and empty lines" when opened from Git window

When I double click on a file with a refactoring in the Git window, it shows me an empty diff and the message "Differences ignored". This seems to be because I have chosen "Ignore whitespaces and empty lines". If I change that to anything else, the refactoring differences actually show. For whatever reason the diff window decides to ignore renaming etc even though it's not just whitespace or empty line change.

With "Ignore whitespaces and empty lines":
Screenshot_2020-07-31_12-38-22

With "Do not ignore":
Screenshot_2020-07-31_12-38-29


Maybe related observation: a normal (non-refactoring) diff for that commit shows the corresponding commit hashes in the diff window, but the refactoring diff only shows the file paths (same on both sides):
Screenshot_2020-07-31_12-41-00

Comparing the "Highlight words" in this normal diff to the one above, it also looks like "Highlight words" works differently in a refactoring diff window. Also, code highlighting is different and lacking some colors.

Excessive memory consumption by the plugin

image
image

It looks like the plugin has started 8 threads to process commits, and each of the threads has loaded a big PackFile.

IntelliJ IDEA 2020.1.3 (Community Edition)
Build #IC-201.8538.31, built on July 7, 2020
Runtime version: 11.0.7+10-b765.64 x86_64
VM: OpenJDK 64-Bit Server VM by JetBrains s.r.o.
macOS 10.15.5
GC: ParNew, ConcurrentMarkSweep
Memory: 2981M
Cores: 8

Plugin version 2020.1-1.1

Add a gutter to mark refactoring changes in code diffs

Gutter could help to mark refactoring changes in code diffs. If a user is interested in some details, they could click on the gutter and see refactoring description and corresponding code diff (it could be useful in cases when a piece of code was moved to another file).

  • Add a gutter to code diffs
  • Show gutter only close to refactoring changes

Branch: 90-gutter-in-code-diffs
It works only in two sided diff mode. There is a bug in the unified viewer diff, syntax highlighting , gutters, and tooltips don't work.

Add RefactorInsight to the new pull request window in IntelliJ 2020.3

Summary

The new version of IntelliJ (2020.2) comes with a window for reviewing pull requests. It would be help full for developers to have an overview of refactorings in that pull request.

Checklist

  • Discover how to manipulate the new pull requests UI.
  • Incorporate refactorings tree in new UI.
  • Extend mining service to support mining of remote pull requests.
  • Find appropriate time to mine pull requests.
  • Check if current data structure allows storing mined pull requests.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.