Skip to content
This repository was archived by the owner on Mar 31, 2025. It is now read-only.

fix(typescript): handle property accessors correctly #247

Merged
merged 1 commit into from
Oct 8, 2017

Conversation

petebacondarwin
Copy link
Contributor

Closes #246

if (this.getAccessor) {
this.type = this.getAccessor.type;
} else if (this.setAccessor) {
this.type = this.setAccessor.parameters[0].split(/:\s?/)[1];
Copy link
Member

@devversion devversion Oct 7, 2017

Choose a reason for hiding this comment

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

This doesn't seem to work properly. Right now if it's a combination of both getter and setter, then only the type of the getter will be used.

But actually it should try to find the type in the setter if it couldn't find a type in the getter. Thoughts?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

What does it mean to have a getter that has no type? Oh, I guess that if you code has no explicit return type... e.g.

class C {
  _foo: string;
  get foo() { return this._foo; }
  set foo(value: string) { this._foo = value; }
}

Is that the scenario? Generally in our public API docs we always give getters a return type.
In that case, then I guess we do need to look at the setter.

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've added a commit that fixes this... @devversion PTAL

// If this property has accessors then compute the type based on that instead
this.getAccessor = getAccessorDeclaration && new AccessorInfoDoc('get', this, getAccessorDeclaration, basePath, namespacesToInclude);
this.setAccessor = setAccessorDeclaration && new AccessorInfoDoc('set', this, setAccessorDeclaration, basePath, namespacesToInclude);
this.type = this.type || this.setAccessor && this.setAccessor.parameters[0].split(/:\s?/)[1] || '';
Copy link
Contributor Author

Choose a reason for hiding this comment

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

If we have passed in declaration or getAccessorDeclaration then we will have extracted the type from one of those, if possible.

Copy link
Member

@devversion devversion Oct 8, 2017

Choose a reason for hiding this comment

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

Yeah that's true. On Material we have a small workaround for this, but it still uses the declaration to retrieve the type. See here

Copy link
Member

@devversion devversion Oct 8, 2017

Choose a reason for hiding this comment

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

Might be worth to also check how the description of the getter/setter is being handled. I noticed that the description is only being read from one place.

get test() {}

/** Description on the setter */
set test(val: boolean) {}

Copy link
Contributor Author

Choose a reason for hiding this comment

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

So the getter and setter are docs in their own right, so their documentation should be processed for jsdoc tags, etc. You can then access them via the member.getAccessor and member.setAccessor for use in the property template.

This is similar to how overloads are being dealt with. With overloads we extract the content of the "actual" function for the member doc but then attach the content for each of the overload declarations to the overloads for that member.

In the case of a property with a getter and setter, we extract the content from the first declaration that is defined from [declaration, getter, setter]. It would seem to me more common to put the documentation (if there is only one) on the getter not the setter YMMV. But if you do put it only on the setter then you could easily get around this by doing something like:

Something like:

<h2 class="property-name">{$ member.name $}</h2>
<p class="description">{$ member.content or member.setAccessor and member.getAccessor.content $}</p>

Is this too unreasonable? Do you really put documentation on the setter only?

Copy link
Member

@devversion devversion Oct 8, 2017

Choose a reason for hiding this comment

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

Not really, on Material I remember seeing accessors that have the descriptions on a setter or on the getter and I want to make sure we don't need to enforce something here.

For the description, for me it makes sense to have a description property on the "MemberDoc". The description there should be retrieved in a similar way as the type, because it can be either on the getter or setter.

// In theory the accessor should only have one JSDoc at all, 
// it's still considered a property.
memberDoc.description // Should show the proper description of the getter/setter.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

OK, I'll transfer that from the relevant accessor too.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done PTAL

Copy link
Member

@devversion devversion Oct 8, 2017

Choose a reason for hiding this comment

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

Just tested it locally and the types seem to work fine now. For the descriptions, I'm not sure what's different to content is? When debugging most of our accessors in Material, they don't seem to have a content either.

Isn't there a way to set the description as well, based on the two cases I described above?

    // This works fine now. Seems like every thing has a type now!
    if (!propertyDoc.type) {
      console.log('No type for', propertyDoc.name);
    }

    // Likely every accessor doesn't have a description. 
    // "content" seems to be empty in most of the cases too.
    if (!propertyDoc.description) {
      console.log('No description for', propertyDoc.name, propertyDoc.content);
    }

This is the code-snippet we currently use in Material to receive the proper description for an accessor.

https://github.com/angular/material2/blob/4d97271786855598cfd18921641d5ffaafa079d8/tools/dgeni/common/dgeni-accessors-parse.ts#L51-L54

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Remember that this processor runs before the jsdic processing happens. The content field contains the raw content. After jsdoc runs there will be a description property too

Copy link
Member

@devversion devversion Oct 8, 2017

Choose a reason for hiding this comment

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

Hmm I'm not sure why the content is empty then. For me likely every accessor document has a content that is empty. Discussed on Slack.

Copy link
Member

@devversion devversion left a comment

Choose a reason for hiding this comment

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

LGTM. Thanks for the perfect work.

@petebacondarwin petebacondarwin merged commit a6e5041 into angular:master Oct 8, 2017
devversion added a commit to devversion/material2 that referenced this pull request Oct 9, 2017
Due to angular/dgeni-packages#246 the Material docs package used a workaround for accessor types.

The issue has been fixed with angular/dgeni-packages#247 and the workaround can be removed now.
devversion added a commit to devversion/material2 that referenced this pull request Oct 9, 2017
Due to angular/dgeni-packages#246 the Material docs package used a workaround for accessor types.

The issue has been fixed with angular/dgeni-packages#247 and the workaround can be removed now.
andrewseguin pushed a commit to angular/components that referenced this pull request Oct 12, 2017
Due to angular/dgeni-packages#246 the Material docs package used a workaround for accessor types.

The issue has been fixed with angular/dgeni-packages#247 and the workaround can be removed now.
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants