Skip to content

Sdk10 version #360

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

Open
wants to merge 75 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
75 commits
Select commit Hold shift + click to select a range
04ef6c2
Update BuildApiTest.cs
SimonCropp Jun 19, 2025
1967ea2
Update BuildApiTest.cs
SimonCropp Jun 20, 2025
e9d943c
Update BuildApiTest.cs
SimonCropp Jun 20, 2025
eb4dd0f
.
SimonCropp Jun 20, 2025
dc8079c
Update BuildApiTest.cs
SimonCropp Jun 20, 2025
bd28a54
Update BuildApiTest.cs
SimonCropp Jun 21, 2025
8685db5
Update BuildApiTest.cs
SimonCropp Jun 21, 2025
f72be2f
Update BuildApiTest.cs
SimonCropp Jun 21, 2025
ad8c14f
Update BuildApiTest.cs
SimonCropp Jun 21, 2025
2be4bcb
.
SimonCropp Jun 21, 2025
22a3a17
.
SimonCropp Jun 21, 2025
b4ee1ce
Update BuildApiTest.cs
SimonCropp Jun 21, 2025
e69bc4d
Update BuildApiTest.cs
SimonCropp Jun 21, 2025
4b408b7
.
SimonCropp Jun 21, 2025
5076b17
Update LinkReader.cs
SimonCropp Jun 21, 2025
11c1fe6
Update RoslynExtensions.cs
SimonCropp Jun 21, 2025
c2b507e
Update BuildApiTest.cs
SimonCropp Jun 21, 2025
e4107ae
.
SimonCropp Jun 21, 2025
4f08a9d
Update BuildApiTest.cs
SimonCropp Jun 21, 2025
3182b38
.
SimonCropp Jun 21, 2025
3a6784c
Update DelegatePolyfill.cs
SimonCropp Jun 21, 2025
da9e1d2
Update DateTimePolyfill.cs
SimonCropp Jun 21, 2025
44494b4
Update DateTimePolyfill.cs
SimonCropp Jun 21, 2025
eec2c12
Update DelegatePolyfill.cs
SimonCropp Jun 21, 2025
db703c3
.
SimonCropp Jun 21, 2025
ebdf2c8
Merge branch 'main' into sdk10Version
SimonCropp Jun 21, 2025
2b43a07
.
SimonCropp Jun 21, 2025
4fead01
Update global.json
SimonCropp Jun 21, 2025
19679b4
.
SimonCropp Jun 21, 2025
9a107d5
Merge branch 'main' into sdk10Version
SimonCropp Jun 21, 2025
8acb22b
.
SimonCropp Jun 21, 2025
59138fa
.
SimonCropp Jun 21, 2025
f7c82e1
.
SimonCropp Jun 22, 2025
7080b99
Update StringPolyfill.cs
SimonCropp Jun 22, 2025
39a0600
Update StringPolyfill.cs
SimonCropp Jun 22, 2025
8274504
Update BuildApiTest.cs
SimonCropp Jun 22, 2025
90bebd3
.
SimonCropp Jun 22, 2025
e505ab7
Update RegexPolyfill.cs
SimonCropp Jun 22, 2025
5bb0bf2
.
SimonCropp Jun 22, 2025
1352c30
.
SimonCropp Jun 22, 2025
909af2a
.
SimonCropp Jun 22, 2025
79df7fb
.
SimonCropp Jun 22, 2025
6c8cf16
Update ULongPolyfill.cs
SimonCropp Jun 22, 2025
9831355
.
SimonCropp Jun 22, 2025
4cbadc5
.
SimonCropp Jun 22, 2025
36c65b7
Update DelegatePolyfill.cs
SimonCropp Jun 22, 2025
b810c95
.
SimonCropp Jun 22, 2025
a4c55f3
Update OperatingSystemPolyfill.cs
SimonCropp Jun 22, 2025
3f27230
.
SimonCropp Jun 22, 2025
9641780
.
SimonCropp Jun 22, 2025
8235058
.
SimonCropp Jun 22, 2025
d5c7efa
.
SimonCropp Jun 22, 2025
59bd03a
.
SimonCropp Jun 22, 2025
bfb7053
.
SimonCropp Jun 22, 2025
5dda7ce
.
SimonCropp Jun 22, 2025
7ad69f3
Update SHA256Polyfill.cs
SimonCropp Jun 22, 2025
55006d2
Update RandomPolyfill.cs
SimonCropp Jun 22, 2025
38770df
Update PathPolyfill.cs
SimonCropp Jun 22, 2025
b5f5353
Update MathPolyfill.cs
SimonCropp Jun 22, 2025
9f6cbc2
Update GuidPolyfill.cs
SimonCropp Jun 22, 2025
5bcff65
Update FilePolyfill.cs
SimonCropp Jun 22, 2025
fa33737
Update EnumPolyfill.cs
SimonCropp Jun 22, 2025
62f6793
Update DelegatePolyfill.cs
SimonCropp Jun 22, 2025
6a25f8b
Update DateTimePolyfill.cs
SimonCropp Jun 22, 2025
df27369
Update DateTimeOffsetPolyfill.cs
SimonCropp Jun 22, 2025
6b15cf4
.
SimonCropp Jun 22, 2025
1a9eb64
.
SimonCropp Jun 22, 2025
cb7a494
Update RegexPolyfill.cs
SimonCropp Jun 22, 2025
6710bde
.
SimonCropp Jun 22, 2025
3e29264
.
SimonCropp Jun 22, 2025
68bc278
.
SimonCropp Jun 22, 2025
57cb419
.
SimonCropp Jun 22, 2025
e664b2a
.
SimonCropp Jun 22, 2025
248424d
Merge branch 'main' into sdk10Version
SimonCropp Jun 25, 2025
3946f98
.
SimonCropp Jun 25, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion apiCount.include.md
Original file line number Diff line number Diff line change
@@ -1 +1 @@
**API count: 571**
**API count: 572**
619 changes: 277 additions & 342 deletions api_list.include.md

Large diffs are not rendered by default.

607 changes: 278 additions & 329 deletions readme.md

Large diffs are not rendered by default.

225 changes: 164 additions & 61 deletions src/ApiBuilderTests/BuildApiTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,40 +13,19 @@ static BuildApiTest()
[Test]
public void RunWithRoslyn()
{
var types = ReadFiles();

var md = Path.Combine(solutionDirectory, "..", "api_list.include.md");
File.Delete(md);
using var writer = File.CreateText(md);
var count = 0;
count = WriteExtensions(writer, count);

var extensions = types["Polyfill"];
writer.WriteLine("### Extension methods");
writer.WriteLine();
foreach (var grouping in PublicMethods(extensions)
.GroupBy(_ => _.ParameterList.Parameters[0].Type!.ToString())
.OrderBy(_ => _.Key))
{
WriteTypeMethods(grouping.Key, writer, ref count, grouping);
}

writer.WriteLine("### Static helpers");
writer.WriteLine();
foreach (var (key, value) in types
.OrderBy(_ => _.Key)
.Where(_ => _.Key.EndsWith("Polyfill") &&
_.Key != "Polyfill"))
{
WriteTypeMethods(key, writer, ref count, value);
}

WriteHelper(types, "Guard", writer, ref count);
WriteHelper(types, "Lock", writer, ref count);
WriteHelper(types, nameof(KeyValuePair), writer, ref count);
WriteHelper("Guard*", writer, ref count);
WriteHelper("Lock", writer, ref count);
WriteHelper(nameof(KeyValuePair), writer, ref count);
WriteType(nameof(TaskCompletionSource), writer, ref count);
WriteType(nameof(UnreachableException), writer, ref count);

count += types.Count(_ => _.Key.EndsWith("Attribute"));
count += Directory.EnumerateFiles(polyfillDir, "*Attribute.cs", SearchOption.AllDirectories).Count();
// Index and Range
count++;
//Nullability*
Expand All @@ -57,37 +36,152 @@ public void RunWithRoslyn()
File.WriteAllText(countMd, $"**API count: {count}**");
}

static IEnumerable<Method> PublicMethods(HashSet<Method> type) =>
type.Where(_ => _.IsPublic() &&
!_.IsConstructor())
.OrderBy(_ => _.Identifier.ToString());

static Dictionary<string, HashSet<Method>> ReadFiles()
static int WriteExtensions(StreamWriter writer, int count)
{
var types = new Dictionary<string, HashSet<Method>>();
var methodComparer = EqualityComparer<Method>
.Create(
(x, y) => Key(x!) == Key(y!),
_ => Key(_).GetHashCode());
foreach (var file in Directory.EnumerateFiles(polyfillDir, "*.cs", SearchOption.AllDirectories))
var files = Directory.EnumerateFiles(polyfillDir, "*Polyfill*.cs", SearchOption.AllDirectories).ToList();

var instanceFiles = files
.Where(_ => Path.GetFileNameWithoutExtension(_).StartsWith("Polyfill_"))
.ToList();

var staticFiles = files
.Where(_ =>
{
var name = Path.GetFileNameWithoutExtension(_);
return name.EndsWith("Polyfill") &&
name != "Polyfill";
})
.ToList();

var instanceMethods = ReadMethodsForFiles(instanceFiles);

var instanceTypeNames = instanceMethods
.Select(FirstParameterType);

var staticTypeNames = staticFiles
.Select(Path.GetFileNameWithoutExtension)
.Select(_ => _.TrimEnd("Polyfill").ToString());

var typeNames = instanceTypeNames.Concat(staticTypeNames)
.Distinct()
.ToList();

writer.WriteLine("### Extension methods");
writer.WriteLine();

foreach (var name in typeNames.Order())
{
foreach (var type in Identifiers.ReadTypesForFile(file))
var instanceMethodsForType = instanceMethods
.Where(_ => FirstParameterType(_) == name)
.ToList();
writer.WriteLine($"#### {name}");
writer.WriteLine();
if (instanceMethodsForType.Count != 0)
{
foreach (var method in instanceMethodsForType.OrderBy(Key))
{
count++;
WriteSignature(method, writer);
}
}

var staticExtension = staticFiles
.SingleOrDefault(_ => Path.GetFileNameWithoutExtension(_).TrimEnd("Polyfill").ToString() == name);
if (staticExtension != null)
{
var identifier = type.Identifier.Text;
if (!types.TryGetValue(identifier, out var methods))
foreach (var method in ReadMethodsForFiles([staticExtension]).OrderBy(Key))
{
methods = new(methodComparer);
types.Add(identifier, methods);
count++;
WriteSignature(method, writer);
}

foreach (var method in type.PublicMethods())
foreach (var property in ReadPropertiesForFiles([staticExtension]))
{
methods.Add(method);
count++;
WriteSignature(property, writer);
}
}

writer.WriteLine();
writer.WriteLine();
}

return count;
}

static Dictionary<string, string> langwordToType = new()
{
["bool"] = "Boolean",
["byte"] = "Byte",
["sbyte"] = "SByte",
["char"] = "Char",
["decimal"] = "Decimal",
["double"] = "Double",
["float"] = "Single",
["int"] = "Int32",
["uint"] = "UInt32",
["long"] = "Int64",
["ulong"] = "UInt64",
["object"] = "Object",
["short"] = "Int16",
["ushort"] = "UInt16",
["string"] = "String"
};

static string FirstParameterType(Method method)
{
var type = method.ParameterList.Parameters[0].Type!.ToString();
return langwordToType.GetValueOrDefault(type, type);
}

static List<Method> ReadMethodsForFiles(string pattern)
{
var files = Directory.EnumerateFiles(polyfillDir, $"{pattern}.cs", SearchOption.AllDirectories);
return ReadMethodsForFiles(files);
}

private static List<Method> ReadMethodsForFiles(IEnumerable<string> files)
{
var types = files
.SelectMany(Identifiers.ReadTypesForFile)
.ToList();

var distinctTypes = types.Select(_ => _.Identifier.Text).Distinct().ToList();
if (distinctTypes.Count > 1)
{
throw new(string.Join(", ", distinctTypes));
}

return types
.SelectMany(_ => _.PublicMethods())
.DistinctBy(Key)
.OrderBy(Key)
.ToList();
}

static List<Property> ReadPropertiesForFiles(string pattern)
{
var files = Directory.EnumerateFiles(polyfillDir, $"{pattern}.cs", SearchOption.AllDirectories);
return ReadPropertiesForFiles(files);
}

static List<Property> ReadPropertiesForFiles(IEnumerable<string> files)
{
var types = files
.SelectMany(Identifiers.ReadTypesForFile)
.ToList();

var distinctTypes = types.DistinctBy(_ => _.Identifier.Text).ToList();
if (distinctTypes.Count > 1)
{
throw new(string.Join(", ", distinctTypes));
}

return types;
return types
.SelectMany(_ => _.PublicProperties())
.DistinctBy(_ => _.Identifier.Text)
.OrderBy(_ => _.Identifier.Text)
.ToList();
}

static void WriteType(string name, StreamWriter writer, ref int count)
Expand All @@ -100,12 +194,8 @@ static void WriteType(string name, StreamWriter writer, ref int count)
count++;
}

static void WriteHelper(Dictionary<string, HashSet<Method>> types, string name, StreamWriter writer, ref int count)
{
var methods = types[name];

WriteTypeMethods(name, writer, ref count, methods.OrderBy(Key));
}
static void WriteHelper(string name, StreamWriter writer, ref int count) =>
WriteTypeMethods(name.Trim('*'), writer, ref count, ReadMethodsForFiles(name));

static void WriteTypeMethods(string name, StreamWriter writer, ref int count, IEnumerable<Method> methods)
{
Expand Down Expand Up @@ -144,6 +234,20 @@ static void WriteSignature(Method method, StreamWriter writer)
}
}

static void WriteSignature(Property method, StreamWriter writer)
{
var signature = new StringBuilder(method.Identifier.Text);

if (method.TryGetReference(out var reference))
{
writer.WriteLine($" * `{signature}` [reference]({reference})");
}
else
{
writer.WriteLine($" * `{signature}`");
}
}

static string Key(Method method) =>
$"{method.Identifier.Text}{BuildTypeArgs(method)}({BuildParameters(method, false)})";

Expand All @@ -160,17 +264,16 @@ static string BuildTypeArgs(Method method)

static string BuildParameters(Method method, bool skipThisModified)
{
List<Parameter> parameters;
var parameters = method
.ParameterList
.Parameters
.ToList();

if (skipThisModified)
{
parameters = method.ParameterList
.Parameters
.Where(_ => !_.IsThis()).ToList();
}
else
{
parameters = method.ParameterList
.Parameters.ToList();
parameters = parameters
.Where(_ => !_.IsThis())
.ToList();
}

if (parameters.Count > 0)
Expand Down
4 changes: 2 additions & 2 deletions src/ApiBuilderTests/LinkReader.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
public static class LinkReader
{
public static bool TryGetReference(this Method method, [NotNullWhen(true)] out string? reference)
public static bool TryGetReference(this Member member, [NotNullWhen(true)] out string? reference)
{
var syntaxTrivia = method.GetLeadingTrivia();
var syntaxTrivia = member.GetLeadingTrivia();
foreach (var trivia in syntaxTrivia)
{
if (!trivia.IsKind(SyntaxKind.SingleLineCommentTrivia))
Expand Down
7 changes: 7 additions & 0 deletions src/ApiBuilderTests/RoslynExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,13 @@ public static IEnumerable<Method> PublicMethods(this Type type) =>
_.IsPublic() &&
!_.IsConstructor());

public static IEnumerable<Property> PublicProperties(this Type type) =>
type
.DescendantNodes()
.OfType<Property>()
.Where(_ => _.Parent == type &&
_.IsPublic());

public static bool IsConstructor(this Method method)
{
if (method.Parent is Type type)
Expand Down
Loading