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

feature/indexers revamp #2532

Merged
merged 2 commits into from
Apr 11, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 2 additions & 2 deletions src/Kiota.Builder/CodeDOM/CodeClass.cs
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,9 @@ public CodeIndexer? Indexer
if (Indexer is CodeIndexer existingIndexer)
{
RemoveChildElement(existingIndexer);
AddRange(CodeMethod.FromIndexer(existingIndexer, $"By{existingIndexer.SerializationName.CleanupSymbolName().ToFirstCharacterUpperCase()}", true));
AddRange(CodeMethod.FromIndexer(existingIndexer, static x => $"With{x.ToFirstCharacterUpperCase()}", static x => x.ToFirstCharacterUpperCase(), true));
}
AddRange(CodeMethod.FromIndexer(value, $"By{value.SerializationName.CleanupSymbolName().ToFirstCharacterUpperCase()}", false));
AddRange(CodeMethod.FromIndexer(value, static x => $"With{x.ToFirstCharacterUpperCase()}", static x => x.ToFirstCharacterUpperCase(), false));
}
else
AddRange(value);
Expand Down
7 changes: 7 additions & 0 deletions src/Kiota.Builder/CodeDOM/CodeIndexer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,13 @@ public required CodeTypeBase ReturnType
returnType = value;
}
}
/// <summary>
/// The name of the parameter to use for the indexer.
/// </summary>
public required string IndexParameterName
{
get; set;
}
public string SerializationName { get; set; } = string.Empty;
public CodeDocumentation Documentation { get; set; } = new();
/// <summary>
Expand Down
7 changes: 4 additions & 3 deletions src/Kiota.Builder/CodeDOM/CodeMethod.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using Kiota.Builder.Extensions;

namespace Kiota.Builder.CodeDOM;

Expand Down Expand Up @@ -74,7 +75,7 @@ public object Clone()
public class CodeMethod : CodeTerminalWithKind<CodeMethodKind>, ICloneable, IDocumentedElement
{
public static readonly CodeParameterKind ParameterKindForConvertedIndexers = CodeParameterKind.Custom;
public static CodeMethod FromIndexer(CodeIndexer originalIndexer, string? methodNameSuffix, bool parameterNullable)
public static CodeMethod FromIndexer(CodeIndexer originalIndexer, Func<string, string> methodNameCallback, Func<string, string> parameterNameCallback, bool parameterNullable)
{
ArgumentNullException.ThrowIfNull(originalIndexer);
var method = new CodeMethod
Expand All @@ -83,7 +84,7 @@ public static CodeMethod FromIndexer(CodeIndexer originalIndexer, string? method
IsStatic = false,
Access = AccessModifier.Public,
Kind = CodeMethodKind.IndexerBackwardCompatibility,
Name = originalIndexer.PathSegment + methodNameSuffix,
Name = methodNameCallback(originalIndexer.IndexParameterName),
Documentation = new()
{
Description = originalIndexer.Documentation.Description,
Expand All @@ -95,7 +96,7 @@ public static CodeMethod FromIndexer(CodeIndexer originalIndexer, string? method
method.ReturnType.IsNullable = false;
var parameter = new CodeParameter
{
Name = "id",
Name = parameterNameCallback(originalIndexer.IndexParameterName),
Optional = false,
Kind = ParameterKindForConvertedIndexers,
Documentation = new()
Expand Down
1 change: 1 addition & 0 deletions src/Kiota.Builder/KiotaBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -858,6 +858,7 @@ private CodeIndexer CreateIndexer(string childIdentifier, string childType, Open
ReturnType = new CodeType { Name = childType },
SerializationName = currentNode.Segment.SanitizeParameterNameForUrlTemplate(),
PathSegment = parentNode.GetNodeNamespaceFromPath(string.Empty).Split('.').Last(),
IndexParameterName = currentNode.Segment.CleanupSymbolName(),
};
}

Expand Down
52 changes: 4 additions & 48 deletions src/Kiota.Builder/Refiners/CommonLanguageRefiner.cs
Original file line number Diff line number Diff line change
Expand Up @@ -657,59 +657,15 @@ protected static void MoveClassesWithNamespaceNamesUnderNamespace(CodeElement cu
}
CrawlTree(currentElement, MoveClassesWithNamespaceNamesUnderNamespace);
}
protected static void ReplaceIndexersByMethodsWithParameter(CodeElement currentElement, bool parameterNullable, string? methodNameSuffix = default)
protected static void ReplaceIndexersByMethodsWithParameter(CodeElement currentElement, bool parameterNullable, Func<string, string> methodNameCallback, Func<string, string> parameterNameCallback)
{
if (currentElement is CodeIndexer currentIndexer &&
currentElement.Parent is CodeClass indexerParentClass &&
indexerParentClass.Parent is CodeNamespace indexerNamespace &&
indexerNamespace.Parent is CodeNamespace lookupNamespace)
currentElement.Parent is CodeClass indexerParentClass)
{
indexerParentClass.RemoveChildElement(currentElement);
AddIndexerMethod(indexerParentClass,
methodNameSuffix,
parameterNullable,
currentIndexer,
lookupNamespace);
}
CrawlTree(currentElement, c => ReplaceIndexersByMethodsWithParameter(c, parameterNullable, methodNameSuffix));
}
private static void AddIndexerMethod(CodeClass indexerParentClass, string? methodNameSuffix, bool parameterNullable, CodeIndexer currentIndexer, CodeNamespace lookupNamespace)
{
if (lookupNamespace.Classes
.Where(static x => x.IsOfKind(CodeClassKind.RequestBuilder))
.SelectMany(static x => x.Properties)
.Where(x => x.IsOfKind(CodePropertyKind.RequestBuilder) &&
x.Type is CodeType xType &&
xType.TypeDefinition == indexerParentClass)
.Select(static x => x.Parent)
.OfType<CodeClass>()
.FirstOrDefault() is CodeClass parentClassForProperty)
{
parentClassForProperty.AddMethod(CodeMethod.FromIndexer(currentIndexer, methodNameSuffix, parameterNullable));
}
else if (lookupNamespace.Classes
.Where(static x => x.IsOfKind(CodeClassKind.RequestBuilder))
.SelectMany(static x => x.Methods)
.Where(x => x.IsOfKind(CodeMethodKind.RequestBuilderWithParameters, CodeMethodKind.RequestBuilderBackwardCompatibility) &&
x.ReturnType is CodeType xMethodType &&
xMethodType.TypeDefinition == indexerParentClass)
.Select(static x => x.Parent)
.OfType<CodeClass>()
.FirstOrDefault() is CodeClass parentClassForMethod)
{
parentClassForMethod.AddMethod(CodeMethod.FromIndexer(currentIndexer, methodNameSuffix, parameterNullable));
}
else if (lookupNamespace.GetImmediateParentOfType<CodeNamespace>() is CodeNamespace parentNamespace &&
parentNamespace.Classes
.Where(static x => x.IsOfKind(CodeClassKind.RequestBuilder))
.SelectMany(static x => x.Methods)
.FirstOrDefault(x => x.IsOfKind(CodeMethodKind.IndexerBackwardCompatibility) &&
x.ReturnType is CodeType xMethodType &&
xMethodType.TypeDefinition == indexerParentClass)
is not null)
{
indexerParentClass.AddMethod(CodeMethod.FromIndexer(currentIndexer, methodNameSuffix, parameterNullable)); //we already went one up with the previous indexer
indexerParentClass.AddMethod(CodeMethod.FromIndexer(currentIndexer, methodNameCallback, parameterNameCallback, parameterNullable));
}
CrawlTree(currentElement, c => ReplaceIndexersByMethodsWithParameter(c, parameterNullable, methodNameCallback, parameterNameCallback));
}
internal void DisableActionOf(CodeElement current, params CodeParameterKind[] kinds)
{
Expand Down
3 changes: 2 additions & 1 deletion src/Kiota.Builder/Refiners/GoRefiner.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@ public override Task Refine(CodeNamespace generatedCode, CancellationToken cance
ReplaceIndexersByMethodsWithParameter(
generatedCode,
false,
"ById");
static x => $"With{x.ToFirstCharacterUpperCase()}",
static x => x.ToFirstCharacterLowerCase());
FlattenNestedHierarchy(generatedCode);
FlattenGoParamsFileNames(generatedCode);
FlattenGoFileNames(generatedCode);
Expand Down
5 changes: 4 additions & 1 deletion src/Kiota.Builder/Refiners/JavaRefiner.cs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,10 @@ public override Task Refine(CodeNamespace generatedCode, CancellationToken cance
});
RemoveClassNamePrefixFromNestedClasses(generatedCode);
InsertOverrideMethodForRequestExecutorsAndBuildersAndConstructors(generatedCode);
ReplaceIndexersByMethodsWithParameter(generatedCode, true);
ReplaceIndexersByMethodsWithParameter(generatedCode,
true,
static x => $"With{x.ToFirstCharacterUpperCase()}",
static x => x.ToFirstCharacterLowerCase());
cancellationToken.ThrowIfCancellationRequested();
RemoveCancellationParameter(generatedCode);
ConvertUnionTypesToWrapper(generatedCode,
Expand Down
5 changes: 4 additions & 1 deletion src/Kiota.Builder/Refiners/PhpRefiner.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,10 @@ public override Task Refine(CodeNamespace generatedCode, CancellationToken cance
cancellationToken.ThrowIfCancellationRequested();
CorrectParameterType(generatedCode);
MakeModelPropertiesNullable(generatedCode);
ReplaceIndexersByMethodsWithParameter(generatedCode, false, "ById");
ReplaceIndexersByMethodsWithParameter(generatedCode,
false,
static x => $"With{x.ToFirstCharacterUpperCase()}",
static x => x.ToFirstCharacterLowerCase());
cancellationToken.ThrowIfCancellationRequested();
MoveClassesWithNamespaceNamesUnderNamespace(generatedCode);
AddDiscriminatorMappingsUsingsToParentClasses(
Expand Down
5 changes: 4 additions & 1 deletion src/Kiota.Builder/Refiners/PythonRefiner.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,10 @@ public override Task Refine(CodeNamespace generatedCode, CancellationToken cance
DisableActionOf(generatedCode,
CodeParameterKind.RequestConfiguration);
cancellationToken.ThrowIfCancellationRequested();
ReplaceIndexersByMethodsWithParameter(generatedCode, false, "_by_id");
ReplaceIndexersByMethodsWithParameter(generatedCode,
false,
static x => $"_with_{x.ToSnakeCase()}",
static x => x.ToSnakeCase());
RemoveCancellationParameter(generatedCode);
CorrectCoreType(generatedCode, CorrectMethodType, CorrectPropertyType, CorrectImplements);
cancellationToken.ThrowIfCancellationRequested();
Expand Down
5 changes: 4 additions & 1 deletion src/Kiota.Builder/Refiners/RubyRefiner.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,10 @@ public override Task Refine(CodeNamespace generatedCode, CancellationToken cance
return Task.Run(() =>
{
cancellationToken.ThrowIfCancellationRequested();
ReplaceIndexersByMethodsWithParameter(generatedCode, false, "_by_id");
ReplaceIndexersByMethodsWithParameter(generatedCode,
false,
static x => $"_with_{x.ToSnakeCase()}",
static x => x.ToSnakeCase());
MoveRequestBuilderPropertiesToBaseType(generatedCode,
new CodeUsing
{
Expand Down
3 changes: 2 additions & 1 deletion src/Kiota.Builder/Refiners/SwiftRefiner.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ public override Task Refine(CodeNamespace generatedCode, CancellationToken cance
ReplaceIndexersByMethodsWithParameter(
generatedCode,
false,
"ById");
static x => $"With{x.ToFirstCharacterUpperCase()}",
static x => x.ToFirstCharacterUpperCase());
cancellationToken.ThrowIfCancellationRequested();
ReplaceReservedNames(
generatedCode,
Expand Down
5 changes: 4 additions & 1 deletion src/Kiota.Builder/Refiners/TypeScriptRefiner.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,10 @@ public override Task Refine(CodeNamespace generatedCode, CancellationToken cance
IsExternal = true
}
});
ReplaceIndexersByMethodsWithParameter(generatedCode, false, "ById");
ReplaceIndexersByMethodsWithParameter(generatedCode,
false,
static x => $"with{x.ToFirstCharacterUpperCase()}",
static x => x.ToFirstCharacterLowerCase());
RemoveCancellationParameter(generatedCode);
CorrectCoreType(generatedCode, CorrectMethodType, CorrectPropertyType, CorrectImplements);
CorrectCoreTypesForBackingStore(generatedCode, "BackingStoreFactorySingleton.instance.createBackingStore()");
Expand Down
2 changes: 1 addition & 1 deletion src/Kiota.Builder/Writers/Java/CodeMethodWriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -377,7 +377,7 @@ private void WriteIndexerBody(CodeMethod codeElement, CodeClass parentClass, Lan
{
if (parentClass.GetPropertyOfKind(CodePropertyKind.PathParameters) is CodeProperty pathParametersProperty && codeElement.OriginalIndexer != null)
conventions.AddParametersAssignment(writer, pathParametersProperty.Type, $"this.{pathParametersProperty.Name}",
parameters: (codeElement.OriginalIndexer.IndexType, codeElement.OriginalIndexer.SerializationName, "id"));
parameters: (codeElement.OriginalIndexer.IndexType, codeElement.OriginalIndexer.SerializationName, codeElement.OriginalIndexer.IndexParameterName.ToFirstCharacterLowerCase()));
conventions.AddRequestBuilderBody(parentClass, returnType, writer, conventions.TempDictionaryVarName);
}
private void WriteDeserializerBody(CodeMethod codeElement, CodeClass parentClass, LanguageWriter writer, bool inherits)
Expand Down
2 changes: 1 addition & 1 deletion src/Kiota.Builder/Writers/Php/CodeMethodWriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -583,7 +583,7 @@ private void WriteIndexerBody(CodeMethod codeElement, CodeClass parentClass, str
if (parentClass.GetPropertyOfKind(CodePropertyKind.PathParameters) is CodeProperty pathParametersProperty &&
codeElement.OriginalIndexer != null)
conventions.AddParametersAssignment(writer, pathParametersProperty.Type, $"$this->{pathParametersProperty.Name}",
(codeElement.OriginalIndexer.IndexType, codeElement.OriginalIndexer.SerializationName, "$id"));
(codeElement.OriginalIndexer.IndexType, codeElement.OriginalIndexer.SerializationName, $"${codeElement.OriginalIndexer.IndexParameterName.ToFirstCharacterLowerCase()}"));
conventions.AddRequestBuilderBody(parentClass, returnType, writer, conventions.TempDictionaryVarName, pathParameters);
}

Expand Down
2 changes: 1 addition & 1 deletion src/Kiota.Builder/Writers/Python/CodeMethodWriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ private void WriteIndexerBody(CodeMethod codeElement, CodeClass parentClass, str
if (parentClass.GetPropertyOfKind(CodePropertyKind.PathParameters) is CodeProperty pathParametersProperty &&
codeElement.OriginalIndexer != null)
conventions.AddParametersAssignment(writer, pathParametersProperty.Type, $"self.{pathParametersProperty.Name}",
(codeElement.OriginalIndexer.IndexType, codeElement.OriginalIndexer.SerializationName, "id"));
(codeElement.OriginalIndexer.IndexType, codeElement.OriginalIndexer.SerializationName, codeElement.OriginalIndexer.IndexParameterName.ToSnakeCase()));
conventions.AddRequestBuilderBody(parentClass, returnType, writer, conventions.TempDictionaryVarName);
}
private void WriteRequestBuilderWithParametersBody(CodeMethod codeElement, CodeClass parentClass, string returnType, LanguageWriter writer)
Expand Down
2 changes: 1 addition & 1 deletion src/Kiota.Builder/Writers/Ruby/CodeMethodWriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ private void WriteIndexerBody(CodeMethod codeElement, CodeClass parentClass, Lan
if (parentClass.GetPropertyOfKind(CodePropertyKind.PathParameters) is CodeProperty pathParametersProperty &&
codeElement.OriginalIndexer != null)
writer.WriteLines($"{conventions.TempDictionaryVarName} = @{pathParametersProperty.NamePrefix}{pathParametersProperty.Name.ToSnakeCase()}.clone",
$"{conventions.TempDictionaryVarName}[\"{codeElement.OriginalIndexer.SerializationName}\"] = id");
$"{conventions.TempDictionaryVarName}[\"{codeElement.OriginalIndexer.SerializationName}\"] = {codeElement.OriginalIndexer.IndexParameterName.ToSnakeCase()}");
conventions.AddRequestBuilderBody(parentClass, returnType, writer, conventions.TempDictionaryVarName, $"return {prefix}");
}
private void WriteDeserializerBody(CodeClass parentClass, LanguageWriter writer)
Expand Down
2 changes: 1 addition & 1 deletion src/Kiota.Builder/Writers/TypeScript/CodeMethodWriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ private void WriteIndexerBody(CodeMethod codeElement, CodeClass parentClass, str
codeElement.OriginalIndexer != null)
{
localConventions.AddParametersAssignment(writer, pathParametersProperty.Type, $"this.{pathParametersProperty.Name}",
parameters: (codeElement.OriginalIndexer.IndexType, codeElement.OriginalIndexer.SerializationName, "id"));
parameters: (codeElement.OriginalIndexer.IndexType, codeElement.OriginalIndexer.SerializationName, codeElement.OriginalIndexer.IndexParameterName.ToFirstCharacterLowerCase()));
}
conventions.AddRequestBuilderBody(parentClass, returnType, writer, conventions.TempDictionaryVarName);
}
Expand Down
6 changes: 4 additions & 2 deletions tests/Kiota.Builder.Tests/CodeDOM/CodeClassTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ public void SetsIndexer()
IsExternal = true,
IsNullable = true,
},
IndexParameterName = "idxSmth",
};
Assert.Single(codeClass.GetChildElements(true).OfType<CodeIndexer>());
Assert.Throws<ArgumentNullException>(() =>
Expand All @@ -88,12 +89,13 @@ public void SetsIndexer()
IsExternal = true,
IsNullable = true,
},
IndexParameterName = "idx2",
};
Assert.Empty(codeClass.GetChildElements(true).OfType<CodeIndexer>());
var methods = codeClass.GetChildElements(true).OfType<CodeMethod>().Where(x => x.IsOfKind(CodeMethodKind.IndexerBackwardCompatibility)).ToArray();
Assert.Equal(2, methods.Length);
Assert.Equal("ByIdx_smth", methods.FirstOrDefault(x => x.OriginalIndexer.Name.Equals("idx")).Name);
Assert.Equal("ByIdx2", methods.FirstOrDefault(x => x.OriginalIndexer.Name.Equals("idx2")).Name);
Assert.Equal("WithIdxSmth", methods.FirstOrDefault(static x => x.OriginalIndexer.Name.Equals("idx")).Name);
Assert.Equal("WithIdx2", methods.FirstOrDefault(static x => x.OriginalIndexer.Name.Equals("idx2")).Name);
}
[Fact]
public void ThrowsOnAddingEmptyCollections()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,8 @@ public void OrdersWithMethodWithinClass()
},
IndexType = new CodeType {
Name = "string"
}
},
IndexParameterName = "param"
}, new CodeProperty() {
Name = "prop",
Type = new CodeType {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,8 @@ public void OrdersWithMethodWithinClass()
},
IndexType = new CodeType {
Name = "string"
}
},
IndexParameterName = "param"
}, new CodeProperty() {
Name = "prop",
Type = new CodeType {
Expand Down Expand Up @@ -115,7 +116,8 @@ public void OrdersWithMethodsOutsideOfClass()
},
IndexType = new CodeType {
Name = "string"
}
},
IndexParameterName = "param"
}, new CodeProperty() {
Name = "prop",
Type = new CodeType {
Expand Down
3 changes: 2 additions & 1 deletion tests/Kiota.Builder.Tests/CodeDOM/CodeIndexerTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ public void IndexerInits()
Description = "some description",
},
IndexType = new CodeType(),
ReturnType = new CodeType()
ReturnType = new CodeType(),
IndexParameterName = "param",
};
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,8 @@ public async Task EscapesReservedKeywordsForReservedNamespaceNameSegments()
{
Name = "string",
},
ReturnType = indexerCodeType
ReturnType = indexerCodeType,
IndexParameterName = "id",
};
requestBuilder.Indexer = indexer;

Expand Down Expand Up @@ -296,7 +297,8 @@ public async Task ConvertsUnionTypesToWrapper()
IndexType = new CodeType
{
Name = "string"
}
},
IndexParameterName = "id",
};
model.Indexer = indexer;
method.AddParameter(parameter);
Expand Down
Loading