Skip to content

Commit

Permalink
Merge branch 'main' into andrueastman/bitwiseEnums
Browse files Browse the repository at this point in the history
  • Loading branch information
andrueastman authored Sep 1, 2023
2 parents ac256ef + 466e0cd commit 9f340bf
Show file tree
Hide file tree
Showing 4 changed files with 92 additions and 19 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Fixes uuid conversion to string value in PathParameters in Go. [#3106](https://github.com/microsoft/kiota/issues/3176)
- Fixes a bug with incorrect reserved models renaming that occurs sometimes depending on the order of type processing [microsoftgraph/msgraph-sdk-dotnet/issues/2084](https://github.com/microsoftgraph/msgraph-sdk-dotnet/issues/2084)
- Work around a System.ComandLine bug where adjacent matching command names would crash the CLI parser (CLI). [microsoftgraph/msgraph-cli#316](https://github.com/microsoftgraph/msgraph-cli/issues/316) [microsoftgraph/msgraph-cli#320](https://github.com/microsoftgraph/msgraph-cli/issues/320), [dotnet/command-line-api#2260](https://github.com/dotnet/command-line-api/issues/2260)
- Aggregate typescript import statements by source [#3232](https://github.com/microsoft/kiota/issues/3232)
- Fixes a bug in dotnet where enums types would not be fully disambiguated when initialized in constructor with default values and existing conflicting property exists [#3233]

## [1.5.1] - 2023-08-08
Expand Down
2 changes: 1 addition & 1 deletion src/Kiota.Builder/Refiners/TypeScriptRefiner.cs
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ public override Task Refine(CodeNamespace generatedCode, CancellationToken cance
static x =>
{
var result = new List<CodeUsing>() {
new() { Name = "ParseNode", Declaration = new() { Name = AbstractionsPackageName, IsExternal = true } }
new() { Name = "ParseNode", Declaration = new() { Name = AbstractionsPackageName, IsExternal = true }, IsErasable = true }
};
if (x.Parent?.Parent != null)
result.Add(new() { Name = x.Parent.Parent.Name, Declaration = new() { Name = x.Parent.Name, TypeDefinition = x.Parent } });
Expand Down
31 changes: 17 additions & 14 deletions src/Kiota.Builder/Writers/TypeScript/CodeUsingWriter.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;

using Kiota.Builder.CodeDOM;

namespace Kiota.Builder.Writers.TypeScript;
Expand All @@ -19,35 +17,40 @@ public void WriteCodeElement(IEnumerable<CodeUsing> usings, CodeNamespace parent
var enumeratedUsings = usings.ToArray();
var externalImportSymbolsAndPaths = enumeratedUsings
.Where(static x => x.IsExternal)
.Select(static x => new { Symbol = x.Name, Alias = string.Empty, Path = x.Declaration?.Name ?? string.Empty, ShouldUseTypeImport = x.IsErasable });
.Select(static x => new { Symbol = x.Name, Alias = string.Empty, Path = x.Declaration?.Name ?? string.Empty, ShouldUseTypeImport = GetShouldUseTypeImport(x) });
var internalImportSymbolsAndPaths = enumeratedUsings
.Where(static x => !x.IsExternal)
.Select(x => new { CodeUsingPathTokens = _relativeImportManager.GetRelativeImportPathForUsing(x, parentNamespace), ShouldUseTypeImport = GetShouldUseTypeImport(x) });
var importSymbolsAndPaths = externalImportSymbolsAndPaths
.Union(internalImportSymbolsAndPaths.Select(static x => new { Symbol = x.CodeUsingPathTokens.Item1, Alias = x.CodeUsingPathTokens.Item2, Path = x.CodeUsingPathTokens.Item3, x.ShouldUseTypeImport }))
.GroupBy(static x => (x.Path, x.ShouldUseTypeImport))
.OrderBy(static x => x.Key.Path, StringComparer.Ordinal)
.ThenBy(static x => x.Key.ShouldUseTypeImport);
foreach (var codeUsing in importSymbolsAndPaths.Where(static x => !string.IsNullOrWhiteSpace(x.Key.Path)))
writer.WriteLine($"import {codeUsing.Select(x => x.ShouldUseTypeImport ? "type " : "").Distinct().OrderBy(static x => x, StringComparer.Ordinal).Aggregate(static (x, y) => x)}" +
$"{{{codeUsing.Select(static x => GetAliasedSymbol(x.Symbol, x.Alias)).Distinct().OrderBy(static x => x, StringComparer.Ordinal).Aggregate(static (x, y) => x + ", " + y)}}} from '{codeUsing.Key.Path}';");
.GroupBy(static x => x.Path)
.OrderBy(static x => x.Key);
foreach (var codeUsing in importSymbolsAndPaths.Where(static x => !string.IsNullOrWhiteSpace(x.Key)))
writer.WriteLine($"import {{ {codeUsing.Select(static x => GetAliasedSymbol(x.Symbol, x.Alias, x.ShouldUseTypeImport)).Distinct().OrderBy(static x => x).Aggregate(static (x, y) => x + ", " + y)} }} from '{codeUsing.Key}';");

writer.WriteLine();
}

/**
* Determines whether the import clause on TypeScript should include `import type` or just normal `import` statement
*
* @param codeUsing The code using statement to check
**/
private static bool GetShouldUseTypeImport(CodeUsing codeUsing)
{
// Check if codeUsing is Erassable or codeUsing.Declaration is an instance of CodeType and if codeType.TypeDefinition is an instance of CodeInterface
return codeUsing.IsErasable || codeUsing.Declaration is CodeType codeType && codeType.TypeDefinition is CodeInterface;
// Check if codeUsing is Erassable
if (codeUsing.IsErasable) return true;
if (codeUsing.Declaration is CodeType codeType)
{
if (codeType.TypeDefinition is CodeInterface) return true;
// this will handle endge cases for typescript Declarations that are already known to be interfaces: RequestConfiguration, QueryParameters, and Model classes
if (codeType.TypeDefinition is CodeClass codeClass && codeClass.IsOfKind(CodeClassKind.RequestConfiguration, CodeClassKind.QueryParameters, CodeClassKind.Model)) return true;
}
return false;
}

private static string GetAliasedSymbol(string symbol, string alias)
private static string GetAliasedSymbol(string symbol, string alias, bool shouldUseTypeImport)
{
return string.IsNullOrEmpty(alias) ? symbol : $"{symbol} as {alias}";
var importPrefix = shouldUseTypeImport ? "type " : "";
return string.IsNullOrEmpty(alias) ? $"{importPrefix}{symbol}" : $"{importPrefix}{symbol} as {alias}";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ public void WritesAliasedSymbol()
};
usingWriter.WriteCodeElement(new CodeUsing[] { us }, root, writer);
var result = tw.ToString();
Assert.Contains("import {Bar as baz} from", result);
Assert.Contains("import { Bar as baz } from", result);
}
[Fact]
public void DoesntAliasRegularSymbols()
Expand All @@ -62,7 +62,7 @@ public void DoesntAliasRegularSymbols()
};
usingWriter.WriteCodeElement(new CodeUsing[] { us }, root, writer);
var result = tw.ToString();
Assert.Contains("import {Bar} from", result);
Assert.Contains("import { Bar } from", result);
}

[Fact]
Expand All @@ -86,7 +86,7 @@ public void WritesImportTypeStatementForGeneratedInterfaces()
};
usingWriter.WriteCodeElement(new CodeUsing[] { us }, root, writer);
var result = tw.ToString();
Assert.Contains("import type {Bar} from", result);
Assert.Contains("import { type Bar } from", result);
}

[Fact]
Expand All @@ -109,6 +109,75 @@ public void WritesImportTypeStatementForDenotedExternalLibraries()
};
usingWriter.WriteCodeElement(new CodeUsing[] { us }, root, writer);
var result = tw.ToString();
Assert.Contains("import type {Bar} from", result);
Assert.Contains("import { type Bar } from", result);
}

[Fact]
public void WritesImportTypeStatementForRequestConfiguration()
{
var usingWriter = new CodeUsingWriter("foo");
var codeClass = root.AddClass(new CodeClass
{
Name = "bar",
Kind = CodeClassKind.RequestConfiguration
}).First();
var us = new CodeUsing
{
Name = "bar",
Declaration = new CodeType
{
Name = codeClass.Name,
TypeDefinition = codeClass,
}
};
usingWriter.WriteCodeElement(new CodeUsing[] { us }, root, writer);
var result = tw.ToString();
Assert.Contains("import { type Bar } from", result);
}

[Fact]
public void WritesImportTypeStatementForQueryParameters()
{
var usingWriter = new CodeUsingWriter("foo");
var codeClass = root.AddClass(new CodeClass
{
Name = "bar",
Kind = CodeClassKind.QueryParameters
}).First();
var us = new CodeUsing
{
Name = "bar",
Declaration = new CodeType
{
Name = codeClass.Name,
TypeDefinition = codeClass,
}
};
usingWriter.WriteCodeElement(new CodeUsing[] { us }, root, writer);
var result = tw.ToString();
Assert.Contains("import { type Bar } from", result);
}

[Fact]
public void WritesImportTypeStatementForModel()
{
var usingWriter = new CodeUsingWriter("foo");
var codeClass = root.AddClass(new CodeClass
{
Name = "bar",
Kind = CodeClassKind.Model
}).First();
var us = new CodeUsing
{
Name = "bar",
Declaration = new CodeType
{
Name = codeClass.Name,
TypeDefinition = codeClass,
}
};
usingWriter.WriteCodeElement(new CodeUsing[] { us }, root, writer);
var result = tw.ToString();
Assert.Contains("import { type Bar } from", result);
}
}

0 comments on commit 9f340bf

Please sign in to comment.