44overlay [ local?]
55module ;
66
7+ private import unified as U
78private import AstPlugin
89private import codeql.files.FileSystem
910private import codeql.unified.internal.NameBinding as NameBinding
@@ -37,7 +38,9 @@ module Unified {
3738 )
3839 }
3940
40- /** Gets the nearest enclosing class declaration, if any. */
41+ /**
42+ * Gets the nearest syntactically enclosing class declaration, if any.
43+ */
4144 ClassLikeDeclaration getEnclosingClass ( ) {
4245 exists ( AstNode parent | parent = this .getParent ( ) |
4346 result = parent
@@ -205,17 +208,33 @@ module Unified {
205208 /**
206209 * Gets the name of this member qualified by the short names of each immediately-enclosing class.
207210 */
208- string getQualifiedName ( ) {
209- exists ( ClassLikeDeclaration cls |
210- this = cls .getAMember ( ) and
211- result = cls .getQualifiedName ( ) + "." + this .getNameOrFallback ( )
212- )
211+ string getQualifiedName ( ) { result = QualifiedName< getParentClass / 1 > :: getQualifiedName ( this ) }
212+ }
213+
214+ private signature ClassLikeDeclaration getDeclaringClassSig ( Member m ) ;
215+
216+ private module QualifiedName< getDeclaringClassSig / 1 getDeclaringClass> {
217+ string getQualifiedName ( Member m ) {
218+ result = getQualifiedName ( getDeclaringClass ( m ) ) + "." + m .getNameOrFallback ( )
213219 or
214- not this = any ( ClassLikeDeclaration cls ) . getAMember ( ) and
215- result = this .getNameOrFallback ( )
220+ not exists ( getDeclaringClass ( m ) ) and
221+ result = m .getNameOrFallback ( )
216222 }
217223 }
218224
225+ private ClassLikeDeclaration getParentClass ( Member m ) {
226+ result .getAMemberIncludingExtensions ( ) = m
227+ }
228+
229+ private ClassLikeDeclaration getEnclosingClass ( Member m ) { result .getAMember ( ) = m }
230+
231+ /**
232+ * Similar to `Member.getQualifiedName`, but avoids a dependency on name binding, making
233+ * it suitable for use in `toString` predicates.
234+ */
235+ private predicate getQualifiedNameForToString =
236+ QualifiedName< getEnclosingClass / 1 > :: getQualifiedName / 1 ;
237+
219238 class ClassLikeDeclaration extends G:: ClassLikeDeclaration {
220239 /** Gets the name of this declaration. */
221240 string getName ( ) { result = this .getNameNode ( ) .getValue ( ) }
@@ -226,8 +245,33 @@ module Unified {
226245 NameBinding:: getStaticBindingTargetFromRef ( this .getABaseType ( ) .getType ( ) )
227246 }
228247
248+ /**
249+ * Gets the target of this extension class, or this class itself if it is not an extension.
250+ */
251+ ClassLikeDeclaration resolve ( ) {
252+ not exists ( this .getExtensionTarget ( ) ) and
253+ result = this
254+ or
255+ exists ( NameBinding:: NamespaceNode ns |
256+ ns .isStaticMemberNamespace ( result ) and
257+ ns .getAnExtension ( ) .isStaticMemberNamespace ( this )
258+ )
259+ }
260+
261+ /**
262+ * Gets a member of this class, including members from extensions.
263+ */
264+ Member getAMemberIncludingExtensions ( ) {
265+ exists ( ClassLikeDeclaration cls |
266+ this = cls .resolve ( ) and
267+ result = cls .getAMember ( )
268+ )
269+ }
270+
229271 override string toString ( ) {
230- result = concat ( getClassLikeDeclarationKeyword ( this ) + " " ) + concat ( this .getQualifiedName ( ) )
272+ result =
273+ concat ( getClassLikeDeclarationKeyword ( this ) + " " ) +
274+ concat ( getQualifiedNameForToString ( this ) )
231275 }
232276 }
233277
@@ -237,7 +281,8 @@ module Unified {
237281
238282 override string toString ( ) {
239283 result =
240- concat ( getConstructorDeclarationKeyword ( this ) + " " ) + concat ( this .getQualifiedName ( ) )
284+ concat ( getConstructorDeclarationKeyword ( this ) + " " ) +
285+ concat ( getQualifiedNameForToString ( this ) )
241286 }
242287 }
243288
@@ -251,7 +296,9 @@ module Unified {
251296 string getName ( ) { result = this .getNameNode ( ) .getValue ( ) }
252297
253298 override string toString ( ) {
254- result = concat ( getFunctionDeclarationKeyword ( this ) + " " ) + concat ( this .getQualifiedName ( ) )
299+ result =
300+ concat ( getFunctionDeclarationKeyword ( this ) + " " ) +
301+ concat ( getQualifiedNameForToString ( this ) )
255302 }
256303 }
257304
@@ -263,7 +310,9 @@ module Unified {
263310 string getName ( ) { result = this .getNameNode ( ) .getValue ( ) }
264311
265312 override string toString ( ) {
266- result = concat ( getVariableDeclarationKeyword ( this ) + " " ) + concat ( this .getQualifiedName ( ) )
313+ result =
314+ concat ( getVariableDeclarationKeyword ( this ) + " " ) +
315+ concat ( getQualifiedNameForToString ( this ) )
267316 }
268317 }
269318
0 commit comments