Skip to content

Conversation

tamasvajk
Copy link
Contributor

No description provided.

@tamasvajk tamasvajk marked this pull request as ready for review August 31, 2022 12:21
@tamasvajk tamasvajk requested a review from a team as a code owner August 31, 2022 12:21
@tamasvajk tamasvajk requested a review from a team August 31, 2022 12:21
atorralba
atorralba previously approved these changes Aug 31, 2022
Copy link
Contributor

@atorralba atorralba left a comment

Choose a reason for hiding this comment

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

A little surprising at first glance that the internal method has the public modifier but isPublic doesn't hold for it. But I guess it makes sense if we want isPublic to exclude Kotlin internal methods. LGTM.

* Holds if this element has a `public` modifier or is implicitly public.
* Kotlin `internal` members, which are `public` in JVM Bytecode, are not considered `public`.
*/
predicate isPublic() { this.hasModifier("public") and not this.isInternal() }
Copy link
Contributor

Choose a reason for hiding this comment

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

Hmm, hasModifier is also public, so we should probably do something like (untested)

private predicate hasModifierRefined(Modifiable e, Modifier m) {
    hasModifier(e, m)
    // Kotlin "internal" elements may also get "public" modifiers, so we want to filter those out
    and not exists(Modifier m2 | hasModifier(e, m2) and modifiers(m, "public") and modifiers(m2, "internal"))
}

instead, and use that everywhere instead of hasModifier.

It's also a bit odd that class Modifier doesn't have a predicate to get the name of the modifier. That would probably allow this to be tidied up a bit, and remove some calls to dbscheme relations.

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 wanted to introduce as little change as possible. hasModifier has a comment on top of it:

  /**
   * Holds if this element has modifier `m`.
   *
   * For most purposes, the more specialized predicates `isAbstract`, `isPublic`, etc.
   * should be used.
   *
   * Both this method and those specialized predicates take implicit modifiers into account.
   * For instance, non-default instance methods in interfaces are implicitly
   * abstract, so `isAbstract()` will hold for them even if `hasModifier("abstract")`
   * does not.
   */
  predicate hasModifier(string m) { modifiers(this.getAModifier(), m) }

So in my view it's okay to return the public modifier even if isPublic doesn't hold. That feels similar to the abstract case.

I think the best option would be making hasModifier private, but it's used heavily for concatenating all modifiers. (For all other purposes we anyways should go with the specialized predicates, which in some case are overridden (for example Method::isPublic).)

What do you think?

Copy link
Contributor

Choose a reason for hiding this comment

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

My proposal is that codeql treats internal predicates as simply internal. The only reason that we sometimes get a public modifier in the database is that the Java extractor isn't able to tell that they are internal, and it isn't easy to patch that up before the database is created, and so I suggest that we patch it at the lowest level of QL, i.e. wrapping the relevant table and only using the wrapper elsewhere.

As far as queries are concerned, there should therefore be no public modifier, whether you ask isPublic or hasModifier. This isn't a case of it being implicit, it simply shouldn't exist.

An alternative approach would be to always extract internal entities as also being public in the Kotlin extractor, so entities would always have both modifiers consistently. This would presumably be consistent with Java's world view, but I think that it would be more confusing on balance.

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 see what you mean. How do you like e66d2dd?

hasModifier(this, mod2) and modifiers(mod, "public") and modifiers(mod2, "internal")
)
)
}
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't think that we need to change this. this.getAModifier() calls Modifier.getElement() which has already done the filtering in your change above.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks for spotting this. I removed it.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks for spotting this. I removed it.

@tamasvajk tamasvajk added the no-change-note-required This PR does not need a change note label Sep 2, 2022
@igfoo igfoo merged commit 07b3b15 into github:main Sep 2, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Java Kotlin no-change-note-required This PR does not need a change note
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants