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

Fix for type collisions for types referenced from OData actions #1215

Merged
merged 1 commit into from
Feb 16, 2022

Conversation

andrueastman
Copy link
Member

@andrueastman andrueastman commented Feb 16, 2022

This PR closes #1198

Changes include

  1. Evaluate the targetNamespace in the event an array has a reference schema (similar to how objects are handled).
    This fixes the duplication of types models in other namespaces and now will be placed in the namespace as expected from the schema. (E.g we would see Message model in the default models namespace and in a function/action namespace and this would type collisions if someone imported both)

  2. Eliminate the explicit setting of the checkInAllNameSpaces to true when calling AddModelDeclarationIfDoesntExit as this produces flaky generation results.
    This has now been limited to scenarios when the schema in use does not have a reference (essentially when the schema is inline?). This is because the namespace resolution seems solid and the type/model should be found in a consistent manner in the event there is a reference. Explicitly setting to true results in property types changing on different runs and models missing/or showing up in different runs. because of sometimes resolving Microsoft.Graph.Group instead of Microsoft.Graph.TermStore.Group(and vice versa based on random conditions lol).

  3. Refactor typo in method name AddModelDeclarationIfDoesntExist

Notes

  • Testing with error mapping yaml here yields no diff as it seems the changes do not cover the cases in the document.

Todo add tests
@sonarqubecloud
Copy link

Kudos, SonarCloud Quality Gate passed!    Quality Gate passed

Bug A 0 Bugs
Vulnerability A 0 Vulnerabilities
Security Hotspot A 0 Security Hotspots
Code Smell A 0 Code Smells

31.2% 31.2% Coverage
0.0% 0.0% Duplication

type = CreateModelDeclarationAndType(currentNode, schema?.Items, operation, codeNamespace);
if (type == null)
{
var targetNamespace = schema?.Items == null ? codeNamespace : GetShortestNamespace(codeNamespace, schema.Items);
Copy link
Member Author

@andrueastman andrueastman Feb 16, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We evaluate this case similar to objects so that if a collection item has a schema, we will look at the same place(namespace) and avoid duplicating models in different namespaces.

@@ -820,7 +823,7 @@ private CodeTypeBase CreateModelDeclarations(OpenApiUrlTreeNode currentNode, Ope
var parentSchema = referencedAllOfs.FirstOrDefault();
if(parentSchema != null) {
var parentClassNamespace = GetShortestNamespace(currentNamespace, parentSchema);
inheritsFrom = AddModelDeclarationIfDoesntExit(currentNode, parentSchema, parentSchema.GetSchemaTitle(), parentClassNamespace, null, true) as CodeClass;
inheritsFrom = AddModelDeclarationIfDoesntExist(currentNode, parentSchema, parentSchema.GetSchemaTitle(), parentClassNamespace, null, !parentSchema.IsReferencedSchema()) as CodeClass;
Copy link
Member Author

@andrueastman andrueastman Feb 16, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Only set to true if we don't have schema. The parentClassNamespace should ideally contain the type if the schema is referenced as the namespace is consistently evaluated from the schema (if it exists).
With this change, we know which namespace the type should be if we have a reference schema so no need to search all namespaces.

@@ -851,7 +854,7 @@ private CodeTypeBase CreateModelDeclarations(OpenApiUrlTreeNode currentNode, Ope
var shortestNamespaceName = GetModelsNamespaceNameFromReferenceId(propertyDefinitionSchema.Reference?.Id);
var targetNamespace = string.IsNullOrEmpty(shortestNamespaceName) ? ns :
(rootNamespace.FindNamespaceByName(shortestNamespaceName) ?? rootNamespace.AddNamespace(shortestNamespaceName));
definition = AddModelDeclarationIfDoesntExit(currentNode, propertyDefinitionSchema, className, targetNamespace, null, true);
definition = AddModelDeclarationIfDoesntExist(currentNode, propertyDefinitionSchema, className, targetNamespace, null, !propertyDefinitionSchema.IsReferencedSchema());
Copy link
Member Author

@andrueastman andrueastman Feb 16, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Only set to true if we don't have schema. The targetNamespace should ideally contain the type if the schema is referenced as the namespace is consistently evaluated from the schema (if it exists).
Leaving to true results to flaky generation of Types as sometimes it might resolve something like Microsoft.Graph.Group vs Microsoft.Graph.TermStore.Group depending on which namespace is dug up first(if set to true).
With this change, we know which namespace the type should be if we have a reference schema so no need to search all namespaces.

@andrueastman andrueastman marked this pull request as ready for review February 16, 2022 08:41
@andrueastman andrueastman self-assigned this Feb 16, 2022
@andrueastman andrueastman added the generator Issues or improvements relater to generation capabilities. label Feb 16, 2022
@andrueastman andrueastman added this to the Community Preview milestone Feb 16, 2022
@baywet
Copy link
Member

baywet commented Feb 16, 2022

Great work rootcausing this issue! Thanks for the detailed explanation.

This is because the namespace resolution seems solid

You have more trust in the code I wrote than I do 🤣

Jokes aside the "namespace and naming calculation code" has been built iteratively, by trial and error following increasing complexity of the different descriptions I was testing with, and this might show in the current structure (compared to a fully designed ahead approach).

I'm going to disable the auto merge and merge as admin because the CLA check doesn't seem to be working at the moment.

@baywet baywet disabled auto-merge February 16, 2022 13:33
@baywet baywet merged commit 1457eed into main Feb 16, 2022
@baywet baywet deleted the andrueastman/TypeCollision branch February 16, 2022 13:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
generator Issues or improvements relater to generation capabilities.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Regression] Type collisions for types referenced from OData actions
2 participants