Skip to content

Commit cf89ef0

Browse files
committed
Add a new template specifically for extern aliases, and use it to implement "missing" examples
1 parent 7cd8ba4 commit cf89ef0

File tree

13 files changed

+109
-24
lines changed

13 files changed

+109
-24
lines changed

standard/namespaces.md

Lines changed: 15 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -138,8 +138,7 @@ An error occurs if a program declares an extern alias for which no external defi
138138
139139
> *Example*: The following program declares and uses two extern aliases, `X` and `Y`, each of which represent the root of a distinct namespace hierarchy:
140140
>
141-
> <!-- ExternalRef$Example: {template:"standalone-lib-without-using", name:"ExternAliasDirectives", expectedErrors:["x","x"], expectedWarnings:["x","x"]} -->
142-
> <!-- FIX: I got this to work outside the test framework. 1. The external definitions are in files ExternAliasX.cs and ExternAliasY.cs in the additional-files folder. 2. We need a DLL for each of these compiled using csc ExternAliasX.cs -t:library and csc ExternAliasY.cs -t:library 3. The Library.cs file needs to be compiled using csc Library.cs -t:library -r:X=ExternAliasX.dll -r:Y=ExternAliasY.dll, where the two references must include the path to the DLLs. -->
141+
> <!-- Example: {template:"extern-lib", name:"ExternAliasDirectives", project:"ExampleProject"} -->
143142
> ```csharp
144143
> extern alias X;
145144
> extern alias Y;
@@ -224,9 +223,7 @@ Within using directives, global attributes and member declarations in a compilat
224223
225224
> *Example*: For example:
226225
>
227-
> <!-- ExternalRef$Example: {template:"standalone-lib-without-using", name:"UsingAliasDirectives3", expectedErrors:["x","x"], expectedWarnings:["x","x"]} -->
228-
> <!-- FIX: I got this to work outside the test framework. 1. The external definition is in file ExternAliasN2.cs in the additional-files folder. 2. We need a DLL for this compiled using csc ExternAliasN2.cs -t:library 3. The Library.cs file needs to be compiled using csc Library.cs -t:library -r:X=ExternAliasN2.dll, where the reference must include the path to the DLL. -->
229-
> <!-- IncompleteExample: {template:"standalone-lib", name:"UsingAliasDirectives3", expectedErrors:["x","x"], expectedWarnings:["x","x"]} -->
226+
> <!-- Example: {template:"extern-lib", name:"UsingAliasDirectives3", project:"ExampleProject"} -->
230227
> ```csharp
231228
> namespace N1
232229
> {
@@ -238,8 +235,7 @@ Within using directives, global attributes and member declarations in a compilat
238235
>
239236
> Above, within member declarations in the `N1namespace, `N2` is an alias for some namespace whose definition is external to the source code of the program. Class `N1.B` derives from class `N2.A`. The same effect can be obtained by creating an alias `A` for `N2.A` and then referencing `A`:
240237
>
241-
> <!-- ExternalRef$Example: {template:"standalone-lib-without-using", name:"UsingAliasDirectives4", expectedErrors:["x","x"], expectedWarnings:["x","x"]} -->
242-
> <!-- FIX: I got this to work outside the test framework. 1. The external definition is in file ExternAliasN2.cs in the additional-files folder. 2. We need a DLL for this compiled using csc ExternAliasN2.cs -t:library 3. The Library.cs file needs to be compiled using csc Library.cs -t:library -r:X=ExternAliasN2.dll, where the reference must include the path to the DLL. -->
238+
> <!-- Example: {template:"extern-lib", name:"UsingAliasDirectives4", project:"ExampleProject"} -->
243239
> ```csharp
244240
> namespace N1
245241
> {
@@ -257,8 +253,7 @@ An *extern_alias_directive* or *using_alias_directive* makes an alias available
257253
258254
> *Example*: In the following code
259255
>
260-
> <!-- ExternalRef$Example: {template:"standalone-lib-without-using", name:"UsingAliasDirectives5", expectedErrors:["x","x"], expectedWarnings:["x","x"]} -->
261-
> <!-- FIX: I got this to work outside the test framework. 1. The external definition is in file ExternAliasR1.cs in the additional-files folder. 2. We need a DLL for this compiled using csc ExternAliasR1.cs -t:library 3. The Library.cs file needs to be compiled using csc Library.cs N1N2.cs -t:library -r:X=ExternAliasR1.dll, where the reference must include the path to the DLL. -->
256+
> <!-- Example: {template:"extern-lib", name:"UsingAliasDirectives5", project:"ExampleProject", expectedErrors:["CS0246","CS0432"], additionalFiles:["N1N2.cs"]} -->
262257
> ```csharp
263258
> namespace N3
264259
> {
@@ -275,8 +270,7 @@ An *extern_alias_directive* or *using_alias_directive* makes an alias available
275270
>
276271
> the scopes of the alias directives that introduce `R1` and `R2` only extend to member declarations in the namespace body in which they are contained, so `R1` and `R2` are unknown in the second namespace declaration. However, placing the alias directives in the containing compilation unit causes the alias to become available within both namespace declarations:
277272
>
278-
> <!-- ExternalRef$Example: {template:"standalone-lib-without-using", name:"UsingAliasDirectives6", expectedErrors:["x","x"], expectedWarnings:["x","x"]} -->
279-
> <!-- FIX: I got this to work outside the test framework. 1. The external definition is in file ExternAliasR1.cs in the additional-files folder. 2. We need a DLL for this compiled using csc ExternAliasR1.cs -t:library 3. The Library.cs file needs to be compiled using csc Library.cs N1N2.cs -t:library -r:X=ExternAliasR1.dll, where the reference must include the path to the DLL. -->
273+
> <!-- Example: {template:"extern-lib", name:"UsingAliasDirectives6", project:"ExampleProject", additionalFiles:["N1N2.cs"]} -->
280274
> ```csharp
281275
> extern alias R1;
282276
>
@@ -299,18 +293,17 @@ Each *extern_alias_directive* or *using_alias_directive* in a *compilation_unit*
299293
300294
> *Example*:
301295
>
302-
> <!-- ExternalRef$Example: {template:"standalone-lib-without-using", name:"UsingAliasDirectives7", expectedErrors:["x","x"], expectedWarnings:["x","x"]} -->
303-
> <!-- FIX: I got this to work outside the test framework. 1. The external definitions are in files ExternAliasA.cs and ExternAliasB.cs in the additional-files folder. 2. We need a DLL for each of these compiled using csc ExternAliasA.cs -t:library and csc ExternAliasB.cs -t:library 3. The Library.cs file needs to be compiled using csc Library.cs N1N2.cs -t:library -r:X=ExternAliasA.dll -r:Y=ExternAliasB.dll, where the two references must include the path to the DLLs. -->
296+
> <!-- Example: {template:"extern-lib", name:"UsingAliasDirectives7", project:"ExampleProject", expectedErrors:["CS1537"], additionalFiles:["N1N2.cs"]} -->
304297
> ```csharp
305-
> extern alias A;
306-
> extern alias B;
298+
> extern alias X;
299+
> extern alias Y;
307300
>
308-
> using A = N1.N2; // Error: alias A already exists
301+
> using X = N1.N2; // Error: alias X already exists
309302
>
310-
> class B {} // Ok
303+
> class Y {} // Ok
311304
> ```
312305
>
313-
> The using alias named `A` causes an error since there is already an alias named `A` in the same compilation unit. The class named `B` does not conflict with the extern alias named `B` since these names are added to distinct declaration spaces. The former is added to the global declaration space and the latter is added to the alias declaration space for this compilation unit.
306+
> The using alias named `X` causes an error since there is already an alias named `X` in the same compilation unit. The class named `Y` does not conflict with the extern alias named `Y` since these names are added to distinct declaration spaces. The former is added to the global declaration space and the latter is added to the alias declaration space for this compilation unit.
314307
>
315308
> When an alias name matches the name of a member of a namespace, usage of either must be appropriately qualified:
316309
>
@@ -366,23 +359,22 @@ The order in which *extern_alias_directive*s are written has no significance. Li
366359
367360
> *Example*: In the following code
368361
>
369-
> <!-- ExternalRef$Example: {template:"standalone-lib-without-using", name:"UsingAliasDirectives10", expectedErrors:["x","x"], expectedWarnings:["x","x"]} -->
370-
> <!-- FIX: I got this to work outside the test framework. 1. The external definition is in file ExternAliasE.cs in the additional-files folder. 2. We need a DLL for this compiled using csc ExternAliasE.cs -t:library 3. The Library.cs file needs to be compiled using csc Library.cs -t:library -r:E=ExternAliasE.dll, where the reference must include the path to the DLL. -->
362+
> <!-- Example: {template:"extern-lib", name:"UsingAliasDirectives10", project:"ExampleProject", expectedErrors:["CS0246"]} -->
371363
> ```csharp
372364
> namespace N1.N2 {}
373365
>
374366
> namespace N3
375367
> {
376-
> extern alias E;
368+
> extern alias X;
377369
>
378-
> using R1 = E::N; // OK
370+
> using R1 = X::N; // OK
379371
> using R2 = N1; // OK
380372
> using R3 = N1.N2; // OK
381373
> using R4 = R2.N2; // Error, R2 unknown
382374
> }
383375
> ```
384376
>
385-
> the last *using_alias_directive* results in a compile-time error because it is not affected by the previous *using_alias_directive*. The first *using_alias_directive* does not result in an error since the scope of the extern alias E includes the *using_alias_directive*.
377+
> the last *using_alias_directive* results in a compile-time error because it is not affected by the previous *using_alias_directive*. The first *using_alias_directive* does not result in an error since the scope of the extern alias X includes the *using_alias_directive*.
386378
>
387379
> *end example*
388380

tools/ExampleExtractor/ExampleMetadata.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,14 @@ public class ExampleMetadata
1919
[JsonProperty("replaceEllipsis")]
2020
public bool ReplaceEllipsis { get; set; }
2121

22+
/// <summary>
23+
/// When null, the sample directory is expected to contain a single .csproj file.
24+
/// Specify this as the project file (without extension) to disambiguate for
25+
/// samples with multiple project files.
26+
/// </summary>
27+
[JsonProperty("project")]
28+
public string Project { get; set; }
29+
2230
/// <summary>
2331
/// When set, and when <see cref="ReplaceEllipsis"/> is true, this list is used
2432
/// to provide the replacements, allowing for return statements etc.

tools/ExampleTester/GeneratedExample.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,9 @@ internal async Task<bool> Test(TesterConfiguration configuration)
4040

4141
using var workspace = MSBuildWorkspace.Create();
4242
// TODO: Validate this more cleanly.
43-
var projectFile = Directory.GetFiles(directory, "*.csproj").Single();
43+
var projectFile = Metadata.Project is string specifiedProject
44+
? Path.Combine(directory, $"{specifiedProject}.csproj")
45+
: Directory.GetFiles(directory, "*.csproj").Single();
4446
var project = await workspace.OpenProjectAsync(projectFile);
4547
var compilation = await project.GetCompilationAsync();
4648
if (compilation is null)
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
$example-code
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<TargetFramework>net6.0</TargetFramework>
5+
<EnableDefaultItems>false</EnableDefaultItems>
6+
<NoWarn>CS0169</NoWarn>
7+
</PropertyGroup>
8+
9+
<ItemGroup>
10+
<Compile Include="*.cs" Exclude="Extern*.cs" />
11+
<ProjectReference Include="ExternX.csproj" Aliases="X" />
12+
<ProjectReference Include="ExternY.csproj" Aliases="Y" />
13+
<ProjectReference Include="ExternR1.csproj" Aliases="R1" />
14+
<ProjectReference Include="ExternN2.csproj" Aliases="N2" />
15+
</ItemGroup>
16+
17+
</Project>
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
public class A {}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<TargetFramework>net6.0</TargetFramework>
5+
<EnableDefaultItems>false</EnableDefaultItems>
6+
</PropertyGroup>
7+
8+
<ItemGroup>
9+
<Compile Include="ExternN2.cs" />
10+
</ItemGroup>
11+
12+
</Project>
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
public class A {}
2+
3+
namespace N1.N2
4+
{
5+
public interface I {}
6+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<TargetFramework>net6.0</TargetFramework>
5+
<EnableDefaultItems>false</EnableDefaultItems>
6+
</PropertyGroup>
7+
8+
<ItemGroup>
9+
<Compile Include="ExternR1.cs" />
10+
</ItemGroup>
11+
12+
</Project>
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
namespace N
2+
{
3+
public class A {}
4+
public class B {}
5+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<TargetFramework>net6.0</TargetFramework>
5+
<EnableDefaultItems>false</EnableDefaultItems>
6+
</PropertyGroup>
7+
8+
<ItemGroup>
9+
<Compile Include="ExternX.cs" />
10+
</ItemGroup>
11+
12+
</Project>
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
namespace N
2+
{
3+
public class B {}
4+
public class C {}
5+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<TargetFramework>net6.0</TargetFramework>
5+
<EnableDefaultItems>false</EnableDefaultItems>
6+
</PropertyGroup>
7+
8+
<ItemGroup>
9+
<Compile Include="ExternY.cs" />
10+
</ItemGroup>
11+
12+
</Project>

0 commit comments

Comments
 (0)