Skip to content

Commit d3aa6e2

Browse files
committed
C#: Handle some broken types in BMN.
1 parent c4033f2 commit d3aa6e2

File tree

1 file changed

+26
-3
lines changed
  • csharp/extractor/Semmle.Extraction.CSharp/Entities/Types

1 file changed

+26
-3
lines changed

csharp/extractor/Semmle.Extraction.CSharp/Entities/Types/NamedType.cs

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,32 @@ public static NamedType Create(Context cx, INamedTypeSymbol type) =>
2828
public static NamedType CreateNamedTypeFromTupleType(Context cx, INamedTypeSymbol type) =>
2929
UnderlyingTupleTypeFactory.Instance.CreateEntity(cx, (new SymbolEqualityWrapper(type), typeof(TupleType)), type);
3030

31-
public override bool NeedsPopulation => base.NeedsPopulation || Symbol.TypeKind == TypeKind.Error;
31+
public override bool NeedsPopulation => base.NeedsPopulation || IsBrokenType(Symbol);
32+
33+
/// <summary>
34+
/// Returns true in case we suspect this is broken type.
35+
/// </summary>
36+
/// <param name="symbol">Type symbol</param>
37+
private bool IsBrokenType(ITypeSymbol symbol)
38+
{
39+
if (symbol.TypeKind == TypeKind.Error)
40+
{
41+
return true;
42+
}
43+
44+
if (!Context.ExtractionContext.IsStandalone)
45+
{
46+
return false;
47+
}
48+
// (1) public class { ... } is a broken type and doesn't have a name.
49+
// (2) public class var { ... } is a an allowed type, but it overrides the var keyword for all uses.
50+
// It is probably a better heuristic to treat it as a broken type.
51+
return string.IsNullOrEmpty(symbol.Name) || symbol.Name == "var";
52+
}
3253

3354
public override void Populate(TextWriter trapFile)
3455
{
35-
if (Symbol.TypeKind == TypeKind.Error)
56+
if (IsBrokenType(Symbol))
3657
{
3758
UnknownType.Create(Context); // make sure this exists so we can use it in `TypeRef::getReferencedType`
3859
Context.ExtractionContext.MissingType(Symbol.ToString()!, Context.FromSource);
@@ -166,7 +187,9 @@ private class UnderlyingTupleTypeFactory : CachedEntityFactory<INamedTypeSymbol,
166187
// Create typerefs for constructed error types in case they are fully defined elsewhere.
167188
// We cannot use `!this.NeedsPopulation` because this would not be stable as it would depend on
168189
// the assembly that was being extracted at the time.
169-
private bool UsesTypeRef => Symbol.TypeKind == TypeKind.Error || SymbolEqualityComparer.Default.Equals(Symbol.OriginalDefinition, Symbol);
190+
private bool UsesTypeRef =>
191+
IsBrokenType(Symbol) ||
192+
SymbolEqualityComparer.Default.Equals(Symbol.OriginalDefinition, Symbol);
170193

171194
public override Type TypeRef => UsesTypeRef ? (Type)NamedTypeRef.Create(Context, Symbol) : this;
172195
}

0 commit comments

Comments
 (0)