JavaScript: ignore self-assignments with a JSDoc comment#166
Conversation
ghost
left a comment
There was a problem hiding this comment.
I agree about the fishyness,
I think we should tie the heuristic as close as possible to the specific TypeScript use case, see comments.
| not isDOMProperty(e.(PropAccess).getPropertyName()) | ||
| select e.getParent(), "This expression assigns " + dsc + " to itself." No newline at end of file | ||
| not isDOMProperty(e.(PropAccess).getPropertyName()) and | ||
| // exclude self-assignments with a JSDoc comment |
There was a problem hiding this comment.
Perhaps:
// exclude self-assignments that have been inserted to satisfy the TypeScript type checker
| select e.getParent(), "This expression assigns " + dsc + " to itself." No newline at end of file | ||
| not isDOMProperty(e.(PropAccess).getPropertyName()) and | ||
| // exclude self-assignments with a JSDoc comment | ||
| not exists(e.getAssignment().getParent().(ExprStmt).getDocumentation().getATag()) |
There was a problem hiding this comment.
Can we make this even more specific?
not e.getAssignment().getParent().(ExprStmt).getDocumentation().getATag().getName() = "type"
ghost
left a comment
There was a problem hiding this comment.
Great.
I think this deserves a change note, it may be a more widespread problem than we are aware of.
|
Modern versions of TypeScript also support Which is probably clearer. |
|
That's a very good point @Zarel, thank you much for bringing it up. That case falls under the purview of the "expression has no effect" query, which already has the same exception for JSDoc comments. Maybe it's worth reconsidering the exception here, though, since there actually is a more reasonable alternative (@esben-semmle). @Zarel was there a reason you didn't use the short form in Pokemon-Showdown? |
|
@asger-semmle We started using TypeScript's I'll probably switch to using the shorter form at some point. |
I agree. Let us keep the whitelist simple, and drop this PR. |
|
Someone mentioned one reason to do it this way. If you use then the property will be initialized to |
|
True, but |
|
The use-case is something like: class Foo {
constructor(options = {}) {
Object.assign(this, options);
/** @type {string | undefined} */
this.x = this.x;
}
}
let a = new Foo();
let b = new Foo({x: "bar"}); |
|
Right, fair enough. If people feel that this is a common enough idiom to whitelist it, we can do so. |
|
I honestly wouldn't know. I would guess it's really uncommon. I'm using it to strongly type the data I get from data files, but there's probably a better way to do it. |
|
OK, that sounds like something people might reasonably do. @asger-semmle, @esben-semmle, do you think it is safe to whitelist |
|
I am not sure. |
|
OK. How about resurrecting this PR with its idea to only whitelist self-assignments that have a |
|
The |
8a5f7f6 to
5bd96f7
Compare
|
LGTM, but could you also update the qhelp to mention this additional whitelisting condition, perhaps in the "how to fix" section? It gives people a semantic way of addressing the alert without having to resort to suppression comments. |
|
Will rebase after #388 lands, as they both touch the change notes. |
|
#388 has landed; time for rebase? |
73de56e to
e670919
Compare
|
Rebased |
xiemaisi
left a comment
There was a problem hiding this comment.
LGTM, modulo one niggle which I won't insist on.
| </p> | ||
|
|
||
| <p> | ||
| If the self-assignment is intentional, and is needed for documentation or optimization purposes, |
Minimal implementation of shared type-tracking library
…tution-prototypes Extract generic method prototypes
resolving ruby df error
Fixes a technically correct but seemingly unfixable alert in type-checked JS code, like this:
TypeScript can check JS code, and recognizes JSDoc-annotated assignments in the constructor as fields. If these fields are initialized elsewhere, however, a self-assignment may be necessary to have a place to "declare" the field.
I still think it's fishy, but I think it's fairly safe to turn it off in this case. The real problems are unlikely to have a JSDoc comment in front of them.