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

feat: two-way type references #684

Merged
merged 5 commits into from
May 14, 2021
Merged

feat: two-way type references #684

merged 5 commits into from
May 14, 2021

Conversation

josephaxisa
Copy link
Contributor

@josephaxisa josephaxisa commented May 14, 2021

Modified @looker/sdk-codegen such that given a type such as DashboardElement, it records its parents DashboardElement[] and Dashboard.

Also wired this up in @looker/api-explorer:

image

Given a child type such as DashboardElement, record its parents DashboardElement[] and Dashboard in parentTypes
@github-actions
Copy link
Contributor

Codegen Tests

  1 files    6 suites   21s ⏱️
58 tests 46 ✔️ 12 💤 0 ❌

Results for commit c5daa46.

@github-actions
Copy link
Contributor

Codegen Tests

  1 files    6 suites   20s ⏱️
58 tests 46 ✔️ 12 💤 0 ❌

Results for commit 5d77aed.

@github-actions
Copy link
Contributor

APIX Tests

    1 files  ±0    72 suites  ±0   2m 40s ⏱️ +21s
268 tests ±0  256 ✔️ ±0  12 💤 ±0  0 ❌ ±0 
287 runs  ±0  275 ✔️ ±0  12 💤 ±0  0 ❌ ±0 

Results for commit 5d77aed. ± Comparison against base commit 952ed30.

jkaster
jkaster previously approved these changes May 14, 2021
Comment on lines +1547 to +1548
propType.elementType?.parentTypes.add(propType.name)
propType.elementType?.parentTypes.add(this.name)
Copy link
Contributor

Choose a reason for hiding this comment

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

why do we want both DashboardElement[] and Dashboard? It seems to me that IType.{types|parentTypes} is meant to reference other IType objects which I believe (though I could be wrong) are anything that would be in a "$ref" value from the spec. I don't think DashboardElement[] satisfies that requirement. In fact, in APIX you're using typeRefs(...) which appears to filter out anything that isn't a "$ref" (and thus DashboardElement[] is removed)?

I don't know which of these two lines puts in DashboardElement[] but I think it should be removed.

Caveat: not super up to speed on the actual details/usage of the SdkModel so I could be totally wrong here.

Copy link
Contributor

Choose a reason for hiding this comment

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

parentTypes is primarily for APIX explorer documentation purposes to link a type to the types that use or "contain" it. For exploration, we don't bother to show an array collection type, just the underlying complex type.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is a good point and would only require some additional validation in sdkModels.ts. I'm unsure whether we should do that or not though, I'll have to defer to @jkaster

Copy link
Contributor

Choose a reason for hiding this comment

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

I didn't answer completely. I think DashboardElement should have parent types that are Dashboard and DashboardElement[] because both "contain" DashboardElement.

Copy link
Contributor

@joeldodge79 joeldodge79 May 14, 2021

Choose a reason for hiding this comment

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

I guess my more basic question is what what is a "type" in the context here.

  • this is an instance of Type that implements IType
  • IType.{types|parentTypes}is currently just Set<string> but it seems to me like they're more meant to be Set<IType> (which I know doesn't actually work under the hood due to object equality checks on a set).

If that's correct (i.e. type/parentTypes is mean to represent a collection of IType) then what is an IType? A Dashboard is an IType but DashboardElement[] is not. The former exists as a value to a $ref key in the schema where as the latter never does, rather DashboardElement is referenced in the items key of another IType's property that has a type value of "array"?

On the other hand, maybe types/parentTypes is not a loose reference to IType but rather meant to be the union of IType and IType[]? But, as you say it's primarily for APIX which promptly discards the IType[] type by calling typeRefs(...)?

Or maybe I'm just up too early and my brain isn't on :-) happy to hash out in person later

Copy link
Contributor

Choose a reason for hiding this comment

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

Ok, I thought that might be the question. They must be Set<string> rather than IType to prevent circular references that break JSON serialization. You'll find we use the name of the type rather than the actual Type in several collections for this reason.

Copy link
Contributor

@joeldodge79 joeldodge79 May 14, 2021

Choose a reason for hiding this comment

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

I'm not doing a good job expressing my question/concern: it's not about the implementation of the typescript type or javascript runtime implementation of IType.{types|parentTypes}: my question/concern is what kinds of "things" do IType.{types|parentTypes} refer to. I believe they refer to IType things (even though there's no typescript type constraint because we're just using Set<string>), not container-datastructures of IType things and hence DashboardElement[] does not belong.

I'm thinking of an ERD - a parentType would be another box but would not also include the many-to-one line-arrow pointing to that box

Copy link
Contributor

Choose a reason for hiding this comment

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

I guess I see DashboardElement[] and Dashboard as two fundamentally different kinds of things:

Dashboard - a real thing (a User is a real thing etc)
DashboardElement[] - a programming construct to describe a collection of real things

Housing those under the same property feels like saying "one of my parents is named Tom, and I have another parent whose name is 'Tom's kids'"

Copy link
Contributor

Choose a reason for hiding this comment

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

I agree it gets muddy. What do you suggest instead? We definitely need to link child types of a collection to the user of said collection. For visual representation in APIX, this works. Can we create a ticket to work out this design and address it in another PR, because I've already thought about this and haven't come up with anything clearly better yet, and for the purpose of APIX type ref navigation this works.

Copy link
Contributor

Choose a reason for hiding this comment

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

We definitely need to link child types of a collection to the user of said collection

I don't totally understand what this means w/out seeing concrete code but I'll take your word for it: carry on :-)

@@ -732,6 +732,18 @@ describe('sdkModels', () => {

describe('method and type xrefs', () => {
describe('custom types', () => {
it('determines parent type of array types', () => {
Copy link
Contributor

Choose a reason for hiding this comment

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

maybe add a test for "parent of hash types" since your fix in sdkModels is

propType.instanceOf('ArrayType') || propType.instanceOf('HashType')

(or conversely remove the || HashType condition)

Copy link
Contributor

Choose a reason for hiding this comment

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

We have no complex hash types in the model right now, so we need to create a sample spec for that.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I didn't add a test for this because unfortunately we do not have any typed HashType in the spec. All parameters of type IDictionary expect a scalar property value. I added the check because I expect it to work when we do, but perhaps I should remove it so that when we do need it, we'll remember to add a test

Copy link
Contributor

Choose a reason for hiding this comment

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

we've modified test/openApiRef.json in the past to add spec schema that we don't already have in Looker: 1b64e1b#diff-90f6053ccc4c15adb9cbbba6833dbfb5a6206c6fb3793fe206f10f71230b73faR29331

So yeah, I'd say either remove the check (perhaps adding a TODO) or add the test

Copy link
Contributor Author

Choose a reason for hiding this comment

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

added the test

updated test/openApiRef.json with a fake schema for this
Copy link
Contributor

@jkaster jkaster left a comment

Choose a reason for hiding this comment

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

Looks good.

@github-actions
Copy link
Contributor

APIX Tests

    1 files    72 suites   2m 11s ⏱️
268 tests 256 ✔️ 12 💤 0 ❌
287 runs  275 ✔️ 12 💤 0 ❌

Results for commit 6119e97.

@github-actions
Copy link
Contributor

Codegen Tests

  1 files    6 suites   26s ⏱️
58 tests 46 ✔️ 12 💤 0 ❌

Results for commit 8f35b37.

@github-actions
Copy link
Contributor

Codegen Tests

  1 files  ±0    6 suites  ±0   24s ⏱️ ±0s
58 tests ±0  46 ✔️ ±0  12 💤 ±0  0 ❌ ±0 

Results for commit 6119e97. ± Comparison against base commit 8c75bba.

Comment on lines +747 to +753
it('determines parent type of complex hash types', () => {
const hashProp = apiTestModel.types.ComplexHashProp
expect(hashProp.parentTypes).toEqual(
new Set(['Hash[ComplexHashProp]', 'ComplexHash'])
)
})

Copy link
Contributor

Choose a reason for hiding this comment

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

thanks for adding the test. I'll shut up now but it still smells like something is wrong in our modeling when 'Hash[ComplexHashProp]', 'ComplexHash' are elements of the same property

@josephaxisa josephaxisa merged commit fbc0565 into main May 14, 2021
@josephaxisa josephaxisa deleted the jax/two-way-type-refs branch May 14, 2021 17:22
@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants