-
Notifications
You must be signed in to change notification settings - Fork 1.9k
JS: Add TypeTracker library and Firebase model #1035
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
Conversation
xiemaisi
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've only looked at the first commit so far, and I'm loving it! I'll give it a try on my socket.io model.
Only a few minor comments on the first commit otherwise, I'll come back to this later.
| * | ||
| * Identical to `TPathSummary` except without flow labels. | ||
| */ | ||
| private newtype TStepSummary = MkStepSummary(boolean hasReturn, boolean hasCall) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you change the types of the parameters to Boolean you can omit the body, I think.
| } | ||
| } | ||
|
|
||
| private newtype TTypeTracker = MkTypeTracker(boolean hasCall) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ditto.
| * source/sink relation, that is, it may determine that a node has a given type, | ||
| * but it won't determine where that type came from. | ||
| * | ||
| * It is recommended that all uses of this type is written on the following form, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/is written/are written/
Also, I'm not sure "on the following form" is idiomatic. Perhaps "in the following way" would be better.
xiemaisi
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A few minor comments; now that the type tracking library has landed perhaps it would be good to rebase this pr.
| /** | ||
| * Gets a node that is passed as the callback to a `Reference.transaction` call. | ||
| */ | ||
| DataFlow::SourceNode transactionCallback(DataFlow::TypeTracker t) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this be private?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(same for all other predicates with a TypeTracker parameter)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably a good idea
| (getMethodName() = "on" or getMethodName() = "once") | ||
| } | ||
|
|
||
| DataFlow::Node getCallbackNode() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
qldoc
| result = database(_) | ||
| } | ||
|
|
||
| /** Gets a dataflow node holding a `RefBuilder` object. */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| /** Gets a dataflow node holding a `RefBuilder` object. */ | |
| /** Gets a data flow node holding a `RefBuilder` object. */ |
| import javascript | ||
|
|
||
| module Firebase { | ||
| /** Gets a reference to the firebase API object. */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here and elsewhere: it would be nice to settle on a consistent capitalisation of [fF]irebase.
|
This is still marked as WIP. Are you planning on doing another performance evaluation? (If so, I have a few commits that might help.) |
|
I'll rebase and do another evaluation just to check |
|
Still 15% slow down on rhino. Probably related to the regression @xiemaisi has seen, so I'll wait and rebase once his tweaks have landed. |
|
After rebasing on #1163, performance looks good, and new results are the same as last time. |
This contains the
TypeTrackerlibrary I've talking about and a model of Firebase using it. I'd appreciate some feedback on theTypeTrackerlibrary in the first commit for now. I've included the firebase model in the PR so the use-case can be seen but I'm in no rush to land it.Evaluation on default.slugs shows a slight slow-down, but I'd like some feedback on the type-tracking library before spending more time on it.
Evaluation on firebase.slugs shows a couple of results, but not too exciting.
TypeTracker library
This adds the
TypeTrackerlibrary for tracking values of a certain type, without tracking where it came from. The differences withTrackedNodeis:Also, type tracker tracks values through instance fields more aggressively (note: currently conflicting with #989). This could of course easily be added to
TrackedNode, but as discussed, it's not clear that this step is safe for use in general. It should be safe for detecting API calls, though.Usage:
The idea is that each type is a QL predicate with a
TypeTrackerparameter.TypeTrackeris just a fancy facade for aboolean- it has the valuetrueif a call step was needed to track the type there, but this is hidden from the user. Use code looks like this:The
existsclause is boilerplate, which can be copy/pasted out of the qldoc forTypeTracker.Monomorphic API use assumption
The lack of summarization can in practice be sidestepped by not inheriting the
TypeTrackervalue from the dependent type. For example, take the function:If
fbis a firebase app in any calling context, it should be safe to assume that this method always returns a Firebase database. To do that, the predicate for recognizing.database()calls might look like this:Alternatively, if this assumption isn't considered safe, it could be written like this:
That is, by inheriting
tfrom the firebase instance, the database can't be tracked out of the function again.