Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Proposal] Ignored Directives Support #3507

Open
1 of 4 tasks
333fred opened this issue May 28, 2020 · 11 comments
Open
1 of 4 tasks

[Proposal] Ignored Directives Support #3507

333fred opened this issue May 28, 2020 · 11 comments

Comments

@333fred
Copy link
Member

333fred commented May 28, 2020

Ignored Directives

Summary

As we move to allow C# statements in the top level of a file, it's reasonable to assume that we might someday get support for dotnet runing a .cs file. For further use of C# as a scripting language in this vein, I propose that we introduce a new preprocessor directive who's purpose is to exist solely to be ignored by the language: the hashbang directive. Linux and Unix scripts will often use #!<path to interpreter> in order to direct the program loader to the interpreter that can run them. We should add a similar ignore to the C# language.

Detailed design

We introduce a new directive:

pp_directive
    : ... // Existing directives
    | pp_hashbang
    | pp_reference
    ;

pp_hashbang
    : whitespace? '#' '!' input_character*
    ;

pp_reference
    : whitespace? '#' 'r' whitespace input_character*
    ;

The language ignores the contents of the hashbang and reference directives and moves to the next line.

Drawbacks

Any change adds complication to the language. If we implement support for this and it starts appearing in files without actual scripting support, then it could be confusing for users expecting it to work.

Alternatives

N/A

Unresolved questions

  1. If we use these directives to support tooling such as nuget references, we will need to consider how they interact with other pragmas, such as #if. We have a few options for this:
    1. Require that ignored directives are the first directives in a file. We could even go further and require they're all at the beginning of the file.
    2. Less restrictive than 1, but forbid ignored directives inside conditional directives.
    3. Least restrictive, require a true preprocessing step in the compiler. Today, we can process directives up front without having to do a full multi-step preprocessing pass before lexing, but if we want to support nuget directives inside conditional directives we may need the full two-step process.

Design meetings

@ufcpp
Copy link

ufcpp commented May 28, 2020

I'm worried about BOM. The presence of the BOM before the shebang will prevent the script interpreter.

Visual Studio for Win uses Encoding.Default (usually not UTF8) if the BOM doesn't present.

@333fred
Copy link
Member Author

333fred commented May 28, 2020

Sure, and we could certainly consider warning if the file uses anything other than UTF-8 w/o BOM.

@yaakov-h
Copy link
Member

I thought shebang was already supported... is it only in the .csx variant?

@yaakov-h
Copy link
Member

@svick
Copy link
Contributor

svick commented May 28, 2020

  1. As @yaakov-h mentions, shebang is already supported in the scripting dialect. Is this effectively formalizing that support and making it work in both dialects?
  2. If I understand it correctly, the shebang that's supported by the scripting mode has to be literally the first thing in the file: no whitespace before it, no other lines before it. Since that's the only way shebang works, does it make sense to support whitespace before it and to support it on lines other than the first line in the file?

@HaloFour
Copy link
Contributor

HaloFour commented May 28, 2020

I'm a little confused. Do "simple programs" not require a project file? How would a single file "script" in this manner establish references or change any compiler properties?

This feels like trying to bridge a gap between C# "simple programs" and CSX, which already has this support plus the directive support to make it actually useful. Short of adding that directive support this feels extremely limited.

Again, C# would benefit so much more from embracing CSX and improving the tooling support than it ever will by chasing CSX through some separate dialect that will always be much less capable.

@dersia
Copy link

dersia commented May 28, 2020

I agree with @HaloFour without directives for assembly imports this might not be very useful. On the other hand having a script that downloads nuget packages or loading complex and somewhat big assemblies doesn't feel right for scripting.

The only thing that I kind of see as a big plus is that you can just take the cs file to any machine architecture and call dotnet run on it so you don't have to compile aot.

What is still unclear for me is if the purpose of this proposal is that the cs-file is being interpreted or is it going to be compiled on running it.

If the purpose is to "just" interpreted on run, than I agree even more with @HaloFour we should focus on making csx a better experience.

@hez2010
Copy link

hez2010 commented May 29, 2020

I don't think it should introduce a new #! directive to C#, for C# doesn't use # for comment syntax.

How about:

/// <interpreter path="" />

Which will allow more complex definition, for example:

/// <project target="net5.0">
///   <properties>
///     <nullable>enable</nullable>
///   </properties>
///   <items>
///     <package include="Newtonsoft.Json" version="12.0.3" />
///   </items>
/// </project>

@HaloFour
Copy link
Contributor

HaloFour commented May 29, 2020 via email

@333fred 333fred added this to the 10.0 candidate milestone Jul 20, 2020
@aka-nse
Copy link

aka-nse commented Jul 28, 2020

I summarize my understanding of this proposal at followings. Is it right?

  • C# compiler will simply ignore a shebang in the first line of the source. Because the lines start with # are preprocessor directives even on conventional spec, this modification looks not to impact other features.

  • You can write inline csproj XML on and after 2nd line, but the interpretation of them should be done by build tool (e.g. dotnet-cli), not compiler. Such an inline csproj will be written under the conventional comment syntax, and the extension spec will be defined by tools.

#!/bin/dotnet run
//+ <Project Sdk="Microsoft.NET.Sdk">
//+     <PropertyGroup>
//+         <TargetFramework>netcoreapp3.1</TargetFramework>
//+     </PropertyGroup>
//+ </Project>

/*
 * In this example, it is assumed that dotnet-cli will interprets the comments start with `//+` as inline csproj
 */

using System;

Console.WriteLine("Hello, world!");

@333fred
Copy link
Member Author

333fred commented Jul 28, 2020

The first point is correct, and is the only thing this proposal covers. This proposal makes no statement on how a program would communicate dependencies to a tool.

@333fred 333fred modified the milestones: 10.0 candidate, X.0 candidate Sep 28, 2020
@333fred 333fred changed the title [Proposal] Shebang (#!) Support [Proposal] Hashbang (#!) Support May 4, 2021
@jcouv jcouv modified the milestones: Backlog, Working Set May 12, 2021
@333fred 333fred changed the title [Proposal] Hashbang (#!) Support [Proposal] Ignored Directives Support May 12, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

9 participants