GithubHelp home page GithubHelp logo

deaglegross / sharpcoachplugin Goto Github PK

View Code? Open in Web Editor NEW
4.0 4.0 2.0 2.41 MB

Rider C# plugin for easy code generation of mapping classes

License: MIT License

PowerShell 8.67% C# 89.69% Kotlin 1.64%
jetbrains rider mapping codegeneration

sharpcoachplugin's Introduction

SharpCoachPlugin for Rider and ReSharper

This is plugin with useful features for comfortable C# development using JetBrains Rider IDE

Build status

CI

Stats

Rating
Downloads
Version

Features Supported

You cannot install plugin in your Rider?

shout-out to AliExpress colleagues :)

JetBrains plugins publishing system is ... hard
To help identify missing published versions, please, help me by submitting an issue
I would be very grateful if you can create a PR by changing a couple of files, and help me publish new versions faster.

Build

# For Rider
gradlew :runIde

Publish

There are different entities that are needed to be changed for each publishing:

  • ProductVersion specifies version of Rider
  • build is a specific build in a product version
  • plugin_version is a version of plugin, that is maintained by SharpCoachPlugin developers
Branches

All changes are firstly merged into main branch. When a new plugin version is ready to be released, publisher has to merge main into versions\<product_version> branch. Please, make sure that plugin.xml xml-attribute <idea-version since-build="..." until-build="....*" /> sets all builds supported compatibility range (except some ridiculous situations).

When main is merged in some specific branch, execute this command for publishing plugin and make sure it appears on versions page at JetBrains.Marketplace.PluginPage

It is not needed to explicitly change plugin_version when publishing plugin using this command, because it is automatically replaced with an command line argument

Versioning

View JetBrains Rider ProductVersion & BuildNumbers

  • Major version is updated when some serious features are released
  • Minor version is updated on every new version publish
  • Hotfix version is changed for every compatibility different version of plugin. (I.e. 1.0.1 supports 2021.1.3 ProductVersion and 1.0.2 supports 2021.1.5 ProductVersion)
# For Rider & ReSharper (Gradle)
gradlew :publishPlugin -PPluginVersion=<version> -PPublishToken=<token>

Supported ProductVersions and builds:

  • branch versions\2021.1.3 -> ProductVersion = 2021.1.3, build = 211.*
  • branch versions\2021.1.5 -> ProductVersion = 2021.1.5, build = 211.*
  • branch versions\2021.2 -> ProductVersion = 2021.2, build = 212.*
  • branch versions\2021.2.1 -> ProductVersion = 2021.2.1, build = 212.*
  • branch versions\2021.2.2 -> ProductVersion = 2021.2.2, build = 212.*
  • branch versions\2023.3-223build -> ProductVersion = 2023.3-SNAPSHOT, build = 223.*
  • branch versions\2023.1 -> ProductVersion = 2023.1, build = 231.*

Contribution Info

Feel free to take part in developing the project. You can start with viewing opened issues.
Also if you find any bugs or you have any ideas about new features, please, open a new issue

sharpcoachplugin's People

Contributors

deaglegross avatar

Stargazers

 avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

sharpcoachplugin's Issues

Cannot create configurable

Describe the bug
An error when opening ctrl + T smart class finder

To Reproduce
Steps to reproduce the behavior:

  1. open smart finder
  2. search any class
  3. IDE reports a problem

Expected behavior
No error

Desktop:

  • Rider version (#2021.1.5) and build number (#RD-211.7628.61)

Stack trace

Cannot create configurable

com.intellij.diagnostic.PluginException: com.jetbrains.rider.plugins.sharpcoachplugin.SampleOptionsPage PluginClassLoader(plugin=PluginDescriptor(name=CoachSharp, id=deaglegross.coachsharp, descriptorPath=plugin.xml, path=~/Library/Application Support/JetBrains/Rider2021.1/plugins/sharpcoachplugin, version=1.0.5, package=null), packagePrefix=null, instanceId=31, state=active)
  at com.intellij.serviceContainer.ComponentManagerImpl.instantiateClass(ComponentManagerImpl.kt:789)
  at com.intellij.openapi.options.ConfigurableEP$ClassProducer.createElement(ConfigurableEP.java:440)
  at com.intellij.openapi.options.ConfigurableEP.createConfigurable(ConfigurableEP.java:346)
  at com.intellij.openapi.options.ex.ConfigurableWrapper.createConfigurable(ConfigurableWrapper.java:42)
  at com.intellij.openapi.options.ex.ConfigurableWrapper.getConfigurable(ConfigurableWrapper.java:116)
  at com.intellij.openapi.options.ex.ConfigurableWrapper.cast(ConfigurableWrapper.java:91)
  at com.intellij.openapi.options.ex.ConfigurableWrapper.getDisplayName(ConfigurableWrapper.java:137)
  at com.intellij.ide.util.gotoByName.GotoActionModel.lambda$new$0(GotoActionModel.java:90)
  at com.intellij.openapi.util.NotNullLazyValue$3.compute(NotNullLazyValue.java:80)
  at com.intellij.openapi.util.VolatileNotNullLazyValue.getValue(VolatileNotNullLazyValue.java:19)
  at com.intellij.ide.util.gotoByName.GotoActionModel.getConfigurablesNames(GotoActionModel.java:379)
  at com.intellij.ide.util.gotoByName.GotoActionItemProvider.processOptions(GotoActionItemProvider.java:166)
  at com.intellij.ide.util.gotoByName.GotoActionItemProvider.filterElements(GotoActionItemProvider.java:116)
  at com.intellij.ide.actions.searcheverywhere.ActionSearchEverywhereContributor.fetchWeightedElements(ActionSearchEverywhereContributor.java:97)
  at com.intellij.ide.actions.searcheverywhere.MixedResultsSearcher$ContributorSearchTask.run(MixedResultsSearcher.java:177)
  at com.intellij.util.ConcurrencyUtil.runUnderThreadName(ConcurrencyUtil.java:213)
  at com.intellij.util.ConcurrencyUtil.lambda$underThreadNameRunnable$3(ConcurrencyUtil.java:201)
  at com.intellij.util.RunnableCallable.call(RunnableCallable.java:20)
  at com.intellij.util.RunnableCallable.call(RunnableCallable.java:11)
  at com.intellij.openapi.application.impl.ApplicationImpl$1.call(ApplicationImpl.java:265)
  at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
  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.util.concurrent.Executors$PrivilegedThreadFactory$1$1.run(Executors.java:668)
  at java.base/java.util.concurrent.Executors$PrivilegedThreadFactory$1$1.run(Executors.java:665)
  at java.base/java.security.AccessController.doPrivileged(Native Method)
  at java.base/java.util.concurrent.Executors$PrivilegedThreadFactory$1.run(Executors.java:665)
  at java.base/java.lang.Thread.run(Thread.java:829)
Caused by: java.lang.ClassNotFoundException: com.jetbrains.rider.plugins.sharpcoachplugin.SampleOptionsPage PluginClassLoader(plugin=PluginDescriptor(name=CoachSharp, id=deaglegross.coachsharp, descriptorPath=plugin.xml, path=~/Library/Application Support/JetBrains/Rider2021.1/plugins/sharpcoachplugin, version=1.0.5, package=null), packagePrefix=null, instanceId=31, state=active)
  at com.intellij.serviceContainer.ComponentManagerImplKt.doLoadClass(ComponentManagerImpl.kt:1090)
  at com.intellij.serviceContainer.ComponentManagerImplKt.access$doLoadClass(ComponentManagerImpl.kt:1)
  at com.intellij.serviceContainer.ComponentManagerImpl.instantiateClass(ComponentManagerImpl.kt:781)
  ... 27 more

Map internals of models code-fix appears in non-empty method

If the code fix menu is called in a non-empty method it has the Map internals of models code-fix (see the screenshots section).
Looks like this menu item should not be shown in non-empty method context.

To Reproduce
Steps to reproduce the behavior:

  1. Add the following method (the types in the method body don't actually matter)
private async Task BuildResponse(Dictionary<string, List<string>> keyValueItemsByTables)
{
    var responseString = "some string";

    List<object> retBatches = new(keyValueItemsByTables.Count);

    foreach (var keyValueItemsForTable in keyValueItemsByTables)
    {
        // some code
    }
}
  1. Place cursor on the first method line and call the lightbulb menu.
  2. Observe the Map internals of models code-fix.

Expected behavior
It seems that the code fix should not be added in the lightbulb menu in the non-empty method body.

Screenshots
image_2023-03-03_14-37-48

Desktop (please complete the following information):

  • OS: Windows 10 22H2 Build 19045.2604
  • Rider version and build number : #2022.3.2 Build #RD-223.8617.53, built on January 25, 2023

Uable to map IEnumerable<T>

Describe the bug
When mapping a complex type and the target property type is not an array, mapping fails without a message.

To Reproduce
Steps to reproduce the behavior:
Source type:

public class V1CreateManySyncTasksRequest
{
    public SyncTask[] Tasks { set; get; }

    public class SyncTask
    {
        public int Priority { get; set; }
    }
}

Target type:

public class CreateManyTasksModel
{
    public IEnumerable<CreateTaskModel> Tasks { set; get; }

    public class CreateTaskModel
    {
        public int Priority { get; set; }
    }
}

Generated result:

public CreateManyTasksModel Map(V1CreateManySyncTasksRequest request)
{
    return new CreateManyTasksModel()
        { };
}

Expected behavior
Expected the generated code to be:

return new CreateManyTasksModel()
{
    Tasks = request.Tasks.Select(
            tmpTasks => new CreateManyTasksModel.CreateTaskModel()
            {
                Priority = tmpTasks.Priority,
                BuyerId = tmpTasks.BuyerId,
                OrderIds = tmpTasks.OrderIds,
            })
        .ToList(),
};

Desktop (please complete the following information):

  • OS: OSx
  • Rider version and build number :
JetBrains Rider 2021.2.2
Build #RD-212.5284.64, built on October 9, 2021
Runtime version: 11.0.12+7-b1504.28 x86_64
VM: Dynamic Code Evolution 64-Bit Server VM by JetBrains s.r.o.
macOS 12.0.1
.NET 5.0.7
GC: G1 Young Generation, G1 Old Generation
Memory: 1500M
Cores: 12

"Map internals of models" code fix does not appear on extension methods

Describe the bug
The "Map internals of models" code fix does not appear under the lightbulb menu when called on an extension method.

To Reproduce
Steps to reproduce the behavior:

  1. Add a static instance method
private static SomeOutputModel
        MapToResponse(SomeInputModel source)
{}
  1. Observe that the lightbulb contains map internals of models code fix.
  2. Add this qualifier to the first formal parameter of the added method
private static SomeOutputModel
        MapToResponse(this SomeInputModel source)
{}
  1. Observe that the lightbulb does not contain "Map internals of models" code fix.

Expected behavior
The map internals of models code fix should appear under the lightbulb menu when called on an extension method with compatible signature.

Screenshots
Extension method behavior
image

Behavior when this qualifier is removed from first formal parameter
image

Desktop:

  • OS: Windows 10
  • Rider version and build number 2022.3.3 Build #RD-223.8836.53, built on March 20, 2023

Output logs of mapping

When mapping models, there is no output of how many properties where mapped correctly (or pairs found). It is a headache to determine whether all of properties were mapped or not especially when very big classes are mapped.

Firstly you need to search what output method is the best one (i.e. console of Rider or something else).
Then just implement it

Incorrect dictionary mapping

Describe the bug
Incorrect dictionary mapping

To Reproduce
Steps to reproduce the behavior:

  • mapping internal model with
public Dictionary<long, Version> Versions { get; set; }

public class Version
{
    public long Id { get; set; }        
    public string Name { get; set; }
}
  • getting such a result
Versions = new Dictionary()
{
    Comparer = request.Versions.Comparer,
    Count = request.Versions.Count,
    Item = request.Versions.Item,
    Keys = request.Versions.Keys,
    Values = request.Versions.Values
}

Expected behavior
Dictionary should map correctly:

Versions = request.Versions.ToDictionary(pair => pair.Key, pair => new UserResponse.Version
{
    Id = pair.Value.Id,
    Name = pair.Value.Name
})

Screenshots
This is how it is working now:
image

Desktop:

  • Rider version 2021.2, 212.4746.114

Add `null` checks when mapping internal classes

It is better to make checks on null objects.

Currently code is generated in this way:

id = foo.bar.id

But the suggestion is to generate it like this:

foo.bar is null ? null : foo.bar.id

Add conditional LINQ methods call when mapping collections

When mapping the collections of object this plugin generates the Select LINQ clause.

OrderLines = tmpOrders.OrderLines.Select(...)

If the LINQ target is null - System.ArgumentNullException gets thrown at the run time.

It might be a good idea to call all the generated LINQ methods conditionally (either through conditional access operator or via more verbose ternary operator) or add a corresponding setting - whether the extension should generate collection mappings using conditional access.

No option `Map models internals` in quick actions menu when method is a local function

Describe the bug
Everything works fine when Convert method is a method of a class.
However there is no option to generate mapping code when Convert method is a local function.

To Reproduce

  1. Copy and paste to Rider this code fragment
public void MySuperLogic(Request request) 
{
      var response = Convert(request);
      
      static Response Convert(Request x) {
      
      }
}
  1. Try use quick action on Convert method
  2. There is no action

Expected behavior
Action appears in quick actions menu and generates code properly.

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.