File tree Expand file tree Collapse file tree
plugins/python/api/symbols
test/java/org/sonar/python/semantic Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -39,6 +39,9 @@ public interface ClassSymbol extends Symbol {
3939 @ Beta
4040 Optional <Symbol > resolveMember (String memberName );
4141
42+ @ Beta
43+ boolean canHaveMember (String memberName );
44+
4245 @ Beta
4346 boolean isOrExtends (String fullyQualifiedClassName );
4447
Original file line number Diff line number Diff line change @@ -147,6 +147,23 @@ public Optional<Symbol> resolveMember(String memberName) {
147147 return Optional .empty ();
148148 }
149149
150+ @ Override
151+ public boolean canHaveMember (String memberName ) {
152+ if (hasUnresolvedTypeHierarchy ()) {
153+ return true ;
154+ }
155+ for (Symbol symbol : allSuperClasses (true )) {
156+ if (symbol .kind () == Kind .CLASS ) {
157+ ClassSymbolImpl classSymbol = (ClassSymbolImpl ) symbol ;
158+ Symbol matchingMember = classSymbol .membersByName ().get (memberName );
159+ if (matchingMember != null ) {
160+ return true ;
161+ }
162+ }
163+ }
164+ return false ;
165+ }
166+
150167 @ Override
151168 public LocationInFile definitionLocation () {
152169 return classDefinitionLocation ;
Original file line number Diff line number Diff line change @@ -340,10 +340,39 @@ public void inherited_static_member() {
340340 "B.foo"
341341 );
342342
343+ assertThat (classSymbol .canHaveMember ("foo" )).isTrue ();
343344 Symbol foo = classSymbol .resolveMember ("foo" ).get ();
344345 assertThat (foo .usages ()).extracting (Usage ::kind ).containsExactly (Usage .Kind .ASSIGNMENT_LHS , Usage .Kind .OTHER );
345346 }
346347
348+ @ Test
349+ public void inherits_from_ambiguous_symbol () {
350+ ClassSymbol classSymbol = lastClassSymbol (
351+ "if x:" ,
352+ " class A: ..." ,
353+ "else:" ,
354+ " class A:" ,
355+ " def foo(): ..." ,
356+ "class B(A): ..."
357+ );
358+
359+ assertThat (classSymbol .resolveMember ("foo" ).isPresent ()).isFalse ();
360+ assertThat (classSymbol .canHaveMember ("foo" )).isTrue ();
361+ }
362+
363+ @ Test
364+ public void inherits_from_function_call () {
365+ ClassSymbol classSymbol = lastClassSymbol (
366+ "class A:" ,
367+ " def foo(): ..." ,
368+ "def func(): return A" ,
369+ "class B(func()): ..."
370+ );
371+
372+ assertThat (classSymbol .resolveMember ("foo" ).isPresent ()).isFalse ();
373+ assertThat (classSymbol .canHaveMember ("foo" )).isTrue ();
374+ }
375+
347376 private static void assertEqualsWithoutUsages (ClassSymbolImpl classSymbol ) {
348377 ClassSymbolImpl copied = classSymbol .copyWithoutUsages ();
349378 assertThat (copied .hasUnresolvedTypeHierarchy ()).isEqualTo (classSymbol .hasUnresolvedTypeHierarchy ());
You can’t perform that action at this time.
0 commit comments