Skip to content
This repository has been archived by the owner on Nov 28, 2021. It is now read-only.

Commit

Permalink
Added parameterless struct instance constructor support.
Browse files Browse the repository at this point in the history
This commit is largely just restoring parameterless constructors before they were removed by 1a6b2f0 in dotnet#1106
Note that unlike the feature before that commit, this is hidden behind a feature flag rather than a language version.
  • Loading branch information
PathogenDavid committed Nov 2, 2020
1 parent e48c865 commit 7eecef6
Show file tree
Hide file tree
Showing 24 changed files with 432 additions and 19 deletions.
47 changes: 47 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,50 @@
# Patholyn - A soft fork of the .NET Compiler Platform ("Roslyn")

[![MIT Licensed](https://img.shields.io/github/license/infectedlibraries/roslyn?style=flat-square)](LICENSE.txt)
[![Sponsor](https://img.shields.io/badge/sponsor-%E2%9D%A4-lightgrey?logo=github&style=flat-square)](https://github.com/sponsors/PathogenDavid)

This is a soft fork of Roslyn. It is primarily serves as a sandbox for testing out ideas for C#. All changes to the language are locked behind feature flags, meaning you can opt into them individually. (In theory anwyay, the way Roslyn is designed means mistakes could break expecations here.)

The intent is that eventually you'll be able to consume this compiler as a NuGet package and eventually we'll automatically keep pace with the Roslyn upstream using CI.

## Feature Flags

### `StructParameterlessConstructors`

This feature is similar to [dotnet/csharplang#99](https://github.com/dotnet/csharplang/issues/99)

This feature flag enables parameterless instance constructors on structs, for example:

```csharp
public struct MyStruct
{
private string Message;

public MyStruct()
=> Message = "Initialized from parameterless constructor.";

public MyStruct(string message)
=> Message = message;

public override string ToString()
=> Message ?? "Defaulted struct.";
}
```

The implementation of this feature is based on the cut C# 6 feature that [was removed](https://github.com/dotnet/roslyn/pull/1106) before Roslyn 1.0 was released.

(Note that the Visual Basic implementation of this feature was not restored.)

[Roslyn actually supports calling parameterless constructors on structs when they exist](https://github.com/PathogenPlayground/CSharpParameterlessStruct). So using this feature on public API does not make it incompatible with vanilla Roslyn. Parameterless constructors will be called as expected.

# Roslyn Readme

Past this point is the original Roslyn readme, unmodified.

<!-- Don't modify the original readme! Doing so makes it harder to merge changes. -->

----------------------------------

## Welcome to the .NET Compiler Platform ("Roslyn")

[![Join the chat at https://gitter.im/dotnet/roslyn](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/dotnet/roslyn?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Chat on Discord](https://discordapp.com/api/guilds/143867839282020352/widget.png)](http://aka.ms/discord-csharp-roslyn)
Expand Down
6 changes: 6 additions & 0 deletions src/Compilers/CSharp/Portable/CSharpResources.resx
Original file line number Diff line number Diff line change
Expand Up @@ -6588,4 +6588,10 @@ To remove the warning, you can use /reference instead (set the Embed Interop Typ
<data name="WRN_UnreadRecordParameter_Title" xml:space="preserve">
<value>Parameter is unread. Did you forget to use it to initialize the property with that name?</value>
</data>
<data name="ERR_ParameterlessStructCtorsMustBePublic" xml:space="preserve">
<value>Parameterless instance constructors in structs must be public</value>
</data>
<data name="IDS_FeatureStructParameterlessConstructors" xml:space="preserve">
<value>struct instance parameterless constructors</value>
</data>
</root>
6 changes: 6 additions & 0 deletions src/Compilers/CSharp/Portable/Errors/ErrorCode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1928,6 +1928,12 @@ internal enum ErrorCode

#endregion diagnostics introduced for C# 9.0

#region diagnostics introduced for C# Pathogen

ERR_ParameterlessStructCtorsMustBePublic = 32260001,

#endregion diagnostics introduced for C# Pathogen

// Note: you will need to re-generate compiler code after adding warnings (eng\generate-compiler-code.cmd)
}
}
6 changes: 6 additions & 0 deletions src/Compilers/CSharp/Portable/Errors/MessageID.cs
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,10 @@ internal enum MessageID
IDS_Parameter = MessageBase + 12789,
IDS_Return = MessageBase + 12790,
IDS_FeatureVarianceSafetyForStaticInterfaceMembers = MessageBase + 12791,

// Below here are Pathogen C# features
PathogenMessageBase = MessageBase + 322600,
IDS_FeatureStructParameterlessConstructors = PathogenMessageBase + 1
}

// Message IDs may refer to strings that need to be localized.
Expand Down Expand Up @@ -258,6 +262,8 @@ public static LocalizableErrorArgument Localize(this MessageID id)
// Check for current experimental features, if any, in the current branch.
switch (feature)
{
case MessageID.IDS_FeatureStructParameterlessConstructors:
return "StructParameterlessConstructors";
default:
return null;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2990,9 +2990,19 @@ private static void CheckForStructDefaultConstructors(
{
diagnostics.Add(ErrorCode.ERR_EnumsCantContainDefaultConstructor, m.Locations[0]);
}
else if (m.DeclaredAccessibility != Accessibility.Public)
{
diagnostics.Add(ErrorCode.ERR_ParameterlessStructCtorsMustBePublic, m.Locations[0]);
}
else
{
diagnostics.Add(ErrorCode.ERR_StructsCantContainDefaultConstructor, m.Locations[0]);
SyntaxTree? sourceTree = m.Locations[0].SourceTree;

// Not sure how to handle this situation, old code didn't check at all.
if (sourceTree is null)
{ throw new InvalidOperationException("Struct default constructor does not have a source tree."); }

Binder.CheckFeatureAvailability(sourceTree, MessageID.IDS_FeatureStructParameterlessConstructors, diagnostics, m.Locations[0]);
}
}
}
Expand Down
10 changes: 10 additions & 0 deletions src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -702,6 +702,11 @@
<target state="translated">Metoda {0} určuje omezení struct pro parametr typu {1}, ale odpovídající parametr typu {2} přepsané nebo explicitně implementované metody {3} není typ, který nemůže mít hodnotu null.</target>
<note />
</trans-unit>
<trans-unit id="ERR_ParameterlessStructCtorsMustBePublic">
<source>Parameterless instance constructors in structs must be public</source>
<target state="new">Parameterless instance constructors in structs must be public</target>
<note />
</trans-unit>
<trans-unit id="ERR_PartialMethodAccessibilityDifference">
<source>Both partial method declarations must have identical accessibility modifiers.</source>
<target state="new">Both partial method declarations must have identical accessibility modifiers.</target>
Expand Down Expand Up @@ -952,6 +957,11 @@
<target state="new">target-typed object creation</target>
<note />
</trans-unit>
<trans-unit id="IDS_FeatureStructParameterlessConstructors">
<source>struct instance parameterless constructors</source>
<target state="new">struct instance parameterless constructors</target>
<note />
</trans-unit>
<trans-unit id="WRN_AnalyzerReferencesFramework">
<source>The assembly '{0}' containing type '{1}' references .NET Framework, which is not supported.</source>
<target state="new">The assembly '{0}' containing type '{1}' references .NET Framework, which is not supported.</target>
Expand Down
10 changes: 10 additions & 0 deletions src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -702,6 +702,11 @@
<target state="translated">Die Methode "{0}" gibt eine struct-Einschränkung für den Typparameter "{1}" an, aber der zugehörige Typparameter "{2}" der außer Kraft gesetzten oder explizit implementierten Methode "{3}" ist kein Non-Nullable-Werttyp.</target>
<note />
</trans-unit>
<trans-unit id="ERR_ParameterlessStructCtorsMustBePublic">
<source>Parameterless instance constructors in structs must be public</source>
<target state="new">Parameterless instance constructors in structs must be public</target>
<note />
</trans-unit>
<trans-unit id="ERR_PartialMethodAccessibilityDifference">
<source>Both partial method declarations must have identical accessibility modifiers.</source>
<target state="new">Both partial method declarations must have identical accessibility modifiers.</target>
Expand Down Expand Up @@ -952,6 +957,11 @@
<target state="new">target-typed object creation</target>
<note />
</trans-unit>
<trans-unit id="IDS_FeatureStructParameterlessConstructors">
<source>struct instance parameterless constructors</source>
<target state="new">struct instance parameterless constructors</target>
<note />
</trans-unit>
<trans-unit id="WRN_AnalyzerReferencesFramework">
<source>The assembly '{0}' containing type '{1}' references .NET Framework, which is not supported.</source>
<target state="new">The assembly '{0}' containing type '{1}' references .NET Framework, which is not supported.</target>
Expand Down
10 changes: 10 additions & 0 deletions src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -702,6 +702,11 @@
<target state="translated">El método "{0}" especifica una restricción "struct" para el parámetro de tipo "{1}", pero el parámetro de tipo correspondiente "{2}" de los métodos invalidados o implementados explícitamente "{3}" no es un tipo de valor que acepta valores NULL.</target>
<note />
</trans-unit>
<trans-unit id="ERR_ParameterlessStructCtorsMustBePublic">
<source>Parameterless instance constructors in structs must be public</source>
<target state="new">Parameterless instance constructors in structs must be public</target>
<note />
</trans-unit>
<trans-unit id="ERR_PartialMethodAccessibilityDifference">
<source>Both partial method declarations must have identical accessibility modifiers.</source>
<target state="new">Both partial method declarations must have identical accessibility modifiers.</target>
Expand Down Expand Up @@ -952,6 +957,11 @@
<target state="new">target-typed object creation</target>
<note />
</trans-unit>
<trans-unit id="IDS_FeatureStructParameterlessConstructors">
<source>struct instance parameterless constructors</source>
<target state="new">struct instance parameterless constructors</target>
<note />
</trans-unit>
<trans-unit id="WRN_AnalyzerReferencesFramework">
<source>The assembly '{0}' containing type '{1}' references .NET Framework, which is not supported.</source>
<target state="new">The assembly '{0}' containing type '{1}' references .NET Framework, which is not supported.</target>
Expand Down
10 changes: 10 additions & 0 deletions src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -702,6 +702,11 @@
<target state="translated">La méthode '{0}' spécifie une contrainte 'struct' pour le paramètre de type '{1}', mais le paramètre de type '{2}' correspondant de la méthode substituée ou explicitement implémentée '{3}' n'est pas un type valeur non-nullable.</target>
<note />
</trans-unit>
<trans-unit id="ERR_ParameterlessStructCtorsMustBePublic">
<source>Parameterless instance constructors in structs must be public</source>
<target state="new">Parameterless instance constructors in structs must be public</target>
<note />
</trans-unit>
<trans-unit id="ERR_PartialMethodAccessibilityDifference">
<source>Both partial method declarations must have identical accessibility modifiers.</source>
<target state="new">Both partial method declarations must have identical accessibility modifiers.</target>
Expand Down Expand Up @@ -952,6 +957,11 @@
<target state="new">target-typed object creation</target>
<note />
</trans-unit>
<trans-unit id="IDS_FeatureStructParameterlessConstructors">
<source>struct instance parameterless constructors</source>
<target state="new">struct instance parameterless constructors</target>
<note />
</trans-unit>
<trans-unit id="WRN_AnalyzerReferencesFramework">
<source>The assembly '{0}' containing type '{1}' references .NET Framework, which is not supported.</source>
<target state="new">The assembly '{0}' containing type '{1}' references .NET Framework, which is not supported.</target>
Expand Down
10 changes: 10 additions & 0 deletions src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -702,6 +702,11 @@
<target state="translated">Il metodo '{0}' specifica un vincolo 'struct' per il parametro di tipo '{1}', ma il parametro di tipo corrispondente '{2}' del metodo '{3}' sottoposto a override o implementato in modo esplicito non è un tipo valore che non ammette valori Null.</target>
<note />
</trans-unit>
<trans-unit id="ERR_ParameterlessStructCtorsMustBePublic">
<source>Parameterless instance constructors in structs must be public</source>
<target state="new">Parameterless instance constructors in structs must be public</target>
<note />
</trans-unit>
<trans-unit id="ERR_PartialMethodAccessibilityDifference">
<source>Both partial method declarations must have identical accessibility modifiers.</source>
<target state="new">Both partial method declarations must have identical accessibility modifiers.</target>
Expand Down Expand Up @@ -952,6 +957,11 @@
<target state="new">target-typed object creation</target>
<note />
</trans-unit>
<trans-unit id="IDS_FeatureStructParameterlessConstructors">
<source>struct instance parameterless constructors</source>
<target state="new">struct instance parameterless constructors</target>
<note />
</trans-unit>
<trans-unit id="WRN_AnalyzerReferencesFramework">
<source>The assembly '{0}' containing type '{1}' references .NET Framework, which is not supported.</source>
<target state="new">The assembly '{0}' containing type '{1}' references .NET Framework, which is not supported.</target>
Expand Down
10 changes: 10 additions & 0 deletions src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -702,6 +702,11 @@
<target state="translated">メソッド '{0}' は、型パラメーター '{1}' に対して 'struct' 制約を指定していますが、オーバーライドされた、または明示的に実装されたメソッド '{3}' の対応する型パラメーター '{2}' は NULL 非許容の値型ではありません。</target>
<note />
</trans-unit>
<trans-unit id="ERR_ParameterlessStructCtorsMustBePublic">
<source>Parameterless instance constructors in structs must be public</source>
<target state="new">Parameterless instance constructors in structs must be public</target>
<note />
</trans-unit>
<trans-unit id="ERR_PartialMethodAccessibilityDifference">
<source>Both partial method declarations must have identical accessibility modifiers.</source>
<target state="new">Both partial method declarations must have identical accessibility modifiers.</target>
Expand Down Expand Up @@ -952,6 +957,11 @@
<target state="new">target-typed object creation</target>
<note />
</trans-unit>
<trans-unit id="IDS_FeatureStructParameterlessConstructors">
<source>struct instance parameterless constructors</source>
<target state="new">struct instance parameterless constructors</target>
<note />
</trans-unit>
<trans-unit id="WRN_AnalyzerReferencesFramework">
<source>The assembly '{0}' containing type '{1}' references .NET Framework, which is not supported.</source>
<target state="new">The assembly '{0}' containing type '{1}' references .NET Framework, which is not supported.</target>
Expand Down
10 changes: 10 additions & 0 deletions src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -702,6 +702,11 @@
<target state="translated">'{0}' 메서드는 형식 매개 변수 '{1}'의 'struct' 제약 조건을 지정하지만 재정의되었거나 명시적으로 구현된 '{3}' 메서드의 해당 형식 매개 변수 '{2}'이(가) null을 허용하지 않는 값 형식이 아닙니다.</target>
<note />
</trans-unit>
<trans-unit id="ERR_ParameterlessStructCtorsMustBePublic">
<source>Parameterless instance constructors in structs must be public</source>
<target state="new">Parameterless instance constructors in structs must be public</target>
<note />
</trans-unit>
<trans-unit id="ERR_PartialMethodAccessibilityDifference">
<source>Both partial method declarations must have identical accessibility modifiers.</source>
<target state="new">Both partial method declarations must have identical accessibility modifiers.</target>
Expand Down Expand Up @@ -952,6 +957,11 @@
<target state="new">target-typed object creation</target>
<note />
</trans-unit>
<trans-unit id="IDS_FeatureStructParameterlessConstructors">
<source>struct instance parameterless constructors</source>
<target state="new">struct instance parameterless constructors</target>
<note />
</trans-unit>
<trans-unit id="WRN_AnalyzerReferencesFramework">
<source>The assembly '{0}' containing type '{1}' references .NET Framework, which is not supported.</source>
<target state="new">The assembly '{0}' containing type '{1}' references .NET Framework, which is not supported.</target>
Expand Down
10 changes: 10 additions & 0 deletions src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -702,6 +702,11 @@
<target state="translated">Metoda „{0}” określa ograniczenie „struct” dla parametru typu „{1}”, lecz odpowiadający parametr typu „{2}” przesłoniętej lub jawnie zaimplementowanej metody „{3}” nie jest nienullowalnym typem wartości.</target>
<note />
</trans-unit>
<trans-unit id="ERR_ParameterlessStructCtorsMustBePublic">
<source>Parameterless instance constructors in structs must be public</source>
<target state="new">Parameterless instance constructors in structs must be public</target>
<note />
</trans-unit>
<trans-unit id="ERR_PartialMethodAccessibilityDifference">
<source>Both partial method declarations must have identical accessibility modifiers.</source>
<target state="new">Both partial method declarations must have identical accessibility modifiers.</target>
Expand Down Expand Up @@ -952,6 +957,11 @@
<target state="new">target-typed object creation</target>
<note />
</trans-unit>
<trans-unit id="IDS_FeatureStructParameterlessConstructors">
<source>struct instance parameterless constructors</source>
<target state="new">struct instance parameterless constructors</target>
<note />
</trans-unit>
<trans-unit id="WRN_AnalyzerReferencesFramework">
<source>The assembly '{0}' containing type '{1}' references .NET Framework, which is not supported.</source>
<target state="new">The assembly '{0}' containing type '{1}' references .NET Framework, which is not supported.</target>
Expand Down
10 changes: 10 additions & 0 deletions src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -702,6 +702,11 @@
<target state="translated">O método '{0}' especifica uma restrição 'struct' para o parâmetro de tipo '{1}', mas o parâmetro de tipo correspondente '{2}' do método substituído ou implementado explicitamente '{3}' não é um tipo de valor não anulável.</target>
<note />
</trans-unit>
<trans-unit id="ERR_ParameterlessStructCtorsMustBePublic">
<source>Parameterless instance constructors in structs must be public</source>
<target state="new">Parameterless instance constructors in structs must be public</target>
<note />
</trans-unit>
<trans-unit id="ERR_PartialMethodAccessibilityDifference">
<source>Both partial method declarations must have identical accessibility modifiers.</source>
<target state="new">Both partial method declarations must have identical accessibility modifiers.</target>
Expand Down Expand Up @@ -952,6 +957,11 @@
<target state="new">target-typed object creation</target>
<note />
</trans-unit>
<trans-unit id="IDS_FeatureStructParameterlessConstructors">
<source>struct instance parameterless constructors</source>
<target state="new">struct instance parameterless constructors</target>
<note />
</trans-unit>
<trans-unit id="WRN_AnalyzerReferencesFramework">
<source>The assembly '{0}' containing type '{1}' references .NET Framework, which is not supported.</source>
<target state="new">The assembly '{0}' containing type '{1}' references .NET Framework, which is not supported.</target>
Expand Down
Loading

0 comments on commit 7eecef6

Please sign in to comment.