Code Monkey home page Code Monkey logo

prettier-plugin-csharp's Introduction

❌ This repository is unmaintained and the project is incomplete, don't expect anything else than a toy C# project to reformat correctly! ❌

Have a look at CSharpier instead.


Prettier C#

Prettier C# Plugin

Gitter Travis npm version code style: prettier Follow+Prettier+on+Twitter

Intro

Prettier C# adds C# support to the Prettier code formatter. Like Prettier, it is opinionated and restricts style options to a minimum. It runs where Prettier runs, including CI and pre-commit hooks.

Unmaintained

This repository is unmaintained and the project is incomplete, don't expect anything else than a toy C# project to reformat correctly! It will break your code.

Preview the result with this diff example.

Install

yarn add --dev --exact prettier prettier-plugin-csharp

Use

prettier --write "**/*.cs"

How it works

The plugin is written in JavaScript. It depends on the JavaScript port of ANTLR and relies on a fork of an unofficial C# 6 grammar from ANTLR. The grammar is precompiled to plain JavaScript and ready to use in the project.

Contributing

Installing dependencies

Use your favorite Node package manager:

yarn

Updating the grammar

The grammar supports C# 6 as a baseline, and tries to catch up with recent additions. Contributions are welcome. To update the grammar:

  • Update src/csharp/*.g4 files.
  • Ensure you have Java 8+ installed on your machine.
  • Fetch a local copy of ANTLR:
yarn fetch-antlr
  • Generate the JavaScript parser:
yarn generate-parser

Testing

The project is developed against a single grammar-complete regression test. There are no unit tests for the moment.

Run the test with:

yarn test

To test it out on an actual C# file:

  • Clone this repository.
  • Run yarn.
  • Run yarn prettier Your/File.cs to check the output.

Maintainers


Warren Seine

prettier-plugin-csharp's People

Contributors

charlestaylor7 avatar dependabot[bot] avatar matchachoco010 avatar warrenseine 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  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

prettier-plugin-csharp's Issues

Error: Comment was not printed

for the following code i get an error

using System;
using System.ComponentModel.DataAnnotations;
using IdentikeyWrapper.vasco.identikey.model;
using System.Collections.Generic;

namespace My.Project.Models
{
    public class AccessControlServiceModel
    {
        //public List<StoredUser> MonitoringUsers { get; set; }
        public String AvailabilityCounter { get; set; }

        public AccessControlServiceModel()
        {
            //MonitoringUsers = new List<StoredUser>();
        }
    }
}
[error] Models\ViewModels\AccessControlServiceModel.cs: Error: Comment "//MonitoringUsers = new List<StoredUser>();" was not printed. Please report this error!
[error]     at C:\Source\MyProject.SelfService\src\MyProject.SelfService.Portal\node_modules\prettier\bin-prettier.js:13736:13
[error]     at Array.forEach (<anonymous>)
[error]     at ensureAllCommentsPrinted (C:\Source\MyProject.SelfService\src\MyProject.SelfService.Portal\node_modules\prettier\bin-prettier.js:13734:15)
[error]     at coreFormat (C:\Source\MyProject.SelfService\src\MyProject.SelfService.Portal\node_modules\prettier\bin-prettier.js:13786:3)
[error]     at format (C:\Source\MyProject.SelfService\src\MyProject.SelfService.Portal\node_modules\prettier\bin-prettier.js:13941:16)
[error]     at formatWithCursor (C:\Source\MyProject.SelfService\src\MyProject.SelfService.Portal\node_modules\prettier\bin-prettier.js:13953:12)
[error]     at Object.formatWithCursor (C:\Source\MyProject.SelfService\src\MyProject.SelfService.Portal\node_modules\prettier\bin-prettier.js:41969:15)
[error]     at format$1 (C:\Source\MyProject.SelfService\src\MyProject.SelfService.Portal\node_modules\prettier\bin-prettier.js:43321:21)
[error]     at C:\Source\MyProject.SelfService\src\MyProject.SelfService.Portal\node_modules\prettier\bin-prettier.js:43510:16
[error]     at C:\Source\MyProject.SelfService\src\MyProject.SelfService.Portal\node_modules\prettier\bin-prettier.js:43456:14

Using formatting

I checked the diff and current using (disposable) formatting looks bad. You should really think of adding curly brackets when you format to multiple lines.

            using (var v = BeginScope())
                using (A a = new A())
                    using (
                        A
                            a = new A(),
                            b = new A()
                    )
                        using (BeginScope())
                            return;

to

            using (var v = BeginScope())
            {
                using (A a = new A())
                {
                    using (
                        A
                            a = new A(),
                            b = new A()
                    ) 
                    {
                        using (BeginScope())
                            return;
                    }
                }
            }

Also whole idea of multiple using statements after each other without curly brackets is to avoid nesting. I would rather see prettier avoiding nesting of using statements much as possible, if it can be avoided. Nesting them also hurts readability and make lines longer. I would prefer to see original code below in our company's code instead of that formatted one.

            using (var v = BeginScope())
            using (A a = new A())
            using (A a = new A(), b = new A())
            using (BeginScope())
                return;

no viable alternative at input 'default;'

thanks for fixing my other issues. just found another issue in our codebase with 0.4.0. it looks like prettier-sharp doesn't understand the keyword 'default'

for this

public static bool TryGetDataFromCache<T>(string cacheID, out T content)
        {
            ObjectCache cache = MemoryCache.Default;
            try
            {
                content = (T)cache.Get(cacheID);
                if (content == null)
                {
                    return false;
                }
                else
                {
                    return true;
                }
            }
            catch
            {
                content = default;
                return false;
            }
        }

we get

no viable alternative at input 'default;'

TypeError: node.children is not iterable

for the following code i get an error

using MyProject.SelfService.Logic.APIHelper;
using GraphQL.Language.AST;
using GraphQL.Types;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Web;

namespace MyProject.AuthPortal.GraphQL.Customer.Service.SecurityPatching
{
    public class SecurityPatchingModel
    {

        private readonly CMDBApiHelper<SecurityPatchingModel> _cmdbHelper;
        private readonly String Customer;

        public SecurityPatchingModel(UserContext userContext, String customer)
        {
            Customer = customer;
            _cmdbHelper = new CMDBApiHelper<SecurityPatchingModel>(userContext.GetAccessToken());
        }

        public async Task<List<API.CMDB.Schema.Server.Server>> GetServers<T>(ResolveFieldContext<T> context, string[] skipPaths = null)
        {
            var arguments = new Arguments();
            var whereFilterArgument = new Argument(new NameNode("where"));
            {
                var fields = new List<ObjectField>(new ObjectField[] {
                    new ObjectField(
                        new NameNode("customer"),
                        new StringValue(Customer.ToLower())
                        ),
                    new ObjectField(
                        new NameNode("active"),
                        new EnumValue("ACTIVE")
                        ),
                    });
                
                whereFilterArgument.Value = new ObjectValue(fields);
            }
            arguments.Add(whereFilterArgument);
            if (
                context.Arguments.ContainsKey("where") &&
                context.Arguments["where"] is Dictionary<string, object> where &&
                where.ContainsKey("uid") && where["uid"] is string uid && whereFilterArgument.Value is ObjectValue objVal
                )
            {

                whereFilterArgument.Value = new ObjectValue(objVal.ObjectFields.Append(new ObjectField(new NameNode("uid"), new StringValue(uid))));
            }

            return await _cmdbHelper.QueryDepthOne<List<API.CMDB.Schema.Server.Server>, T>(context, fieldName: "servers", arguments: arguments, skipPaths: skipPaths);
        }
    }
}
GraphQL\Customer\Service\SecurityPatching\SecurityPatchingModel.csline 45:73 missing ')' at 'where'
line 46:67 missing ';' at 'uid'
line 46:115 missing ';' at 'objVal'

[error] GraphQL\Customer\Service\SecurityPatching\SecurityPatchingModel.cs: TypeError: node.children is not iterable
[error]     at simplifyTree (C:\Source\MyProject.SelfService\src\MyProject.SelfService.Portal\node_modules\prettier-csharp\src\parser.js:69:26)
[error]     at simplifyTree (C:\Source\MyProject.SelfService\src\MyProject.SelfService.Portal\node_modules\prettier-csharp\src\parser.js:70:13)
[error]     at simplifyTree (C:\Source\MyProject.SelfService\src\MyProject.SelfService.Portal\node_modules\prettier-csharp\src\parser.js:70:13)
[error]     at simplifyTree (C:\Source\MyProject.SelfService\src\MyProject.SelfService.Portal\node_modules\prettier-csharp\src\parser.js:70:13)
[error]     at simplifyTree (C:\Source\MyProject.SelfService\src\MyProject.SelfService.Portal\node_modules\prettier-csharp\src\parser.js:70:13)
[error]     at simplifyTree (C:\Source\MyProject.SelfService\src\MyProject.SelfService.Portal\node_modules\prettier-csharp\src\parser.js:70:13)
[error]     at simplifyTree (C:\Source\MyProject.SelfService\src\MyProject.SelfService.Portal\node_modules\prettier-csharp\src\parser.js:70:13)
[error]     at simplifyTree (C:\Source\MyProject.SelfService\src\MyProject.SelfService.Portal\node_modules\prettier-csharp\src\parser.js:70:13)
[error]     at simplifyTree (C:\Source\MyProject.SelfService\src\MyProject.SelfService.Portal\node_modules\prettier-csharp\src\parser.js:70:13)
[error]     at simplifyTree (C:\Source\MyProject.SelfService\src\MyProject.SelfService.Portal\node_modules\prettier-csharp\src\parser.js:70:13)

What is the current status on this plugin?

I assume it only works with VS code? Is the Readme up to date, ie. will it still break the code?
Do you have a changelog so we can follow the feature/stability progress?
Also, does it work on individual open files or can I import an existing project and have all the .cs files prettified in one go?

Thanks for any response that clarifies these questions.

Cheers ;)

String interpolation handled incorrectly

String interploation with the '$' character does not work properly. It only fails when the line length is longer than the specified limit.

https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/tokens/interpolated

Input:

Logging.Log.Error($"Some error message text: ({someVariableValue} did not work)");

Output:

Logging
  .Log
  .Error($"Some error message text: ({
  someVariableValue} did not work)");

Expected Output:

Logging.Log.Error(
   $"Some error message text: ({someVariableValue} did not work)");

Ideal Output:

Logging.Log.Error($"Some error message " +
   $" text: ({someVariableValue} did not work)");

How to install - doesn't seem to work

I tried with the instructions in the readme... I also tried with the master branch from github directly.

With the npm release, I get a bunch of syntax errors on the first using statement. With the master branch install, it doesn't have ./csharp/...references. I'd like to be able to use this, but I'm not sure if/what dependencies are needed etc.

OS: macOS High Sierra 10.13.3 (moving to Linux next month with new computer) (windows 10 at work)
Node: 12.9.0
dotnet: core 3 preview 8

JavaScript heap out of memory when importing

Hi there, thanks for your work, looks promising to me.

Im trying to use your plugin in a react project, where I want to provide users a webeditor that would format their code in the browser.
Im trying the prettier docs here: https://prettier.io/docs/en/browser.html#es-modules, i.e. with your plugin I would assume code along these lines could work:

import prettier from "prettier";
import parser from "prettier-plugin-csharp";

const result = prettier.format("using System ;", {
    parser: "cs",
    plugins: [parser]
});

The problem is no matter what I try to import from "prettier-plugin-csharp", starting my project I get a JS heap out of memory error:

client-app: FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of memory
client-app:  1: 00007FF6AAC8DD8A v8::internal::GCIdleTimeHandler::GCIdleTimeHandler+4506
client-app:  2: 00007FF6AAC68886 node::MakeCallback+4534
client-app:  3: 00007FF6AAC69200 node_module_register+2032
client-app:  4: 00007FF6AAF830DE v8::internal::FatalProcessOutOfMemory+846
client-app:  5: 00007FF6AAF8300F v8::internal::FatalProcessOutOfMemory+639
client-app:  6: 00007FF6AB169804 v8::internal::Heap::MaxHeapGrowingFactor+9620
client-app:  7: 00007FF6AB1607E6 v8::internal::ScavengeJob::operator=+24550
client-app:  8: 00007FF6AB15EE3C v8::internal::ScavengeJob::operator=+17980
client-app:  9: 00007FF6AB167B87 v8::internal::Heap::MaxHeapGrowingFactor+2327
client-app: 10: 00007FF6AB167C06 v8::internal::Heap::MaxHeapGrowingFactor+2454
client-app: 11: 00007FF6AB291EA7 v8::internal::Factory::NewFillerObject+55
client-app: 12: 00007FF6AB30F096 v8::internal::operator<<+73494
client-app: 13: 000003DC082DC5C1
client-app: npm ERR! code ELIFECYCLE
client-app: npm ERR! errno 134
client-app: npm ERR! [email protected] start: `react-app-rewired start`
client-app: npm ERR! Exit status 134
client-app: npm ERR!
client-app: npm ERR! Failed at the [email protected] start script.
client-app: npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
client-app: npm ERR! A complete log of this run can be found in:
client-app: npm ERR!     C:\Users\jannik\AppData\Roaming\npm-cache\_logs\2020-02-05T21_35_13_140Z-debug.log

Any ideas why this happens?

TypeError: Cannot read property '0' of undefined

with the version on npm i get the following error for every cs file when running yarn prettier --plugin=prettier-csharp --parser=cs --write "**/*.cs"

[error] GraphQL\Customer\Service\Client\Devices\Assignments\AssignmentResultModel.cs: TypeError: Cannot read property '0' of undefined
[error]     at FastPath.call (C:\Code\My.Project\src\My.Project.Portal\node_modules\prettier\bin-prettier.js:9945:18)
[error]     at printCompilationUnit (C:\Code\My.Project\src\My.Project.Portal\node_modules\prettier-csharp\src\printer.js:20:38)
[error]     at Object.printNode [as print] (C:\Code\My.Project\src\My.Project.Portal\node_modules\prettier-csharp\src\printer.js:3269:14)
[error]     at genericPrint (C:\Code\My.Project\src\My.Project.Portal\node_modules\prettier\bin-prettier.js:10130:18)
[error]     at C:\Code\My.Project\src\My.Project.Portal\node_modules\prettier\bin-prettier.js:10076:16
[error]     at Object.printComments (C:\Code\My.Project\src\My.Project.Portal\node_modules\prettier\bin-prettier.js:9838:17)
[error]     at printGenerically (C:\Code\My.Project\src\My.Project.Portal\node_modules\prettier\bin-prettier.js:10075:22)
[error]     at printAstToDoc (C:\Code\My.Project\src\My.Project.Portal\node_modules\prettier\bin-prettier.js:10087:16)
[error]     at coreFormat (C:\Code\My.Project\src\My.Project.Portal\node_modules\prettier\bin-prettier.js:10414:16)
[error]     at format (C:\Code\My.Project\src\My.Project.Portal\node_modules\prettier\bin-prettier.js:10572:16)

How to install and use as plugin in VSCode?

I found this post on prettier plugins on the prettier.io site, but not quite sure how to put it into effect in a C# project.

I also found this post on how to configure prettier

Coming from a NodeJS and JS background, I assumes I'd have to install prettier and the plugin in packages.json of my C# project root as dev dependencies.

Not sure if I should then use the CLI or the API option? Is it possible with direct integration in the IDE/Editor, ie. auto format on save as per the usual settings.json prettier setting?

Would be great if the Readme could be more clear on this. I know the plugins are beta.
Great work!

Cheers :)

Rename project?

This is similar to #10, the Prettier docs specify:

Plugins are automatically loaded if you have them installed in the same node_modules directory where prettier is located. Plugin package names must start with @prettier/plugin- or prettier-plugin- to be registered.

The VS Code extension seems to have some open problems with plugins (prettier/prettier-vscode#395), but in Atom at least it will auto-format on save if I manually rename the folder in node_modules to 'prettier-csharp-plugin'

You can also see that it's registered automatically with prettier --support-info (I found this through prettier/prettier-atom#395 (comment)):

$ ./node_modules/.bin/prettier --support-info | grep '"\.cs'
      "extensions": [".css"],
      "extensions": [".cs", ".cake", ".cshtml", ".csx"],

Are you accepting contributors?

I was fixing to write a C# formatter myself to keep me sane at work. This project looks like it's most of the way there.

Would you be open to having contributors?
Or at the very least would you mind if I forked the project and continued development on it?

I didn't see any license in the Repo, so I wanted to check with you before forking the project.

Activity

No changes since 3 years. C# 6.0 was published in 2015 . Now we have C# 11.0.
I may assume that this project is dead. :-(

Are there alternatives known?
What do you currently use to reformat C# code?

Empty braces are not consistently formatted

Empty braces are printed inline for classes & structs, but printed on separate lines for if statements and method blocks.
e.g.

// inline
class Foo { }
// separate lines
if (true)
{
}

I'd prefer to standardize on inlining empty braces, which is how Prettier proper handles JS.

Compiled Version

Can you provide a compiled version that we can just put in the node_modules to use. Trying to get antlr to run on windows isnt working form me.

Bug: Embedded Empty Statements are deleted

This

    if (true);
    while (false) ;
    foreach (var x in "") ;

gets transformed to this

    if (true)
        while (false) 
            foreach (var x in "") 

I started on a fix for this, but I had a few questions.

  1. Why does if use an if_body node, but while & foreach, etc., use an embedded_statement node?

  2. Is it better to update the grammar to have a special node for required embedded empty statements, or encode the logic solely at the printer level?

question: support for different csharp versions

hi @warrenseine,
Thank you for your work, looks promising.

I have several related questions that Ill just bundle here:

  • What would it take to support newer versions of C# and even other flavors, i.e. CSharp Scripting?
  • Would the antlr project be the right place to implement the grammar?
  • Do you know if other projects can be reused, i.e. Visual Studio already has code formatting and MS has made a lot of stuff open source? Maybe they also have some sort of "grammar" files somewhere?
  • General question about grammar vs formatting: I assume the grammar is some kind of ruleset or syntax about what is considered "the language", whereas formatting is only concerned about all whitespaces and linebreaks. It seems that the formatting is defined in src/printer.js. Am I roughly correct?

String interpolations cause hanging

Simple string interpolation seems to work fine, such as ($"Hello {name}") but some more advanced ones seem to get stuck.

Here are some replications files:

class A
{
  A()
  {
    Console.WriteLine($"It's {DateTime.Now:HH:mm} now.");
  }
}
class A
{
  A()
  {
    Console.WriteLine($"It's {(true ? 1 : 2)} now.");
  }
}

Using v0.2.1-development

Example usage

Any chance you can add a bare bones "example usage" to the docs, i.e how to include it in node, format some code etc?

I assume it would be just calling prettier with this listed as a plugin, but that would be helpful to new users.

Mixed tabs & spaces

The *.g4 antlr files have spaces mixed with tabs. I've deduced based on your commits, that your using a tab width of 4 spaces; whereas I have been using a tab width of 2 spaces for these files. To make matters worse, Github uses a tab width of 8 spaces by default.

I'd like to normalize to pure tabs or pure spaces, with my preference towards the latter.
I can submit a PR to normalize everything, or we can do a more fancy git-filter-branch to normalize the whole git log.

What do you think?

Unable to run

I'm trying to run the command inside a .NET repo, from the root. The command fails.

Command: yarn prettier --write "**/*.cs"

Output:

yarn run v1.22.19
warning package.json: No license field
$ /workspace/node_modules/.bin/prettier --write '**/*.cs'
[error] Must use import to load ES Module: /workspace/node_modules/antlr4/src/antlr4/index.js
[error] require() of ES modules is not supported.
[error] require() of /workspace/node_modules/antlr4/src/antlr4/index.js from /workspace/node_modules/prettier-plugin-csharp/src/parser.js is an ES module file as it is a .js file whose nearest parent package.json contains "type": "module" which defines all .js files in that package scope as ES modules.
[error] Instead rename index.js to end in .cjs, change the requiring code to use import(), or remove "type": "module" from /workspace/node_modules/antlr4/package.json.
[error]
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.

package.json:

{
  "devDependencies": {
    "prettier": "2.7.1",
    "prettier-plugin-csharp": "0.6.0-development"
  }
}

node -v: v14.19.2
npm -v: 8.9.0

I tried also prettier --write "**/*.cs" (without yarn) but it can't find the plugin, emitting errors like this:

[error] No parser could be inferred for file: ....cs

Inconsistent #if ... #endif blocks reformatting

Hi! Thanks for this plugin; I'm very well aware that it's still considered in 'alpha' stage, but it already does some amazing things, which is really great!

I'm no professional C# programmer, and that's why prettifying other people's code to make it more consistently readable is so useful for me. Yesterday I came across some conditional compilation rules such as:

		public static void WriteInfo(
			string message
#if VERBOSE_MESSAGES
			, [CallerMemberName] string callingMethod = "",
			[CallerFilePath] string callingFilePath = "",
			[CallerLineNumber] int callingFileLineNumber = 0
#endif
		)
		{
#if VERBOSE_MESSAGES
			message =
				message +
				"; from " +
				callingMethod +
				"(" +
				Path.GetFileName(callingFilePath) +
				":" +
				callingFileLineNumber +
				")";
#endif
			restbotLog.Info(message);
			Output("[INFO] " + message, ConsoleColor.White);
		}

which gets turned by this plugin into:

		public static void WriteInfo(
			string message,
#if VERBOSE_MESSAGES
			[CallerMemberName] string callingMethod = "",
			[CallerFilePath] string callingFilePath = "",
			[CallerLineNumber] int callingFileLineNumber = 0
		)
		{
#if VERBOSE_MESSAGES
			message =
				message +
				"; from " +
				callingMethod +
				"(" +
				Path.GetFileName(callingFilePath) +
				":" +
				callingFileLineNumber +
				")";
#endif
			restbotLog.Info(message);
			Output("[INFO] " + message, ConsoleColor.White);
		}

#endif

It's actually interesting to see why this happens; there is clearly some cleverness under the skin to get the parser to produce this output!

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.