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

Remove Class Name Prefix from Nested Classes #1980

Merged
merged 22 commits into from
Dec 1, 2022
Merged
Show file tree
Hide file tree
Changes from 20 commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
4292b85
remove parent name prefix from inner classes
ramsessanchez Nov 15, 2022
d6b645c
Config/query class refrences match new name
ramsessanchez Nov 17, 2022
a000107
- removes add inner classes that noops with default settings
baywet Nov 17, 2022
de0d1bf
- moves add inner class unit test to Go
baywet Nov 17, 2022
6ed9b49
Update src/Kiota.Builder/Refiners/JavaRefiner.cs
ramsessanchez Nov 17, 2022
159ff0b
Apply suggestions from code review
ramsessanchez Nov 17, 2022
89a5022
change the way we set httpMethod
ramsessanchez Nov 18, 2022
82f5146
refactor put statements
ramsessanchez Nov 18, 2022
ea8de1a
missing semicolon
ramsessanchez Nov 18, 2022
12eed73
remove more anonymous methods and comments
ramsessanchez Nov 19, 2022
a5e18ab
semicolon
ramsessanchez Nov 19, 2022
8a70a84
test update
ramsessanchez Nov 21, 2022
1f7dd26
remove equals sign
ramsessanchez Nov 21, 2022
59d91be
Merge pull request #1982 from microsoft/java/requestInfoInstantiation…
ramsessanchez Nov 21, 2022
f4582f2
consolidate loops
ramsessanchez Nov 21, 2022
4c38061
Update src/Kiota.Builder/Writers/Java/CodeMethodWriter.cs
ramsessanchez Nov 22, 2022
cad9de4
Update src/Kiota.Builder/Writers/Java/CodeMethodWriter.cs
ramsessanchez Nov 22, 2022
be57a57
Update CHANGELOG.md
ramsessanchez Nov 22, 2022
578563f
Merge branch 'main' into removeParentNamePrefix-Java
ramsessanchez Nov 22, 2022
122784e
Merge branch 'main' into removeParentNamePrefix-Java
baywet Nov 29, 2022
241e1e7
Merge branch 'main' into removeParentNamePrefix-Java
baywet Nov 30, 2022
2041c3c
- fixes unit test for java executor method
baywet Nov 30, 2022
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: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Fixed a bug in PHP generation where request bodies would not serialize single elements properly. [#1937](https://github.com/microsoft/kiota/pull/1937)
- Fixed a bug where request information would always be set from scalar. [#1965](https://github.com/microsoft/kiota/pull/1965)
- Fixed a bug where path parameters would be missing if no operation was present at the segment the parameter is defined. [#1940](https://github.com/microsoft/kiota/issues/1940)
- Fixed a bug where nested classes with long names caused compilation errors for java generated libraries. [#1949](https://github.com/microsoft/kiota/issues/1949)
- Removed use of anonymous classes in java generated libraries to reduce the number of java classes created at compilation time. [#1980](https://github.com/microsoft/kiota/pull/1980)
- Fixed a bug where generation would result in wrong indentation in some classes for Python [#1996]((https://github.com/microsoft/kiota/issues/1996).
- Fixed a bug where error class modules were hardcoded for Python [#1999]((https://github.com/microsoft/kiota/issues/1999)
- Fixed a bug where generation would sometimes result in wrong original names for query parameters in Python [#2000]((https://github.com/microsoft/kiota/issues/2000).
Expand Down
2 changes: 1 addition & 1 deletion src/Kiota.Builder/KiotaBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1412,7 +1412,7 @@ internal static void AddSerializationMembers(CodeClass model, bool includeAdditi
}
private CodeClass CreateOperationParameterClass(OpenApiUrlTreeNode node, OperationType operationType, OpenApiOperation operation, CodeClass parentClass)
{
var parameters = node.PathItems[Constants.DefaultOpenApiLabel].Parameters.Union(operation.Parameters).Where(p => p.In == ParameterLocation.Query);
var parameters = node.PathItems[Constants.DefaultOpenApiLabel].Parameters.Union(operation.Parameters).Where(static p => p.In == ParameterLocation.Query);
if(parameters.Any()) {
var parameterClass = parentClass.AddInnerClass(new CodeClass
{
Expand Down
1 change: 0 additions & 1 deletion src/Kiota.Builder/Refiners/CSharpRefiner.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ public override Task Refine(CodeNamespace generatedCode, CancellationToken cance
AddRawUrlConstructorOverload(generatedCode);
AddPropertiesAndMethodTypesImports(generatedCode, false, false, false);
AddAsyncSuffix(generatedCode);
AddInnerClasses(generatedCode, false, string.Empty);
cancellationToken.ThrowIfCancellationRequested();
AddParsableImplementsForModelClasses(generatedCode, "IParsable");
CapitalizeNamespacesFirstLetters(generatedCode);
Expand Down
2 changes: 1 addition & 1 deletion src/Kiota.Builder/Refiners/CommonLanguageRefiner.cs
Original file line number Diff line number Diff line change
Expand Up @@ -473,7 +473,7 @@ internal void DisableActionOf(CodeElement current, params CodeParameterKind[] ki
CrawlTree(current, x => DisableActionOf(x, kinds));
}
internal void AddInnerClasses(CodeElement current, bool prefixClassNameWithParentName, string queryParametersBaseClassName = "", bool addToParentNamespace = false) {
if(current is CodeClass currentClass) {
if(current is CodeClass currentClass && currentClass.IsOfKind(CodeClassKind.RequestBuilder)) {
var parentNamespace = currentClass.GetImmediateParentOfType<CodeNamespace>();
var innerClasses = currentClass
.Methods
Expand Down
3 changes: 1 addition & 2 deletions src/Kiota.Builder/Refiners/GoRefiner.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,7 @@ public override Task Refine(CodeNamespace generatedCode, CancellationToken cance
cancellationToken.ThrowIfCancellationRequested();
AddInnerClasses(
generatedCode,
true,
null);
true);
ReplaceIndexersByMethodsWithParameter(
generatedCode,
generatedCode,
Expand Down
61 changes: 58 additions & 3 deletions src/Kiota.Builder/Refiners/JavaRefiner.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ public override Task Refine(CodeNamespace generatedCode, CancellationToken cance
return Task.Run(() => {
cancellationToken.ThrowIfCancellationRequested();
LowerCaseNamespaceNames(generatedCode);
AddInnerClasses(generatedCode, false, string.Empty);
RemoveClassNamePrefixFromNestedClasses(generatedCode);
InsertOverrideMethodForRequestExecutorsAndBuildersAndConstructors(generatedCode);
ReplaceIndexersByMethodsWithParameter(generatedCode, generatedCode, true);
cancellationToken.ThrowIfCancellationRequested();
Expand Down Expand Up @@ -298,9 +298,64 @@ private void InsertOverrideMethodForRequestExecutorsAndBuildersAndConstructors(C

CrawlTree(currentElement, InsertOverrideMethodForRequestExecutorsAndBuildersAndConstructors);
}
private static void RemoveClassNamePrefixFromNestedClasses(CodeElement currentElement) {
if(currentElement is CodeClass currentClass && currentClass.IsOfKind(CodeClassKind.RequestBuilder)) {
var prefix = currentClass.Name;
var requestConfigClasses = currentClass
.Methods
.SelectMany(static x => x.Parameters)
.Where(static x => x.Type.ActionOf && x.IsOfKind(CodeParameterKind.RequestConfiguration))
.SelectMany(static x => x.Type.AllTypes)
.Select(static x => x.TypeDefinition)
.OfType<CodeClass>();
// ensure we do not miss out the types present in request configuration objects i.e. the query parameters
var innerClasses = requestConfigClasses
.SelectMany(static x => x.Properties)
.Where(static x => x.IsOfKind(CodePropertyKind.QueryParameters))
.SelectMany(static x => x.Type.AllTypes)
.Select(static x => x.TypeDefinition)
.OfType<CodeClass>().Union(requestConfigClasses)
.Where(x => x.Name.StartsWith(prefix, StringComparison.OrdinalIgnoreCase));

foreach(var innerClass in innerClasses) {
innerClass.Name = innerClass.Name[prefix.Length..];

if(innerClass.IsOfKind(CodeClassKind.RequestConfiguration))
RemovePrefixFromQueryProperties(innerClass, prefix);
}
RemovePrefixFromRequestConfigParameters(currentClass, prefix);
}
CrawlTree(currentElement, x => RemoveClassNamePrefixFromNestedClasses(x));
}
private static void RemovePrefixFromQueryProperties(CodeElement currentElement, String prefix) {
if(currentElement is CodeClass currentClass) {
var queryProperty = currentClass
.Properties
.Where(static x=> x.IsOfKind(CodePropertyKind.QueryParameters))
.Select(static x => x.Type)
.OfType<CodeTypeBase>()
.Where(x => x.Name.StartsWith(prefix, StringComparison.OrdinalIgnoreCase));

// Namespaces in Java by convention are all lower case, like:
// com.microsoft.kiota.serialization
foreach(var property in queryProperty) {
property.Name = property.Name[prefix.Length..];
}
}
}
private static void RemovePrefixFromRequestConfigParameters(CodeElement currentElement, String prefix) {
if(currentElement is CodeClass currentClass) {
var parameters = currentClass
.Methods
.SelectMany(static x => x.Parameters)
.Where(static x => x.Type.ActionOf && x.IsOfKind(CodeParameterKind.RequestConfiguration))
.Select(static x=> x.Type)
.OfType<CodeTypeBase>()
.Where(x => x.Name.StartsWith(prefix, StringComparison.OrdinalIgnoreCase));

foreach(var parameter in parameters) {
parameter.Name = parameter.Name[prefix.Length..];
}
}
}
private static void LowerCaseNamespaceNames(CodeElement currentElement) {
if (currentElement is CodeNamespace codeNamespace)
{
Expand Down
1 change: 0 additions & 1 deletion src/Kiota.Builder/Refiners/ShellRefiner.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ public override Task Refine(CodeNamespace generatedCode, CancellationToken cance
);
AddPropertiesAndMethodTypesImports(generatedCode, false, false, false);
cancellationToken.ThrowIfCancellationRequested();
AddInnerClasses(generatedCode, false);
AddParsableImplementsForModelClasses(generatedCode, "IParsable");
CapitalizeNamespacesFirstLetters(generatedCode);
cancellationToken.ThrowIfCancellationRequested();
Expand Down
30 changes: 12 additions & 18 deletions src/Kiota.Builder/Writers/Java/CodeMethodWriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -402,25 +402,24 @@ private static void WriteDeserializerBodyForIntersectionModel(CodeClass parentCl
}
writer.WriteLine($"return new {DeserializerReturnType}();");
}
private const string DeserializerVarName = "deserializerMap";
private void WriteDeserializerBodyForInheritedModel(CodeMethod method, CodeClass parentClass, LanguageWriter writer, bool inherits) {
var fieldToSerialize = parentClass.GetPropertiesOfKind(CodePropertyKind.Custom);
writer.WriteLines(
$"final {parentClass.Name.ToFirstCharacterUpperCase()} currentObject = this;",
$"return new {DeserializerReturnType}({(inherits ? "super." + method.Name.ToFirstCharacterLowerCase()+ "()" : fieldToSerialize.Count())}) {{{{");
$"final {DeserializerReturnType} {DeserializerVarName} = new {DeserializerReturnType}({(inherits ? "super." + method.Name.ToFirstCharacterLowerCase()+ "()" : fieldToSerialize.Count())});");
if(fieldToSerialize.Any()) {
writer.IncreaseIndent();
fieldToSerialize
.Where(static x => !x.ExistsInBaseType && x.Setter != null)
.OrderBy(static x => x.Name)
.Select(x =>
$"this.put(\"{x.SerializationName ?? x.Name.ToFirstCharacterLowerCase()}\", (n) -> {{ currentObject.{x.Setter.Name.ToFirstCharacterLowerCase()}(n.{GetDeserializationMethodName(x.Type, method)}); }});")
$"{DeserializerVarName}.put(\"{x.SerializationName ?? x.Name.ToFirstCharacterLowerCase()}\", (n) -> {{ this.{x.Setter.Name.ToFirstCharacterLowerCase()}(n.{GetDeserializationMethodName(x.Type, method)}); }});")
.ToList()
.ForEach(x => writer.WriteLine(x));
writer.DecreaseIndent();
}
writer.WriteLine("}};");
writer.WriteLine($"return {DeserializerVarName};");
}
private const string FactoryMethodName = "createFromDiscriminatorValue";
private const string ExecuterExceptionVar = "executionException";
private void WriteRequestExecutorBody(CodeMethod codeElement, RequestParams requestParams, LanguageWriter writer) {
if(codeElement.HttpMethod == null) throw new InvalidOperationException("http method cannot be null");
var returnType = conventions.GetTypeString(codeElement.ReturnType, codeElement, false);
Expand All @@ -431,20 +430,18 @@ private void WriteRequestExecutorBody(CodeMethod codeElement, RequestParams requ
var errorMappingVarName = "null";
if(codeElement.ErrorMappings.Any()) {
errorMappingVarName = "errorMapping";
writer.WriteLine($"final HashMap<String, ParsableFactory<? extends Parsable>> {errorMappingVarName} = new HashMap<String, ParsableFactory<? extends Parsable>>({codeElement.ErrorMappings.Count()}) {{{{");
writer.IncreaseIndent();
writer.WriteLine($"final HashMap<String, ParsableFactory<? extends Parsable>> {errorMappingVarName} = new HashMap<String, ParsableFactory<? extends Parsable>>();");
foreach(var errorMapping in codeElement.ErrorMappings) {
writer.WriteLine($"put(\"{errorMapping.Key.ToUpperInvariant()}\", {errorMapping.Value.Name.ToFirstCharacterUpperCase()}::{FactoryMethodName});");
writer.WriteLine($"{errorMappingVarName}.put(\"{errorMapping.Key.ToUpperInvariant()}\", {errorMapping.Value.Name.ToFirstCharacterUpperCase()}::{FactoryMethodName});");
}
writer.CloseBlock("}};");
}
var factoryParameter = codeElement.ReturnType is CodeType returnCodeType && returnCodeType.TypeDefinition is CodeClass ? $"{returnType}::{FactoryMethodName}" : $"{returnType}.class";
writer.WriteLine($"return this.requestAdapter.{sendMethodName}({RequestInfoVarName}, {factoryParameter}, {errorMappingVarName});");
writer.DecreaseIndent();
writer.StartBlock("} catch (URISyntaxException ex) {");
writer.StartBlock($"return new java.util.concurrent.CompletableFuture<{returnType}>() {{{{");
writer.WriteLine("this.completeExceptionally(ex);");
writer.CloseBlock("}};");
writer.WriteLine($"java.util.concurrent.CompletableFuture<{returnType}> {ExecuterExceptionVar} = new java.util.concurrent.CompletableFuture<{returnType}>();");
writer.WriteLine($"{ExecuterExceptionVar}.completeExceptionally(ex);");
writer.WriteLine($"return {ExecuterExceptionVar};");
writer.CloseBlock();
}
private string GetSendRequestMethodName(bool isCollection, string returnType, bool isEnum)
Expand Down Expand Up @@ -485,11 +482,8 @@ private void WriteRequestGeneratorBody(CodeMethod codeElement, RequestParams req
var urlTemplateParamsProperty = currentClass.GetPropertyOfKind(CodePropertyKind.PathParameters);
var urlTemplateProperty = currentClass.GetPropertyOfKind(CodePropertyKind.UrlTemplate);
var requestAdapterProperty = currentClass.GetPropertyOfKind(CodePropertyKind.RequestAdapter);
writer.WriteLine($"final RequestInformation {RequestInfoVarName} = new RequestInformation() {{{{");
writer.IncreaseIndent();
writer.WriteLine($"httpMethod = HttpMethod.{codeElement.HttpMethod?.ToString().ToUpperInvariant()};");
writer.DecreaseIndent();
writer.WriteLine("}};");
writer.WriteLine($"final RequestInformation {RequestInfoVarName} = new RequestInformation();");
writer.WriteLine($"{RequestInfoVarName}.httpMethod = HttpMethod.{codeElement.HttpMethod?.ToString().ToUpperInvariant()};");
writer.WriteLines($"{RequestInfoVarName}.urlTemplate = {GetPropertyCall(urlTemplateProperty, "\"\"")};",
$"{RequestInfoVarName}.pathParameters = {GetPropertyCall(urlTemplateParamsProperty, "null")};");
if(codeElement.AcceptedResponseTypes.Any())
Expand Down
28 changes: 28 additions & 0 deletions tests/Kiota.Builder.Tests/Refiners/GoLanguageRefinerTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,34 @@ public class GoLanguageRefinerTests {
private readonly CodeNamespace root = CodeNamespace.InitRootNamespace();
#region CommonLangRefinerTests
[Fact]
public async Task AddsInnerClasses() {
var model = root.AddClass(new CodeClass {
Name = "model",
Kind = CodeClassKind.RequestBuilder
}).First();
var method = model.AddMethod(new CodeMethod {
Name = "method1",
ReturnType = new CodeType {
Name = "string",
IsExternal = true
}
}).First();
var parameter = new CodeParameter {
Name = "param1",
Kind = CodeParameterKind.RequestConfiguration,
Type = new CodeType {
Name = "SomeCustomType",
ActionOf = true,
TypeDefinition = new CodeClass {
Name = "SomeCustomType"
}
}
};
method.AddParameter(parameter);
await ILanguageRefiner.Refine(new GenerationConfiguration { Language = GenerationLanguage.Go }, root);
Assert.Equal(2, model.GetChildElements(true).Count());
}
[Fact]
public async Task TrimsCircularDiscriminatorReferences() {
var modelsNS = root.AddNamespace("models");
var baseModel = modelsNS.AddClass(new CodeClass {
Expand Down
28 changes: 0 additions & 28 deletions tests/Kiota.Builder.Tests/Refiners/JavaLanguageRefinerTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -253,34 +253,6 @@ public async Task ReplacesIndexersByMethodsWithParameter() {
Assert.Single(collectionRequestBuilder.Properties);
}
[Fact]
public async Task AddsInnerClasses() {
var model = root.AddClass(new CodeClass {
Name = "model",
Kind = CodeClassKind.Model
}).First();
var method = model.AddMethod(new CodeMethod {
Name = "method1",
ReturnType = new CodeType {
Name = "string",
IsExternal = true
}
}).First();
var parameter = new CodeParameter {
Name = "param1",
Kind = CodeParameterKind.RequestConfiguration,
Type = new CodeType {
Name = "SomeCustomType",
ActionOf = true,
TypeDefinition = new CodeClass {
Name = "SomeCustomType"
}
}
};
method.AddParameter(parameter);
await ILanguageRefiner.Refine(new GenerationConfiguration { Language = GenerationLanguage.Java }, root);
Assert.Equal(2, model.GetChildElements(true).Count());
}
[Fact]
public async Task DoesNotKeepCancellationParametersInRequestExecutors()
{
var model = root.AddClass(new CodeClass
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ public class CodeMethodWriterTests : IDisposable {
private readonly CodeMethod method;
private readonly CodeClass parentClass;
private readonly CodeNamespace root;
private const string ExecuterExceptionVar = "executionException";
private const string MethodName = "methodName";
private const string ReturnTypeName = "Somecustomtype";
private const string MethodDescription = "some description";
Expand Down Expand Up @@ -499,9 +500,8 @@ public void WritesRequestExecutorBody() {
Assert.Contains("put(\"5XX\", Error5XX::createFromDiscriminatorValue);", result);
Assert.Contains("put(\"403\", Error403::createFromDiscriminatorValue);", result);
Assert.Contains("sendAsync", result);
Assert.Contains("return new java.util.concurrent.CompletableFuture<Somecustomtype>() {{", result);
Assert.Contains("this.completeExceptionally(ex);", result);
Assert.Contains("}};", result);
Assert.Contains($"java.util.concurrent.CompletableFuture<Somecustomtype> {ExecuterExceptionVar} = new java.util.concurrent.CompletableFuture<Somecustomtype>();", result);
Assert.Contains($"{ExecuterExceptionVar}.completeExceptionally(ex);", result);
AssertExtensions.CurlyBracesAreClosed(result);
}
[Fact]
Expand Down