Merge pull request #4017 from hvitved/csharp/unqualify-trap-ids3

C#: Remove assembly prefixes from TRAP labels
This commit is contained in:
Tom Hvitved
2020-09-04 09:20:39 +02:00
committed by GitHub
96 changed files with 2645 additions and 1066 deletions

View File

@@ -21,6 +21,10 @@ The following changes in version 1.26 affect C# analysis in all applications.
* Partial method bodies are extracted. Previously, partial method bodies were skipped completely.
* Inferring the lengths of implicitely sized arrays is fixed. Previously, multidimensional arrays were always extracted with the same length for
each dimension. With the fix, the array sizes `2` and `1` are extracted for `new int[,]{{1},{2}}`. Previously `2` and `2` were extracted.
* The extractor is now assembly-insensitive by default. This means that two entities with the same
fully-qualified name are now mapped to the same entity in the resulting database, regardless of
whether they belong to different assemblies. Assembly sensitivity can be reenabled by passing
`--assemblysensitivetrap` to the extractor.
## Changes to libraries

View File

@@ -141,7 +141,7 @@ namespace Semmle.Extraction.CIL.Entities
trapFile = trapWriter.TrapFile;
if (nocache || !System.IO.File.Exists(trapFile))
{
var cx = extractor.CreateContext(null, trapWriter, null);
var cx = extractor.CreateContext(null, trapWriter, null, false);
ExtractCIL(cx, assemblyPath, extractPdbs);
extracted = true;
}

View File

@@ -25,9 +25,12 @@ namespace Semmle.Extraction.CSharp
public readonly ILogger Logger;
public Analyser(IProgressMonitor pm, ILogger logger)
public readonly bool AddAssemblyTrapPrefix;
public Analyser(IProgressMonitor pm, ILogger logger, bool addAssemblyTrapPrefix)
{
Logger = logger;
AddAssemblyTrapPrefix = addAssemblyTrapPrefix;
Logger.Log(Severity.Info, "EXTRACTION STARTING at {0}", DateTime.Now);
stopWatch.Start();
progressMonitor = pm;
@@ -231,7 +234,7 @@ namespace Semmle.Extraction.CSharp
var projectLayout = layout.LookupProjectOrDefault(assemblyPath);
var trapWriter = projectLayout.CreateTrapWriter(Logger, assemblyPath, true, options.TrapCompression);
compilationTrapFile = trapWriter; // Dispose later
var cx = extractor.CreateContext(compilation.Clone(), trapWriter, new AssemblyScope(assembly, assemblyPath, true));
var cx = extractor.CreateContext(compilation.Clone(), trapWriter, new AssemblyScope(assembly, assemblyPath, true), AddAssemblyTrapPrefix);
compilationEntity = new Entities.Compilation(cx, cwd, args);
}
@@ -286,7 +289,7 @@ namespace Semmle.Extraction.CSharp
if (assembly != null)
{
var cx = extractor.CreateContext(c, trapWriter, new AssemblyScope(assembly, assemblyPath, false));
var cx = extractor.CreateContext(c, trapWriter, new AssemblyScope(assembly, assemblyPath, false), AddAssemblyTrapPrefix);
foreach (var module in assembly.Modules)
{
@@ -372,7 +375,7 @@ namespace Semmle.Extraction.CSharp
if (!upToDate)
{
Context cx = extractor.CreateContext(compilation.Clone(), trapWriter, new SourceScope(tree));
Context cx = extractor.CreateContext(compilation.Clone(), trapWriter, new SourceScope(tree), AddAssemblyTrapPrefix);
Populators.CompilationUnit.Extract(cx, tree.GetRoot());
cx.PopulateAll();
cx.ExtractComments(cx.CommentGenerator);

View File

@@ -77,7 +77,7 @@ namespace Semmle.Extraction.CSharp.Entities
}
public new static Accessor Create(Context cx, IMethodSymbol symbol) =>
AccessorFactory.Instance.CreateEntity(cx, symbol);
AccessorFactory.Instance.CreateEntityFromSymbol(cx, symbol);
class AccessorFactory : ICachedEntityFactory<IMethodSymbol, Accessor>
{

View File

@@ -35,7 +35,7 @@ namespace Semmle.Extraction.CSharp.Entities
Context.TrapWriter.Writer.commentblock_binding(this, entity, binding);
}
public static CommentBlock Create(Context cx, ICommentBlock block) => CommentBlockFactory.Instance.CreateEntity(cx, block);
public static CommentBlock Create(Context cx, ICommentBlock block) => CommentBlockFactory.Instance.CreateEntity(cx, block, block);
class CommentBlockFactory : ICachedEntityFactory<ICommentBlock, CommentBlock>
{

View File

@@ -129,7 +129,11 @@ namespace Semmle.Extraction.CSharp.Entities
trapFile.Write(";commentline");
}
static CommentLine Create(Context cx, Microsoft.CodeAnalysis.Location loc, CommentLineType type, string text, string raw) => CommentLineFactory.Instance.CreateEntity(cx, loc, type, text, raw);
static CommentLine Create(Context cx, Microsoft.CodeAnalysis.Location loc, CommentLineType type, string text, string raw)
{
var init = (loc, type, text, raw);
return CommentLineFactory.Instance.CreateEntity(cx, init, init);
}
class CommentLineFactory : ICachedEntityFactory<(Microsoft.CodeAnalysis.Location, CommentLineType, string, string), CommentLine>
{

View File

@@ -104,7 +104,7 @@ namespace Semmle.Extraction.CSharp.Entities
{
case MethodKind.StaticConstructor:
case MethodKind.Constructor:
return ConstructorFactory.Instance.CreateEntity(cx, constructor);
return ConstructorFactory.Instance.CreateEntityFromSymbol(cx, constructor);
default:
throw new InternalError(constructor, "Attempt to create a Constructor from a symbol that isn't a constructor");
}

View File

@@ -11,7 +11,7 @@ namespace Semmle.Extraction.CSharp.Entities
: base(cx, init) { }
public new static Conversion Create(Context cx, IMethodSymbol symbol) =>
ConversionFactory.Instance.CreateEntity(cx, symbol);
ConversionFactory.Instance.CreateEntityFromSymbol(cx, symbol);
public override Microsoft.CodeAnalysis.Location ReportingLocation
{

View File

@@ -24,7 +24,7 @@ namespace Semmle.Extraction.CSharp.Entities
}
public new static Destructor Create(Context cx, IMethodSymbol symbol) =>
DestructorFactory.Instance.CreateEntity(cx, symbol);
DestructorFactory.Instance.CreateEntityFromSymbol(cx, symbol);
class DestructorFactory : ICachedEntityFactory<IMethodSymbol, Destructor>
{

View File

@@ -60,7 +60,7 @@ namespace Semmle.Extraction.CSharp.Entities
TypeMention.Create(Context, syntaxType, this, type);
}
public static Event Create(Context cx, IEventSymbol symbol) => EventFactory.Instance.CreateEntity(cx, symbol);
public static Event Create(Context cx, IEventSymbol symbol) => EventFactory.Instance.CreateEntityFromSymbol(cx, symbol);
class EventFactory : ICachedEntityFactory<IEventSymbol, Event>
{

View File

@@ -53,7 +53,7 @@ namespace Semmle.Extraction.CSharp.Entities
}
public new static EventAccessor Create(Context cx, IMethodSymbol symbol) =>
EventAccessorFactory.Instance.CreateEntity(cx, symbol);
EventAccessorFactory.Instance.CreateEntityFromSymbol(cx, symbol);
class EventAccessorFactory : ICachedEntityFactory<IMethodSymbol, EventAccessor>
{

View File

@@ -18,7 +18,7 @@ namespace Semmle.Extraction.CSharp.Entities
type = new Lazy<AnnotatedType>(() => Entities.Type.Create(cx, symbol.GetAnnotatedType()));
}
public static Field Create(Context cx, IFieldSymbol field) => FieldFactory.Instance.CreateEntity(cx, field);
public static Field Create(Context cx, IFieldSymbol field) => FieldFactory.Instance.CreateEntityFromSymbol(cx, field);
// Do not populate backing fields.
// Populate Tuple fields.
@@ -101,6 +101,8 @@ namespace Semmle.Extraction.CSharp.Entities
public override void WriteId(TextWriter trapFile)
{
trapFile.WriteSubId(Type.Type);
trapFile.Write(" ");
trapFile.WriteSubId(ContainingType);
trapFile.Write('.');
trapFile.Write(symbol.Name);

View File

@@ -71,7 +71,7 @@ namespace Semmle.Extraction.CSharp.Entities
TypeMention.Create(Context, syntax.Type, this, type);
}
public static new Indexer Create(Context cx, IPropertySymbol prop) => IndexerFactory.Instance.CreateEntity(cx, prop);
public static new Indexer Create(Context cx, IPropertySymbol prop) => IndexerFactory.Instance.CreateEntityFromSymbol(cx, prop);
public override void WriteId(TextWriter trapFile)
{

View File

@@ -22,7 +22,7 @@ namespace Semmle.Extraction.CSharp.Entities
trapFile.Write('*');
}
public static new LocalFunction Create(Context cx, IMethodSymbol field) => LocalFunctionFactory.Instance.CreateEntity(cx, field);
public static new LocalFunction Create(Context cx, IMethodSymbol field) => LocalFunctionFactory.Instance.CreateEntityFromSymbol(cx, field);
class LocalFunctionFactory : ICachedEntityFactory<IMethodSymbol, LocalFunction>
{

View File

@@ -43,7 +43,7 @@ namespace Semmle.Extraction.CSharp.Entities
public static LocalVariable Create(Context cx, ISymbol local)
{
return LocalVariableFactory.Instance.CreateEntity(cx, local);
return LocalVariableFactory.Instance.CreateEntityFromSymbol(cx, local);
}
void DefineConstantValue(TextWriter trapFile)

View File

@@ -108,6 +108,9 @@ namespace Semmle.Extraction.CSharp.Entities
/// </summary>
protected static void BuildMethodId(Method m, TextWriter trapFile)
{
m.symbol.ReturnType.BuildOrWriteId(m.Context, trapFile, m.symbol);
trapFile.Write(" ");
trapFile.WriteSubId(m.ContainingType);
AddExplicitInterfaceQualifierToId(m.Context, trapFile, m.symbol.ExplicitInterfaceImplementations);
@@ -129,7 +132,7 @@ namespace Semmle.Extraction.CSharp.Entities
// Type arguments with different nullability can result in
// a constructed method with different nullability of its parameters and return type,
// so we need to create a distinct database entity for it.
trapFile.BuildList(",", m.symbol.GetAnnotatedTypeArguments(), (ta, tb0) => { AddSignatureTypeToId(m.Context, tb0, m.symbol, ta.Symbol); trapFile.Write((int)ta.Nullability); });
trapFile.BuildList(",", m.symbol.GetAnnotatedTypeArguments(), (ta, tb0) => { ta.Symbol.BuildOrWriteId(m.Context, tb0, m.symbol); trapFile.Write((int)ta.Nullability); });
trapFile.Write('>');
}
}
@@ -163,65 +166,21 @@ namespace Semmle.Extraction.CSharp.Entities
BuildMethodId(this, trapFile);
}
/// <summary>
/// Adds an appropriate label ID to the trap builder <paramref name="trapFile"/>
/// for the type <paramref name="type"/> belonging to the signature of method
/// <paramref name="method"/>.
///
/// For methods without type parameters this will always add the key of the
/// corresponding type.
///
/// For methods with type parameters, this will add the key of the
/// corresponding type if the type does *not* contain one of the method
/// type parameters, otherwise it will add a textual representation of
/// the type. This distinction is required because type parameter IDs
/// refer to their declaring methods.
///
/// Example:
///
/// <code>
/// int Count&lt;T&gt;(IEnumerable<T> items)
/// </code>
///
/// The label definitions for <code>Count</code> (<code>#4</code>) and <code>T</code>
/// (<code>#5</code>) will look like:
///
/// <code>
/// #1=&lt;label for System.Int32&gt;
/// #2=&lt;label for type containing Count&gt;
/// #3=&lt;label for IEnumerable`1&gt;
/// #4=@"{#1} {#2}.Count`2(#3<T>);method"
/// #5=@"{#4}T;typeparameter"
/// </code>
///
/// Note how <code>int</code> is referenced in the label definition <code>#3</code> for
/// <code>Count</code>, while <code>T[]</code> is represented textually in order
/// to make the reference to <code>#3</code> in the label definition <code>#4</code> for
/// <code>T</code> valid.
/// </summary>
protected static void AddSignatureTypeToId(Context cx, TextWriter trapFile, IMethodSymbol method, ITypeSymbol type)
{
if (type.ContainsTypeParameters(cx, method))
type.BuildTypeId(cx, trapFile, (cx0, tb0, type0) => AddSignatureTypeToId(cx, tb0, method, type0));
else
trapFile.WriteSubId(Type.Create(cx, type));
}
protected static void AddParametersToId(Context cx, TextWriter trapFile, IMethodSymbol method)
{
trapFile.Write('(');
int index = 0;
if (method.MethodKind == MethodKind.ReducedExtension)
{
trapFile.WriteSeparator(",", ref index);
AddSignatureTypeToId(cx, trapFile, method, method.ReceiverType);
}
var @params = method.MethodKind == MethodKind.ReducedExtension
? method.ReducedFrom.Parameters
: method.Parameters;
foreach (var param in method.Parameters)
foreach (var param in @params)
{
trapFile.WriteSeparator(",", ref index);
AddSignatureTypeToId(cx, trapFile, method, param.Type);
param.Type.BuildOrWriteId(cx, trapFile, method);
trapFile.Write(" ");
trapFile.Write(param.Name);
switch (param.RefKind)
{
case RefKind.Out:
@@ -245,9 +204,7 @@ namespace Semmle.Extraction.CSharp.Entities
public static void AddExplicitInterfaceQualifierToId(Context cx, System.IO.TextWriter trapFile, IEnumerable<ISymbol> explicitInterfaceImplementations)
{
if (explicitInterfaceImplementations.Any())
{
trapFile.AppendList(",", explicitInterfaceImplementations.Select(impl => cx.CreateEntity(impl.ContainingType)));
}
}
public virtual string Name => symbol.Name;

View File

@@ -5,37 +5,16 @@ using System.Reflection;
namespace Semmle.Extraction.CSharp.Entities
{
/// <summary>
/// Provide a "Key" object to allow modifiers to exist as entities in the extractor
/// hash map. (Raw strings would work as keys but might clash with other types).
/// </summary>
class ModifierKey : Object
class Modifier : Extraction.CachedEntity<string>
{
public readonly string name;
public ModifierKey(string m)
{
name = m;
}
public override bool Equals(Object obj)
{
return obj.GetType() == GetType() && name == ((ModifierKey)obj).name;
}
public override int GetHashCode() => 13 * name.GetHashCode();
}
class Modifier : Extraction.CachedEntity<ModifierKey>
{
Modifier(Context cx, ModifierKey init)
Modifier(Context cx, string init)
: base(cx, init) { }
public override Microsoft.CodeAnalysis.Location ReportingLocation => null;
public override void WriteId(TextWriter trapFile)
{
trapFile.Write(symbol.name);
trapFile.Write(symbol);
trapFile.Write(";modifier");
}
@@ -43,7 +22,7 @@ namespace Semmle.Extraction.CSharp.Entities
public override void Populate(TextWriter trapFile)
{
trapFile.modifiers(Label, symbol.name);
trapFile.modifiers(Label, symbol);
}
public static string AccessbilityModifier(Accessibility access)
@@ -152,17 +131,22 @@ namespace Semmle.Extraction.CSharp.Entities
}
}
public static Modifier Create(Context cx, string modifier) =>
ModifierFactory.Instance.CreateEntity(cx, new ModifierKey(modifier));
public static Modifier Create(Context cx, string modifier)
{
return ModifierFactory.Instance.CreateEntity(cx, (typeof(Modifier), modifier), modifier);
}
public static Modifier Create(Context cx, Accessibility access) =>
ModifierFactory.Instance.CreateEntity(cx, new ModifierKey(AccessbilityModifier(access)));
public static Modifier Create(Context cx, Accessibility access)
{
var modifier = AccessbilityModifier(access);
return ModifierFactory.Instance.CreateEntity(cx, (typeof(Modifier), modifier), modifier);
}
class ModifierFactory : ICachedEntityFactory<ModifierKey, Modifier>
class ModifierFactory : ICachedEntityFactory<string, Modifier>
{
public static readonly ModifierFactory Instance = new ModifierFactory();
public Modifier Create(Context cx, ModifierKey init) => new Modifier(cx, init);
public Modifier Create(Context cx, string init) => new Modifier(cx, init);
}
public override TrapStackBehaviour TrapStackBehaviour => TrapStackBehaviour.OptionalLabel;
}

View File

@@ -34,7 +34,7 @@ namespace Semmle.Extraction.CSharp.Entities
trapFile.Write(";namespace");
}
public static Namespace Create(Context cx, INamespaceSymbol ns) => NamespaceFactory.Instance.CreateEntity2(cx, ns);
public static Namespace Create(Context cx, INamespaceSymbol ns) => NamespaceFactory.Instance.CreateEntityFromSymbol(cx, ns);
class NamespaceFactory : ICachedEntityFactory<INamespaceSymbol, Namespace>
{

View File

@@ -51,7 +51,7 @@ namespace Semmle.Extraction.CSharp.Entities
ExtractCompilerGenerated(trapFile);
}
public new static OrdinaryMethod Create(Context cx, IMethodSymbol method) => OrdinaryMethodFactory.Instance.CreateEntity(cx, method);
public new static OrdinaryMethod Create(Context cx, IMethodSymbol method) => OrdinaryMethodFactory.Instance.CreateEntityFromSymbol(cx, method);
class OrdinaryMethodFactory : ICachedEntityFactory<IMethodSymbol, OrdinaryMethod>
{

View File

@@ -66,10 +66,10 @@ namespace Semmle.Extraction.CSharp.Entities
}
public static Parameter Create(Context cx, IParameterSymbol param, IEntity parent, Parameter original = null) =>
ParameterFactory.Instance.CreateEntity(cx, param, parent, original);
ParameterFactory.Instance.CreateEntity(cx, param, (param, parent, original));
public static Parameter Create(Context cx, IParameterSymbol param) =>
ParameterFactory.Instance.CreateEntity(cx, param, null, null);
ParameterFactory.Instance.CreateEntity(cx, param, (param, null, null));
public override void WriteId(TextWriter trapFile)
{
@@ -202,7 +202,7 @@ namespace Semmle.Extraction.CSharp.Entities
return obj != null && obj.GetType() == typeof(VarargsType);
}
public static VarargsType Create(Context cx) => VarargsTypeFactory.Instance.CreateNullableEntity(cx, null);
public static VarargsType Create(Context cx) => VarargsTypeFactory.Instance.CreateEntity(cx, typeof(VarargsType), null);
class VarargsTypeFactory : ICachedEntityFactory<string, VarargsType>
{
@@ -237,7 +237,7 @@ namespace Semmle.Extraction.CSharp.Entities
return obj != null && obj.GetType() == typeof(VarargsParam);
}
public static VarargsParam Create(Context cx, Method method) => VarargsParamFactory.Instance.CreateEntity(cx, method);
public static VarargsParam Create(Context cx, Method method) => VarargsParamFactory.Instance.CreateEntity(cx, typeof(VarargsParam), method);
class VarargsParamFactory : ICachedEntityFactory<Method, VarargsParam>
{
@@ -264,19 +264,8 @@ namespace Semmle.Extraction.CSharp.Entities
trapFile.param_location(this, Original.Location);
}
public override int GetHashCode() => symbol.GetHashCode() + 31 * ConstructedType.GetHashCode();
public override bool Equals(object obj)
{
var other = obj as ConstructedExtensionParameter;
if (other == null || other.GetType() != typeof(ConstructedExtensionParameter))
return false;
return SymbolEqualityComparer.Default.Equals(symbol, other.symbol) && SymbolEqualityComparer.Default.Equals(ConstructedType, other.ConstructedType);
}
public static ConstructedExtensionParameter Create(Context cx, Method method, Parameter parameter) =>
ExtensionParamFactory.Instance.CreateEntity(cx, (method, parameter));
ExtensionParamFactory.Instance.CreateEntity(cx, (new SymbolEqualityWrapper(parameter.symbol), new SymbolEqualityWrapper(method.symbol.ReceiverType)), (method, parameter));
class ExtensionParamFactory : ICachedEntityFactory<(Method, Parameter), ConstructedExtensionParameter>
{

View File

@@ -1,3 +1,4 @@
using System;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Semmle.Extraction.CSharp.Entities.Expressions;
@@ -11,10 +12,18 @@ namespace Semmle.Extraction.CSharp.Entities
class Property : CachedSymbol<IPropertySymbol>, IExpressionParentEntity
{
protected Property(Context cx, IPropertySymbol init)
: base(cx, init) { }
: base(cx, init)
{
type = new Lazy<Type>(() => Type.Create(Context, symbol.Type));
}
readonly Lazy<Type> type;
Type Type => type.Value;
public override void WriteId(TextWriter trapFile)
{
trapFile.WriteSubId(Type);
trapFile.Write(" ");
trapFile.WriteSubId(ContainingType);
trapFile.Write('.');
Method.AddExplicitInterfaceQualifierToId(Context, trapFile, symbol.ExplicitInterfaceImplementations);
@@ -31,7 +40,7 @@ namespace Semmle.Extraction.CSharp.Entities
PopulateNullability(trapFile, symbol.GetAnnotatedType());
PopulateRefKind(trapFile, symbol.RefKind);
var type = Type.Create(Context, symbol.Type);
var type = Type;
trapFile.properties(this, symbol.GetName(), ContainingType, type.TypeRef, Create(Context, symbol.OriginalDefinition));
var getter = symbol.GetMethod;
@@ -113,7 +122,7 @@ namespace Semmle.Extraction.CSharp.Entities
{
bool isIndexer = prop.IsIndexer || prop.Parameters.Any();
return isIndexer ? Indexer.Create(cx, prop) : PropertyFactory.Instance.CreateEntity(cx, prop);
return isIndexer ? Indexer.Create(cx, prop) : PropertyFactory.Instance.CreateEntityFromSymbol(cx, prop);
}
public void VisitDeclaration(Context cx, PropertyDeclarationSyntax p)

View File

@@ -36,7 +36,7 @@ namespace Semmle.Extraction.CSharp.Entities
trapFile.Write(";type");
}
public static ArrayType Create(Context cx, IArrayTypeSymbol symbol) => ArrayTypeFactory.Instance.CreateEntity(cx, symbol);
public static ArrayType Create(Context cx, IArrayTypeSymbol symbol) => ArrayTypeFactory.Instance.CreateEntityFromSymbol(cx, symbol);
class ArrayTypeFactory : ICachedEntityFactory<IArrayTypeSymbol, ArrayType>
{

View File

@@ -9,7 +9,7 @@ namespace Semmle.Extraction.CSharp.Entities
DynamicType(Context cx, IDynamicTypeSymbol init)
: base(cx, init) { }
public static DynamicType Create(Context cx, IDynamicTypeSymbol type) => DynamicTypeFactory.Instance.CreateEntity(cx, type);
public static DynamicType Create(Context cx, IDynamicTypeSymbol type) => DynamicTypeFactory.Instance.CreateEntityFromSymbol(cx, type);
public override Microsoft.CodeAnalysis.Location ReportingLocation => Context.Compilation.ObjectType.Locations.FirstOrDefault();

View File

@@ -17,7 +17,7 @@ namespace Semmle.Extraction.CSharp.Entities
typeArgumentsLazy = new Lazy<Type[]>(() => symbol.TypeArguments.Select(t => Create(cx, t)).ToArray());
}
public static NamedType Create(Context cx, INamedTypeSymbol type) => NamedTypeFactory.Instance.CreateEntity(cx, type);
public static NamedType Create(Context cx, INamedTypeSymbol type) => NamedTypeFactory.Instance.CreateEntityFromSymbol(cx, type);
public override bool NeedsPopulation => base.NeedsPopulation || symbol.TypeKind == TypeKind.Error;
@@ -29,7 +29,8 @@ namespace Semmle.Extraction.CSharp.Entities
return;
}
trapFile.typeref_type((NamedTypeRef)TypeRef, this);
if (UsesTypeRef)
trapFile.typeref_type((NamedTypeRef)TypeRef, this);
if (symbol.IsGenericType)
{
@@ -106,10 +107,25 @@ namespace Semmle.Extraction.CSharp.Entities
public override Microsoft.CodeAnalysis.Location ReportingLocation => GetLocations(symbol).FirstOrDefault();
bool IsAnonymousType() => symbol.IsAnonymousType || symbol.Name.Contains("__AnonymousType");
public override void WriteId(TextWriter trapFile)
{
symbol.BuildTypeId(Context, trapFile, (cx0, tb0, sub) => tb0.WriteSubId(Create(cx0, sub)));
trapFile.Write(";type");
if (IsAnonymousType())
trapFile.Write('*');
else
{
symbol.BuildTypeId(Context, trapFile, symbol);
trapFile.Write(";type");
}
}
public override void WriteQuotedId(TextWriter trapFile)
{
if (IsAnonymousType())
trapFile.Write('*');
else
base.WriteQuotedId(trapFile);
}
/// <summary>
@@ -148,7 +164,13 @@ namespace Semmle.Extraction.CSharp.Entities
public NamedType Create(Context cx, INamedTypeSymbol init) => new NamedType(cx, init);
}
public override Type TypeRef => NamedTypeRef.Create(Context, symbol);
// Do not create typerefs of constructed generics as they are always in the current trap file.
// Create typerefs for constructed error types in case they are fully defined elsewhere.
// We cannot use `!this.NeedsPopulation` because this would not be stable as it would depend on
// the assembly that was being extracted at the time.
bool UsesTypeRef => symbol.TypeKind == TypeKind.Error || SymbolEqualityComparer.Default.Equals(symbol.OriginalDefinition, symbol);
public override Type TypeRef => UsesTypeRef ? (Type)NamedTypeRef.Create(Context, symbol) : this;
}
class NamedTypeRef : Type<INamedTypeSymbol>
@@ -161,7 +183,9 @@ namespace Semmle.Extraction.CSharp.Entities
}
public static NamedTypeRef Create(Context cx, INamedTypeSymbol type) =>
NamedTypeRefFactory.Instance.CreateEntity2(cx, type);
// We need to use a different cache key than `type` to avoid mixing up
// `NamedType`s and `NamedTypeRef`s
NamedTypeRefFactory.Instance.CreateEntity(cx, (typeof(NamedTypeRef), new SymbolEqualityWrapper(type)), type);
class NamedTypeRefFactory : ICachedEntityFactory<INamedTypeSymbol, NamedTypeRef>
{

View File

@@ -27,7 +27,7 @@ namespace Semmle.Extraction.CSharp.Entities
return obj != null && obj.GetType() == typeof(NullType);
}
public static AnnotatedType Create(Context cx) => new AnnotatedType(NullTypeFactory.Instance.CreateNullableEntity(cx, null), NullableAnnotation.None);
public static AnnotatedType Create(Context cx) => new AnnotatedType(NullTypeFactory.Instance.CreateEntity(cx, typeof(NullType), null), NullableAnnotation.None);
class NullTypeFactory : ICachedEntityFactory<ITypeSymbol, NullType>
{

View File

@@ -127,7 +127,7 @@ namespace Semmle.Extraction.CSharp.Entities
symbol.WriteId(trapFile);
}
public static NullabilityEntity Create(Context cx, Nullability init) => NullabilityFactory.Instance.CreateEntity(cx, init);
public static NullabilityEntity Create(Context cx, Nullability init) => NullabilityFactory.Instance.CreateEntity(cx, init, init);
class NullabilityFactory : ICachedEntityFactory<Nullability, NullabilityEntity>
{

View File

@@ -29,7 +29,7 @@ namespace Semmle.Extraction.CSharp.Entities
public Type PointedAtType { get; private set; }
public static PointerType Create(Context cx, IPointerTypeSymbol symbol) => PointerTypeFactory.Instance.CreateEntity(cx, symbol);
public static PointerType Create(Context cx, IPointerTypeSymbol symbol) => PointerTypeFactory.Instance.CreateEntityFromSymbol(cx, symbol);
class PointerTypeFactory : ICachedEntityFactory<IPointerTypeSymbol, PointerType>
{

View File

@@ -13,7 +13,7 @@ namespace Semmle.Extraction.CSharp.Entities
/// </summary>
class TupleType : Type<INamedTypeSymbol>
{
public static TupleType Create(Context cx, INamedTypeSymbol type) => TupleTypeFactory.Instance.CreateEntity(cx, type);
public static TupleType Create(Context cx, INamedTypeSymbol type) => TupleTypeFactory.Instance.CreateEntityFromSymbol(cx, type);
class TupleTypeFactory : ICachedEntityFactory<INamedTypeSymbol, TupleType>
{
@@ -32,7 +32,7 @@ namespace Semmle.Extraction.CSharp.Entities
public override void WriteId(TextWriter trapFile)
{
symbol.BuildTypeId(Context, trapFile, (cx0, tb0, sub) => tb0.WriteSubId(Create(cx0, sub)));
symbol.BuildTypeId(Context, trapFile, symbol);
trapFile.Write(";tuple");
}

View File

@@ -100,19 +100,14 @@ namespace Semmle.Extraction.CSharp.Entities
// Visit base types
var baseTypes = new List<Type>();
if (symbol.BaseType != null)
if (symbol.GetNonObjectBaseType(Context) is INamedTypeSymbol @base)
{
Type baseKey = Create(Context, symbol.BaseType);
Type baseKey = Create(Context, @base);
trapFile.extend(this, baseKey.TypeRef);
if (symbol.TypeKind != TypeKind.Struct)
baseTypes.Add(baseKey);
}
if (symbol.TypeKind == TypeKind.Interface)
{
trapFile.extend(this, Create(Context, Context.Compilation.ObjectType));
}
if (!(base.symbol is IArrayTypeSymbol))
{
foreach (var t in base.symbol.Interfaces.Select(i => Create(Context, i)))
@@ -298,7 +293,9 @@ namespace Semmle.Extraction.CSharp.Entities
: base(cx, init, parent, original) { }
new public static DelegateTypeParameter Create(Context cx, IParameterSymbol param, IEntity parent, Parameter original = null) =>
DelegateTypeParameterFactory.Instance.CreateEntity(cx, (param, parent, original));
// We need to use a different cache key than `param` to avoid mixing up
// `DelegateTypeParameter`s and `Parameter`s
DelegateTypeParameterFactory.Instance.CreateEntity(cx, (typeof(DelegateTypeParameter), new SymbolEqualityWrapper(param)), (param, parent, original));
class DelegateTypeParameterFactory : ICachedEntityFactory<(IParameterSymbol, IEntity, Parameter), DelegateTypeParameter>
{
@@ -324,6 +321,14 @@ namespace Semmle.Extraction.CSharp.Entities
}
public override TrapStackBehaviour TrapStackBehaviour => TrapStackBehaviour.NoLabel;
public override bool Equals(object obj)
{
var other = obj as Type;
return other?.GetType() == GetType() && SymbolEqualityComparer.IncludeNullability.Equals(other.symbol, symbol);
}
public override int GetHashCode() => SymbolEqualityComparer.IncludeNullability.GetHashCode(symbol);
}
abstract class Type<T> : Type where T : ITypeSymbol

View File

@@ -38,17 +38,11 @@ namespace Semmle.Extraction.CSharp.Entities
if (symbol.HasUnmanagedTypeConstraint)
trapFile.general_type_parameter_constraints(constraints, 4);
ITypeSymbol baseType = symbol.HasValueTypeConstraint ?
Context.Compilation.GetTypeByMetadataName(valueTypeName) :
Context.Compilation.ObjectType;
if (symbol.ReferenceTypeConstraintNullableAnnotation == NullableAnnotation.Annotated)
trapFile.general_type_parameter_constraints(constraints, 5);
foreach (var abase in symbol.GetAnnotatedTypeConstraints())
{
if (abase.Symbol.TypeKind != TypeKind.Interface)
baseType = abase.Symbol;
var t = Create(Context, abase.Symbol);
trapFile.specific_type_parameter_constraints(constraints, t.TypeRef);
if (!abase.HasObliviousNullability())
@@ -56,7 +50,6 @@ namespace Semmle.Extraction.CSharp.Entities
}
trapFile.types(this, Kinds.TypeKind.TYPE_PARAMETER, symbol.Name);
trapFile.extend(this, Create(Context, baseType).TypeRef);
Namespace parentNs = Namespace.Create(Context, symbol.TypeParameterKind == TypeParameterKind.Method ? Context.Compilation.GlobalNamespace : symbol.ContainingNamespace);
trapFile.parent_namespace(this, parentNs);
@@ -88,7 +81,7 @@ namespace Semmle.Extraction.CSharp.Entities
}
static public TypeParameter Create(Context cx, ITypeParameterSymbol p) =>
TypeParameterFactory.Instance.CreateEntity(cx, p);
TypeParameterFactory.Instance.CreateEntityFromSymbol(cx, p);
/// <summary>
/// The variance of this type parameter.

View File

@@ -49,13 +49,6 @@ namespace Semmle.Extraction.CSharp.Entities
}
}
public override void WriteId(TextWriter trapFile)
{
AddSignatureTypeToId(Context, trapFile, symbol, symbol.ReturnType); // Needed for op_explicit(), which differs only by return type.
trapFile.Write(' ');
BuildMethodId(this, trapFile);
}
/// <summary>
/// For some reason, some operators are missing from the Roslyn database of mscorlib.
/// This method returns <code>true</code> for such operators.
@@ -68,7 +61,7 @@ namespace Semmle.Extraction.CSharp.Entities
if (containingType != null)
{
var containingNamedType = containingType as INamedTypeSymbol;
return containingNamedType == null || !containingNamedType.MemberNames.Contains(symbol.Name);
return containingNamedType == null || !containingNamedType.GetMembers(symbol.Name).Contains(symbol);
}
var pointerType = symbol.Parameters.Select(p => p.Type).OfType<IPointerTypeSymbol>().FirstOrDefault();
@@ -190,7 +183,7 @@ namespace Semmle.Extraction.CSharp.Entities
return result;
}
public new static UserOperator Create(Context cx, IMethodSymbol symbol) => UserOperatorFactory.Instance.CreateEntity(cx, symbol);
public new static UserOperator Create(Context cx, IMethodSymbol symbol) => UserOperatorFactory.Instance.CreateEntityFromSymbol(cx, symbol);
class UserOperatorFactory : ICachedEntityFactory<IMethodSymbol, UserOperator>
{

View File

@@ -76,7 +76,7 @@ namespace Semmle.Extraction.CSharp
return ExitCode.Ok;
}
using (var analyser = new Analyser(new LogProgressMonitor(logger), logger))
using (var analyser = new Analyser(new LogProgressMonitor(logger), logger, commandLineArguments.AssemblySensitiveTrap))
using (var references = new BlockingCollection<MetadataReference>())
{
try
@@ -318,7 +318,7 @@ namespace Semmle.Extraction.CSharp
ILogger logger,
CommonOptions options)
{
using (var analyser = new Analyser(pm, logger))
using (var analyser = new Analyser(pm, logger, false))
using (var references = new BlockingCollection<MetadataReference>())
{
try

View File

@@ -26,6 +26,11 @@ namespace Semmle.Extraction.CSharp
/// </summary>
public bool ClrTracer = false;
/// <summary>
/// Holds if assembly information should be prefixed to TRAP labels.
/// </summary>
public bool AssemblySensitiveTrap = false;
public static Options CreateWithEnvironment(string[] arguments)
{
var options = new Options();
@@ -75,6 +80,9 @@ namespace Semmle.Extraction.CSharp
case "clrtracer":
ClrTracer = value;
return true;
case "assemblysensitivetrap":
AssemblySensitiveTrap = value;
return true;
default:
return base.handleFlag(flag, value);
}

View File

@@ -85,41 +85,62 @@ namespace Semmle.Extraction.CSharp
}
/// <summary>
/// Holds if this type symbol contains a type parameter from the
/// declaring generic <paramref name="declaringGeneric"/>.
/// Holds if the ID generated for `dependant` will contain a reference to
/// the ID for `symbol`. If this is the case, then the ID for `symbol` must
/// not contain a reference back to `dependant`.
/// </summary>
public static bool ContainsTypeParameters(this ITypeSymbol type, Context cx, ISymbol declaringGeneric)
public static bool IdDependsOn(this ITypeSymbol dependant, Context cx, ISymbol symbol)
{
using (cx.StackGuard)
var seen = new HashSet<ITypeSymbol>(SymbolEqualityComparer.Default);
bool IdDependsOnImpl(ITypeSymbol type)
{
switch (type.TypeKind)
if (SymbolEqualityComparer.Default.Equals(type, symbol))
return true;
if (type is null || seen.Contains(type))
return false;
seen.Add(type);
using (cx.StackGuard)
{
case TypeKind.Array:
var array = (IArrayTypeSymbol)type;
return array.ElementType.ContainsTypeParameters(cx, declaringGeneric);
case TypeKind.Class:
case TypeKind.Interface:
case TypeKind.Struct:
case TypeKind.Enum:
case TypeKind.Delegate:
case TypeKind.Error:
var named = (INamedTypeSymbol)type;
if (named.IsTupleType)
named = named.TupleUnderlyingType;
if (named.ContainingType != null && named.ContainingType.ContainsTypeParameters(cx, declaringGeneric))
return true;
return named.TypeArguments.Any(arg => arg.ContainsTypeParameters(cx, declaringGeneric));
case TypeKind.Pointer:
var ptr = (IPointerTypeSymbol)type;
return ptr.PointedAtType.ContainsTypeParameters(cx, declaringGeneric);
case TypeKind.TypeParameter:
var tp = (ITypeParameterSymbol)type;
var declaringGen = tp.TypeParameterKind == TypeParameterKind.Method ? tp.DeclaringMethod : (ISymbol)tp.DeclaringType;
return SymbolEqualityComparer.Default.Equals(declaringGen, declaringGeneric);
default:
return false;
switch (type.TypeKind)
{
case TypeKind.Array:
var array = (IArrayTypeSymbol)type;
return IdDependsOnImpl(array.ElementType);
case TypeKind.Class:
case TypeKind.Interface:
case TypeKind.Struct:
case TypeKind.Enum:
case TypeKind.Delegate:
case TypeKind.Error:
var named = (INamedTypeSymbol)type;
if (named.IsTupleType)
named = named.TupleUnderlyingType;
if (IdDependsOnImpl(named.ContainingType))
return true;
if (IdDependsOnImpl(named.GetNonObjectBaseType(cx)))
return true;
if (IdDependsOnImpl(named.ConstructedFrom))
return true;
return named.TypeArguments.Any(IdDependsOnImpl);
case TypeKind.Pointer:
var ptr = (IPointerTypeSymbol)type;
return IdDependsOnImpl(ptr.PointedAtType);
case TypeKind.TypeParameter:
var tp = (ITypeParameterSymbol)type;
return tp.ContainingSymbol is ITypeSymbol cont
? IdDependsOnImpl(cont)
: SymbolEqualityComparer.Default.Equals(tp.ContainingSymbol, symbol);
default:
return false;
}
}
}
return IdDependsOnImpl(dependant);
}
/// <summary>
@@ -130,27 +151,19 @@ namespace Semmle.Extraction.CSharp
/// </summary>
/// <param name="cx">The extraction context.</param>
/// <param name="trapFile">The trap builder used to store the result.</param>
/// <param name="subTermAction">The action to apply to syntactic sub terms of this type.</param>
public static void BuildTypeId(this ITypeSymbol type, Context cx, TextWriter trapFile, Action<Context, TextWriter, ITypeSymbol> subTermAction)
{
if (type.SpecialType != SpecialType.None)
{
/*
* Use the keyword ("int" etc) for the built-in types.
* This makes the IDs shorter and means that all built-in types map to
* the same entities (even when using multiple versions of mscorlib).
*/
trapFile.Write(type.ToDisplayString());
return;
}
/// <param name="symbolBeingDefined">The outer symbol being defined (to avoid recursive ids).</param>
public static void BuildTypeId(this ITypeSymbol type, Context cx, TextWriter trapFile, ISymbol symbolBeingDefined) =>
type.BuildTypeId(cx, trapFile, symbolBeingDefined, true);
static void BuildTypeId(this ITypeSymbol type, Context cx, TextWriter trapFile, ISymbol symbolBeingDefined, bool addBaseClass)
{
using (cx.StackGuard)
{
switch (type.TypeKind)
{
case TypeKind.Array:
var array = (IArrayTypeSymbol)type;
subTermAction(cx, trapFile, array.ElementType);
array.ElementType.BuildOrWriteId(cx, trapFile, symbolBeingDefined, addBaseClass);
array.BuildArraySuffix(trapFile);
return;
case TypeKind.Class:
@@ -160,15 +173,17 @@ namespace Semmle.Extraction.CSharp
case TypeKind.Delegate:
case TypeKind.Error:
var named = (INamedTypeSymbol)type;
named.BuildNamedTypeId(cx, trapFile, subTermAction);
named.BuildNamedTypeId(cx, trapFile, symbolBeingDefined, addBaseClass);
return;
case TypeKind.Pointer:
var ptr = (IPointerTypeSymbol)type;
subTermAction(cx, trapFile, ptr.PointedAtType);
ptr.PointedAtType.BuildOrWriteId(cx, trapFile, symbolBeingDefined, addBaseClass);
trapFile.Write('*');
return;
case TypeKind.TypeParameter:
var tp = (ITypeParameterSymbol)type;
tp.ContainingSymbol.BuildOrWriteId(cx, trapFile, symbolBeingDefined, addBaseClass);
trapFile.Write('_');
trapFile.Write(tp.Name);
return;
case TypeKind.Dynamic:
@@ -180,6 +195,42 @@ namespace Semmle.Extraction.CSharp
}
}
static void BuildOrWriteId(this ISymbol symbol, Context cx, TextWriter trapFile, ISymbol symbolBeingDefined, bool addBaseClass)
{
// We need to keep track of the symbol being defined in order to avoid cyclic labels.
// For example, in
//
// ```csharp
// class C<T> : IEnumerable<T> { }
// ```
//
// when we generate the label for ``C`1``, the base class `IEnumerable<T>` has `T` as a type
// argument, which will be qualified with `__self__` instead of the label we are defining.
// In effect, the label will (simplified) look like
//
// ```
// #123 = @"C`1 : IEnumerable<__self___T>"
// ```
if (SymbolEqualityComparer.Default.Equals(symbol, symbolBeingDefined))
trapFile.Write("__self__");
else if (symbol is ITypeSymbol type && type.IdDependsOn(cx, symbolBeingDefined))
type.BuildTypeId(cx, trapFile, symbolBeingDefined, addBaseClass);
else
trapFile.WriteSubId(CreateEntity(cx, symbol));
}
/// <summary>
/// Adds an appropriate ID to the trap builder <paramref name="trapFile"/>
/// for the symbol <paramref name="symbol"/> belonging to
/// <paramref name="symbolBeingDefined"/>.
///
/// This will either write a reference to the ID of the entity belonging to
/// <paramref name="symbol"/> (`{#label}`), or if that will lead to cyclic IDs,
/// it will generate an appropriate ID that encodes the signature of
/// <paramref name="symbol" />.
/// </summary>
public static void BuildOrWriteId(this ISymbol symbol, Context cx, TextWriter trapFile, ISymbol symbolBeingDefined) =>
symbol.BuildOrWriteId(cx, trapFile, symbolBeingDefined, true);
/// <summary>
/// Constructs an array suffix string for this array type symbol.
@@ -211,11 +262,8 @@ namespace Semmle.Extraction.CSharp
trapFile.Write("::");
}
static void BuildNamedTypeId(this INamedTypeSymbol named, Context cx, TextWriter trapFile, Action<Context, TextWriter, ITypeSymbol> subTermAction)
static void BuildNamedTypeId(this INamedTypeSymbol named, Context cx, TextWriter trapFile, ISymbol symbolBeingDefined, bool addBaseClass)
{
bool prefixAssembly = true;
if (named.ContainingAssembly is null) prefixAssembly = false;
if (named.IsTupleType)
{
trapFile.Write('(');
@@ -224,48 +272,71 @@ namespace Semmle.Extraction.CSharp
{
trapFile.Write(f.Name);
trapFile.Write(":");
subTermAction(cx, tb0, f.Type);
f.Type.BuildOrWriteId(cx, tb0, symbolBeingDefined, addBaseClass);
}
);
trapFile.Write(")");
return;
}
if (named.ContainingType != null)
void AddContaining()
{
subTermAction(cx, trapFile, named.ContainingType);
trapFile.Write('.');
}
else if (named.ContainingNamespace != null)
{
if (prefixAssembly)
BuildAssembly(named.ContainingAssembly, trapFile);
named.ContainingNamespace.BuildNamespace(cx, trapFile);
if (named.ContainingType != null)
{
named.ContainingType.BuildOrWriteId(cx, trapFile, symbolBeingDefined, addBaseClass);
trapFile.Write('.');
}
else if (named.ContainingNamespace != null)
{
if (cx.ShouldAddAssemblyTrapPrefix && named.ContainingAssembly is object)
BuildAssembly(named.ContainingAssembly, trapFile);
named.ContainingNamespace.BuildNamespace(cx, trapFile);
}
}
if (named.IsAnonymousType)
named.BuildAnonymousName(cx, trapFile, subTermAction, true);
else if (named.TypeParameters.IsEmpty)
trapFile.Write(named.Name);
else if (IsReallyUnbound(named))
if (named.TypeParameters.IsEmpty)
{
AddContaining();
trapFile.Write(named.Name);
}
else if (named.IsReallyUnbound())
{
AddContaining();
trapFile.Write(named.Name);
trapFile.Write("`");
trapFile.Write(named.TypeParameters.Length);
}
else
{
subTermAction(cx, trapFile, named.ConstructedFrom);
named.ConstructedFrom.BuildOrWriteId(cx, trapFile, symbolBeingDefined, addBaseClass);
trapFile.Write('<');
// Encode the nullability of the type arguments in the label.
// Type arguments with different nullability can result in
// a constructed type with different nullability of its members and methods,
// so we need to create a distinct database entity for it.
trapFile.BuildList(",", named.GetAnnotatedTypeArguments(),
(ta, tb0) => subTermAction(cx, tb0, ta.Symbol)
(ta, tb0) => ta.Symbol.BuildOrWriteId(cx, tb0, symbolBeingDefined, addBaseClass)
);
trapFile.Write('>');
}
if (addBaseClass && named.GetNonObjectBaseType(cx) is INamedTypeSymbol @base)
{
// We need to limit unfolding of base classes. For example, in
//
// ```csharp
// class C1<T> { }
// class C2<T> : C1<C3<T>> { }
// class C3<T> : C1<C2<T>> { }
// class C4 : C3<C4> { }
// ```
//
// when we generate the label for `C4`, the base class `C3<C4>` has itself `C1<C2<C4>>` as
// a base class, which in turn has `C1<C3<C4>>` as a base class. The latter has the original
// base class `C3<C4>` as a type argument, which would lead to infinite unfolding.
trapFile.Write(" : ");
@base.BuildOrWriteId(cx, trapFile, symbolBeingDefined, addBaseClass: false);
}
}
static void BuildNamespace(this INamespaceSymbol ns, Context cx, TextWriter trapFile)
@@ -274,22 +345,14 @@ namespace Semmle.Extraction.CSharp
trapFile.Write('.');
}
static void BuildAnonymousName(this ITypeSymbol type, Context cx, TextWriter trapFile, Action<Context, TextWriter, ITypeSymbol> subTermAction, bool includeParamName)
static void BuildAnonymousName(this INamedTypeSymbol type, Context cx, TextWriter trapFile)
{
var buildParam = includeParamName
? (prop, tb0) =>
{
tb0.Write(prop.Name);
tb0.Write(' ');
subTermAction(cx, tb0, prop.Type);
}
: (Action<IPropertySymbol, TextWriter>)((prop, tb0) => subTermAction(cx, tb0, prop.Type));
int memberCount = type.GetMembers().OfType<IPropertySymbol>().Count();
int hackTypeNumber = memberCount == 1 ? 1 : 0;
trapFile.Write("<>__AnonType");
trapFile.Write(hackTypeNumber);
trapFile.Write('<');
trapFile.BuildList(",", type.GetMembers().OfType<IPropertySymbol>(), buildParam);
trapFile.BuildList(",", type.GetMembers().OfType<IPropertySymbol>(), (prop, tb0) => BuildDisplayName(prop.Type, cx, tb0));
trapFile.Write('>');
}
@@ -354,11 +417,9 @@ namespace Semmle.Extraction.CSharp
}
if (namedType.IsAnonymousType)
{
namedType.BuildAnonymousName(cx, trapFile, (cx0, tb0, sub) => sub.BuildDisplayName(cx0, tb0), false);
}
trapFile.Write(namedType.Name);
namedType.BuildAnonymousName(cx, trapFile);
else
trapFile.Write(namedType.Name);
if (namedType.IsGenericType && namedType.TypeKind != TypeKind.Error && namedType.TypeArguments.Any())
{
trapFile.Write('<');
@@ -434,6 +495,13 @@ namespace Semmle.Extraction.CSharp
return true;
}
/// <summary>
/// Gets the base type of `symbol`. Unlike `symbol.BaseType`, this excludes effective base
/// types of type parameters as well as `object` base types.
/// </summary>
public static INamedTypeSymbol GetNonObjectBaseType(this ITypeSymbol symbol, Context cx) =>
symbol is ITypeParameterSymbol || SymbolEqualityComparer.Default.Equals(symbol.BaseType, cx.Compilation.ObjectType) ? null : symbol.BaseType;
public static IEntity CreateEntity(this Context cx, ISymbol symbol)
{
if (symbol == null) return null;

View File

@@ -41,43 +41,13 @@ namespace Semmle.Extraction
/// </summary>
public readonly TrapWriter TrapWriter;
/// <summary>
/// Holds if assembly information should be prefixed to TRAP labels.
/// </summary>
public readonly bool ShouldAddAssemblyTrapPrefix;
int GetNewId() => TrapWriter.IdCounter++;
/// <summary>
/// Creates a new entity using the factory.
/// </summary>
/// <param name="factory">The entity factory.</param>
/// <param name="init">The initializer for the entity.</param>
/// <returns>The new/existing entity.</returns>
public Entity CreateEntity<Type, Entity>(ICachedEntityFactory<Type, Entity> factory, Type init) where Entity : ICachedEntity where Type : struct
{
return CreateNonNullEntity(factory, init);
}
/// <summary>
/// Creates a new entity using the factory.
/// </summary>
/// <param name="factory">The entity factory.</param>
/// <param name="init">The initializer for the entity.</param>
/// <returns>The new/existing entity.</returns>
public Entity CreateNullableEntity<Type, Entity>(ICachedEntityFactory<Type, Entity> factory, Type init) where Entity : ICachedEntity
{
return init == null ? CreateEntity2(factory, init) : CreateNonNullEntity(factory, init);
}
/// <summary>
/// Creates a new entity using the factory.
/// </summary>
/// <param name="factory">The entity factory.</param>
/// <param name="init">The initializer for the entity.</param>
/// <returns>The new/existing entity.</returns>
public Entity CreateEntityFromSymbol<Type, Entity>(ICachedEntityFactory<Type, Entity> factory, Type init)
where Entity : ICachedEntity
where Type : ISymbol
{
return init == null ? CreateEntity2(factory, init) : CreateNonNullEntity(factory, init);
}
// A recursion guard against writing to the trap file whilst writing an id to the trap file.
bool WritingLabel = false;
@@ -102,47 +72,6 @@ namespace Semmle.Extraction
}
}
/// <summary>
/// Creates a new entity using the factory.
/// Uses a different cache to <see cref="CreateEntity{Type, Entity}(ICachedEntityFactory{Type, Entity}, Type)"/>,
/// and can store null values.
/// </summary>
/// <param name="factory">The entity factory.</param>
/// <param name="init">The initializer for the entity.</param>
/// <returns>The new/existing entity.</returns>
public Entity CreateEntity2<Type, Entity>(ICachedEntityFactory<Type, Entity> factory, Type init) where Entity : ICachedEntity
{
using (StackGuard)
{
var entity = factory.Create(this, init);
if (entityLabelCache.TryGetValue(entity, out var label))
{
entity.Label = label;
}
else
{
label = GetNewLabel();
entity.Label = label;
entityLabelCache[entity] = label;
DefineLabel(entity, TrapWriter.Writer, Extractor);
if (entity.NeedsPopulation)
Populate(init as ISymbol, entity);
#if DEBUG_LABELS
using (var id = new StringWriter())
{
entity.WriteId(id);
CheckEntityHasUniqueLabel(id.ToString(), entity);
}
#endif
}
return entity;
}
}
#if DEBUG_LABELS
private void CheckEntityHasUniqueLabel(string id, ICachedEntity entity)
{
@@ -159,12 +88,27 @@ namespace Semmle.Extraction
public Label GetNewLabel() => new Label(GetNewId());
public Entity CreateNonNullEntity<Type, Entity>(ICachedEntityFactory<Type, Entity> factory, Type init)
public Entity CreateEntity<Type, Entity>(ICachedEntityFactory<Type, Entity> factory, object cacheKey, Type init)
where Entity : ICachedEntity =>
cacheKey is ISymbol s ? CreateEntity(factory, s, init, symbolEntityCache) : CreateEntity(factory, cacheKey, init, objectEntityCache);
public Entity CreateEntityFromSymbol<Type, Entity>(ICachedEntityFactory<Type, Entity> factory, Type init)
where Type : ISymbol
where Entity : ICachedEntity => CreateEntity(factory, init, init, symbolEntityCache);
/// <summary>
/// Creates and populates a new entity, or returns the existing one from the cache.
/// </summary>
/// <param name="factory">The entity factory.</param>
/// <param name="cacheKey">The key used for caching.</param>
/// <param name="init">The initializer for the entity.</param>
/// <param name="dictionary">The dictionary to use for caching.</param>
/// <returns>The new/existing entity.</returns>
Entity CreateEntity<Type, CacheKeyType, Entity>(ICachedEntityFactory<Type, Entity> factory, CacheKeyType cacheKey, Type init, IDictionary<CacheKeyType, ICachedEntity> dictionary)
where CacheKeyType : notnull
where Entity : ICachedEntity
{
if (init is null) throw new ArgumentException("Unexpected null value", nameof(init));
if (objectEntityCache.TryGetValue(init, out var cached))
if (dictionary.TryGetValue(cacheKey, out var cached))
return (Entity)cached;
using (StackGuard)
@@ -173,7 +117,7 @@ namespace Semmle.Extraction
var entity = factory.Create(this, init);
entity.Label = label;
objectEntityCache[init] = entity;
dictionary[cacheKey] = entity;
DefineLabel(entity, TrapWriter.Writer, Extractor);
if (entity.NeedsPopulation)
@@ -227,8 +171,9 @@ namespace Semmle.Extraction
#if DEBUG_LABELS
readonly Dictionary<string, ICachedEntity> idLabelCache = new Dictionary<string, ICachedEntity>();
#endif
readonly Dictionary<object, ICachedEntity> objectEntityCache = new Dictionary<object, ICachedEntity>();
readonly Dictionary<ICachedEntity, Label> entityLabelCache = new Dictionary<ICachedEntity, Label>();
readonly IDictionary<object, ICachedEntity> objectEntityCache = new Dictionary<object, ICachedEntity>();
readonly IDictionary<ISymbol, ICachedEntity> symbolEntityCache = new Dictionary<ISymbol, ICachedEntity>(10000, SymbolEqualityComparer.IncludeNullability);
readonly HashSet<Label> extractedGenerics = new HashSet<Label>();
/// <summary>
@@ -289,12 +234,14 @@ namespace Semmle.Extraction
/// <param name="c">The Roslyn compilation.</param>
/// <param name="extractedEntity">Name of the source/dll file.</param>
/// <param name="scope">Defines which symbols are included in the trap file (e.g. AssemblyScope or SourceScope)</param>
public Context(IExtractor e, Compilation c, TrapWriter trapWriter, IExtractionScope scope)
/// <param name="addAssemblyTrapPrefix">Whether to add assembly prefixes to TRAP labels.</param>
public Context(IExtractor e, Compilation c, TrapWriter trapWriter, IExtractionScope scope, bool addAssemblyTrapPrefix)
{
Extractor = e;
Compilation = c;
Scope = scope;
TrapWriter = trapWriter;
ShouldAddAssemblyTrapPrefix = addAssemblyTrapPrefix;
}
public bool FromSource => Scope.FromSource;
@@ -423,8 +370,8 @@ namespace Semmle.Extraction
throw new InternalError("Unexpected TrapStackBehaviour");
}
var a = duplicationGuard ?
(Action)(() => WithDuplicationGuard(new Key(entity, this.Create(entity.ReportingLocation)), () => entity.Populate(TrapWriter.Writer))) :
var a = duplicationGuard && this.Create(entity.ReportingLocation) is NonGeneratedSourceLocation loc ?
(Action)(() => WithDuplicationGuard(new Key(entity, loc), () => entity.Populate(TrapWriter.Writer))) :
(Action)(() => this.Try(null, optionalSymbol, () => entity.Populate(TrapWriter.Writer)));
if (deferred)

View File

@@ -50,7 +50,7 @@ namespace Semmle.Extraction.Entities
return Equals(symbol, other.symbol);
}
public new static Location Create(Context cx, Microsoft.CodeAnalysis.Location? loc) => AssemblyConstructorFactory.Instance.CreateNullableEntity(cx, loc);
public new static Location Create(Context cx, Microsoft.CodeAnalysis.Location loc) => AssemblyConstructorFactory.Instance.CreateEntity(cx, loc, loc);
class AssemblyConstructorFactory : ICachedEntityFactory<Microsoft.CodeAnalysis.Location?, Assembly>
{
@@ -59,11 +59,12 @@ namespace Semmle.Extraction.Entities
public Assembly Create(Context cx, Microsoft.CodeAnalysis.Location? init) => new Assembly(cx, init);
}
static readonly object outputAssemblyCacheKey = new object();
public static Location CreateOutputAssembly(Context cx)
{
if (cx.Extractor.OutputPath == null)
throw new InternalError("Attempting to create the output assembly in standalone extraction mode");
return AssemblyConstructorFactory.Instance.CreateNullableEntity(cx, null);
return AssemblyConstructorFactory.Instance.CreateEntity(cx, outputAssemblyCacheKey, null);
}
public override void WriteId(System.IO.TextWriter trapFile)

View File

@@ -89,7 +89,7 @@ namespace Semmle.Extraction.Entities
public static string PathAsDatabaseString(string path) => path.Replace('\\', '/');
public static File Create(Context cx, string path) => FileFactory.Instance.CreateEntity(cx, path);
public static File Create(Context cx, string path) => FileFactory.Instance.CreateEntity(cx, (typeof(File), path), path);
public static File CreateGenerated(Context cx) => GeneratedFile.Create(cx);
@@ -111,7 +111,7 @@ namespace Semmle.Extraction.Entities
}
public static GeneratedFile Create(Context cx) =>
GeneratedFileFactory.Instance.CreateNullableEntity(cx, null);
GeneratedFileFactory.Instance.CreateEntity(cx, typeof(GeneratedFile), null);
class GeneratedFileFactory : ICachedEntityFactory<string?, GeneratedFile>
{

View File

@@ -43,7 +43,7 @@ namespace Semmle.Extraction.Entities
}
public static Folder Create(Context cx, DirectoryInfo folder) =>
FolderFactory.Instance.CreateEntity2(cx, folder);
FolderFactory.Instance.CreateEntity(cx, folder, folder);
public override Microsoft.CodeAnalysis.Location? ReportingLocation => null;

View File

@@ -28,7 +28,7 @@ namespace Semmle.Extraction.Entities
public override bool Equals(object? obj) => obj != null && obj.GetType() == typeof(GeneratedLocation);
public static GeneratedLocation Create(Context cx) => GeneratedLocationFactory.Instance.CreateNullableEntity(cx, null);
public static GeneratedLocation Create(Context cx) => GeneratedLocationFactory.Instance.CreateEntity(cx, typeof(GeneratedLocation), null);
class GeneratedLocationFactory : ICachedEntityFactory<string?, GeneratedLocation>
{

View File

@@ -23,7 +23,7 @@ namespace Semmle.Extraction.Entities
FileEntity = File.Create(Context, Position.Path);
}
public new static Location Create(Context cx, Microsoft.CodeAnalysis.Location? loc) => SourceLocationFactory.Instance.CreateNullableEntity(cx, loc);
public new static Location Create(Context cx, Microsoft.CodeAnalysis.Location loc) => SourceLocationFactory.Instance.CreateEntity(cx, loc, loc);
public override void Populate(TextWriter trapFile)
{
@@ -55,11 +55,11 @@ namespace Semmle.Extraction.Entities
trapFile.Write(Position.Span.End.Character);
}
class SourceLocationFactory : ICachedEntityFactory<Microsoft.CodeAnalysis.Location?, SourceLocation>
class SourceLocationFactory : ICachedEntityFactory<Microsoft.CodeAnalysis.Location, SourceLocation>
{
public static readonly SourceLocationFactory Instance = new SourceLocationFactory();
public SourceLocation Create(Context cx, Microsoft.CodeAnalysis.Location? init) => new NonGeneratedSourceLocation(cx, init);
public SourceLocation Create(Context cx, Microsoft.CodeAnalysis.Location init) => new NonGeneratedSourceLocation(cx, init);
}
}
}

View File

@@ -109,41 +109,33 @@ namespace Semmle.Extraction
public static class ICachedEntityFactoryExtensions
{
public static Entity CreateEntity<Entity, T1, T2>(this ICachedEntityFactory<(T1, T2), Entity> factory, Context cx, T1 t1, T2 t2)
where Entity : ICachedEntity => factory.CreateEntity2(cx, (t1, t2));
public static Entity CreateEntity<Entity, T1, T2, T3>(this ICachedEntityFactory<(T1, T2, T3), Entity> factory, Context cx, T1 t1, T2 t2, T3 t3)
where Entity : ICachedEntity => factory.CreateEntity2(cx, (t1, t2, t3));
public static Entity CreateEntity<Entity, T1, T2, T3, T4>(this ICachedEntityFactory<(T1, T2, T3, T4), Entity> factory, Context cx, T1 t1, T2 t2, T3 t3, T4 t4)
where Entity : ICachedEntity => factory.CreateEntity2(cx, (t1, t2, t3, t4));
/// <summary>
/// Creates and populates a new entity, or returns the existing one from the cache,
/// based on the supplied cache key.
/// </summary>
/// <typeparam name="Type">The type used to construct the entity.</typeparam>
/// <typeparam name="Entity">The type of the entity to create.</typeparam>
/// <param name="factory">The factory used to construct the entity.</param>
/// <param name="cx">The extractor context.</param>
/// <param name="cacheKey">The key used for caching.</param>
/// <param name="init">The initializer for the entity.</param>
/// <returns>The entity.</returns>
public static Entity CreateEntity<Type, Entity>(this ICachedEntityFactory<Type, Entity> factory, Context cx, object cacheKey, Type init)
where Entity : ICachedEntity => cx.CreateEntity(factory, cacheKey, init);
/// <summary>
/// Creates and populates a new entity, or returns the existing one from the cache.
/// Creates and populates a new entity from an `ISymbol`, or returns the existing one
/// from the cache.
/// </summary>
/// <typeparam name="Type">The symbol type used to construct the entity.</typeparam>
/// <typeparam name="Type">The type used to construct the entity.</typeparam>
/// <typeparam name="Entity">The type of the entity to create.</typeparam>
/// <param name="cx">The extractor context.</param>
/// <param name="factory">The factory used to construct the entity.</param>
/// <param name="init">The initializer for the entity, which may not be null.</param>
/// <returns>The entity.</returns>
public static Entity CreateEntity<Type, Entity>(this ICachedEntityFactory<Type, Entity> factory, Context cx, Type init) where Type : notnull
where Entity : ICachedEntity => cx.CreateNonNullEntity(factory, init);
public static Entity CreateNullableEntity<Type, Entity>(this ICachedEntityFactory<Type, Entity> factory, Context cx, Type init)
where Entity : ICachedEntity => cx.CreateNullableEntity(factory, init);
/// <summary>
/// Creates and populates a new entity, but uses a different cache.
/// </summary>
/// <typeparam name="Type">The symbol type used to construct the entity.</typeparam>
/// <typeparam name="Entity">The type of the entity to create.</typeparam>
/// <param name="cx">The extractor context.</param>
/// <param name="factory">The factory used to construct the entity.</param>
/// <param name="init">The initializer for the entity, which may be null.</param>
/// <param name="init">The initializer for the entity.</param>
/// <returns>The entity.</returns>
public static Entity CreateEntity2<Type, Entity>(this ICachedEntityFactory<Type, Entity> factory, Context cx, Type init)
where Entity : ICachedEntity => cx.CreateEntity2(factory, init);
public static Entity CreateEntityFromSymbol<Type, Entity>(this ICachedEntityFactory<Type, Entity> factory, Context cx, Type init)
where Type : ISymbol
where Entity : ICachedEntity => cx.CreateEntityFromSymbol(factory, init);
public static void DefineLabel(this IEntity entity, TextWriter trapFile, IExtractor extractor)
{
@@ -156,7 +148,7 @@ namespace Semmle.Extraction
catch (Exception ex) // lgtm[cs/catch-of-all-exceptions]
{
trapFile.WriteLine("\"");
extractor.Message(new Message("Unhandled exception generating id", entity.ToString() ?? "", null, ex.StackTrace));
extractor.Message(new Message($"Unhandled exception generating id: {ex.Message}", entity.ToString() ?? "", null, ex.StackTrace));
}
trapFile.WriteLine();
}

View File

@@ -87,8 +87,9 @@ namespace Semmle.Extraction
/// <param name="c">The C# compilation.</param>
/// <param name="trapWriter">The trap writer.</param>
/// <param name="scope">The extraction scope (what to include in this trap file).</param>
/// <param name="addAssemblyTrapPrefix">Whether to add assembly prefixes to TRAP labels.</param>
/// <returns></returns>
Context CreateContext(Compilation c, TrapWriter trapWriter, IExtractionScope scope);
Context CreateContext(Compilation c, TrapWriter trapWriter, IExtractionScope scope, bool addAssemblyTrapPrefix);
}
/// <summary>
@@ -187,9 +188,9 @@ namespace Semmle.Extraction
}
}
public Context CreateContext(Compilation c, TrapWriter trapWriter, IExtractionScope scope)
public Context CreateContext(Compilation c, TrapWriter trapWriter, IExtractionScope scope, bool addAssemblyTrapPrefix)
{
return new Context(this, c, trapWriter, scope);
return new Context(this, c, trapWriter, scope, addAssemblyTrapPrefix);
}
public IEnumerable<string> MissingTypes => missingTypes;

View File

@@ -69,7 +69,6 @@ namespace Semmle.Extraction
}
else
TrapBuilder.Write(arg.ToString());
}
}

View File

@@ -1,4 +1,5 @@
using System.IO;
using Microsoft.CodeAnalysis;
namespace Semmle.Extraction
{
@@ -65,16 +66,6 @@ namespace Semmle.Extraction
get;
}
/// <summary>
/// Runs the given action <paramref name="a"/>, guarding for trap duplication
/// based on the ID an location of this entity.
/// </summary>
protected void WithDuplicationGuard(System.Action a, IEntity location)
{
var key = new Key(this, location);
Context.WithDuplicationGuard(key, a);
}
public override int GetHashCode() => symbol is null ? 0 : symbol.GetHashCode();
public override bool Equals(object? obj)
@@ -85,4 +76,20 @@ namespace Semmle.Extraction
public abstract TrapStackBehaviour TrapStackBehaviour { get; }
}
/// <summary>
/// A class used to wrap an `ISymbol` object, which uses `SymbolEqualityComparer.Default`
/// for comparison.
/// </summary>
public sealed class SymbolEqualityWrapper
{
public ISymbol Symbol { get; }
public SymbolEqualityWrapper(ISymbol symbol) { Symbol = symbol; }
public override bool Equals(object? other) =>
other is SymbolEqualityWrapper sew && SymbolEqualityComparer.Default.Equals(Symbol, sew.Symbol);
public override int GetHashCode() => 11 * Symbol.GetHashCode();
}
}

View File

@@ -31,7 +31,7 @@ class StaticCall extends Call {
}
/** Holds `t` has instance callable `c` as a member, with name `name`. */
pragma[noinline]
pragma[nomagic]
predicate hasInstanceCallable(ValueOrRefType t, InstanceCallable c, string name) {
t.hasMember(c) and
name = c.getName()

View File

@@ -7,6 +7,7 @@
*/
import csharp
private import TypeRef
private module Annotations {
newtype TAnnotation =

View File

@@ -4,6 +4,7 @@
import Type
private import semmle.code.csharp.ExprOrStmtParent
private import TypeRef
/**
* An element that can have attributes. Either an assembly (`Assembly`), a field (`Field`),

View File

@@ -3,13 +3,14 @@
* such as methods and operators.
*/
import Type
import Member
import Stmt
import Type
import exprs.Call
private import dotnet
private import semmle.code.csharp.ExprOrStmtParent
private import semmle.code.csharp.metrics.Complexity
private import TypeRef
/**
* An element that can be called.
@@ -31,23 +32,15 @@ class Callable extends DotNet::Callable, Parameterizable, ExprOrStmtParent, @cal
* Gets the body of this callable, if any.
*
* The body is either a `BlockStmt` or an `Expr`.
*/
final ControlFlowElement getBody() {
result = this.getStatementBody() or
result = this.getExpressionBody()
}
/**
* Gets a body of this callable, if any.
*
* Unlike `getBody()`, this predicate may return multiple bodies, in the case
* where the same callable is compiled multiple times. For example, if we
* compile both `A.cs`
* Normally, each callable will have at most one body, except in the case where
* the same callable is compiled multiple times. For example, if we compile
* both `A.cs`
*
* ```csharp
* namespaces N {
* public class C {
* public int M() => 0;
* public int M() { return 0; }
* }
* }
* ```
@@ -57,19 +50,24 @@ class Callable extends DotNet::Callable, Parameterizable, ExprOrStmtParent, @cal
* ```csharp
* namespaces N {
* public class C {
* public int M() { return 1; }
* public int M() => 1;
* }
* }
* ```
*
* to the same assembly, then both `0` and `{ return 1; }` are bodies of `N.C.M()`.
* then both `{ return 0; }` and `1` are bodies of `N.C.M()`.
*/
final ControlFlowElement getABody() {
result = this.getAStatementBody() or
result = this.getAnExpressionBody()
final ControlFlowElement getBody() {
result = this.getStatementBody() or
result = this.getExpressionBody()
}
override predicate hasBody() { exists(getBody()) }
/**
* DEPRECATED: Use `getBody()` instead.
*/
deprecated final ControlFlowElement getABody() { result = this.getBody() }
override predicate hasBody() { exists(this.getBody()) }
/**
* Holds if this callable has a non-empty body. That is, either it has
@@ -78,19 +76,15 @@ class Callable extends DotNet::Callable, Parameterizable, ExprOrStmtParent, @cal
predicate hasNonEmptyBody() {
this.hasExpressionBody()
or
this.hasStatementBody() and
not this.getStatementBody().stripSingletonBlocks().(BlockStmt).isEmpty()
this.getStatementBody().stripSingletonBlocks() = any(Stmt s | not s.(BlockStmt).isEmpty())
}
/** Gets the statement body of this callable, if any. */
final BlockStmt getStatementBody() { result = this.getAChildStmt() }
/**
* Gets a statement body of this callable, if any.
* Gets the statement body of this callable, if any.
*
* Unlike `getStatementBody()`, this predicate may return multiple bodies, in
* the case where the same callable is compiled multiple times. For example,
* if we compile both `A.cs`
* Normally, each callable will have at most one statement body, except in the
* case where the same callable is compiled multiple times. For example, if
* we compile both `A.cs`
*
* ```csharp
* namespaces N {
@@ -110,23 +104,25 @@ class Callable extends DotNet::Callable, Parameterizable, ExprOrStmtParent, @cal
* }
* ```
*
* to the same assembly, then both `{ return 0; }` and `{ return 1; }` are
* statement bodies of `N.C.M()`.
* then both `{ return 0; }` and `{ return 1; }` are statement bodies of
* `N.C.M()`.
*/
final BlockStmt getAStatementBody() { stmt_parent_top_level(result, _, this) }
final BlockStmt getStatementBody() { result = this.getAChildStmt() }
/**
* DEPRECATED: Use `getStatementBody` instead.
*/
final BlockStmt getAStatementBody() { result = this.getStatementBody() }
/** Holds if this callable has a statement body. */
final predicate hasStatementBody() { exists(getStatementBody()) }
/** Gets the expression body of this callable (if any), specified by `=>`. */
final Expr getExpressionBody() { result = this.getChildExpr(0) }
/**
* Gets an expression body of this callable (if any), specified by `=>`.
* Gets the expression body of this callable (if any), specified by `=>`.
*
* Unlike `getExpressionBody()`, this predicate may return multiple bodies, in
* the case where the same callable is compiled multiple times. For example,
* if we compile both `A.cs`
* Normally, each callable will have at most one expression body, except in the
* case where the same callable is compiled multiple times. For example, if
* we compile both `A.cs`
*
* ```csharp
* namespaces N {
@@ -146,9 +142,17 @@ class Callable extends DotNet::Callable, Parameterizable, ExprOrStmtParent, @cal
* }
* ```
*
* to the same assembly, then both `0` and `1` are expression bodies of `N.C.M()`.
* then both `0` and `1` are expression bodies of `N.C.M()`.
*/
final Expr getAnExpressionBody() { expr_parent_top_level_adjusted(result, 0, this) }
final Expr getExpressionBody() {
result = this.getAChildExpr() and
not result = this.(Constructor).getInitializer()
}
/**
* DEPRECATED: Use `getExpressionBody()` instead.
*/
deprecated final Expr getAnExpressionBody() { result = this.getExpressionBody() }
/** Holds if this callable has an expression body. */
final predicate hasExpressionBody() { exists(getExpressionBody()) }

View File

@@ -4,6 +4,7 @@
import Member
import Type
private import TypeRef
/**
* An event, for example `E` on line 3 in

View File

@@ -6,74 +6,6 @@
import csharp
/**
* INTERNAL: Do not use.
*
* The `expr_parent_top_level()` relation extended to include a relation
* between getters and expression bodies in properties such as `int P => 0`.
*/
predicate expr_parent_top_level_adjusted(Expr child, int i, @top_level_exprorstmt_parent parent) {
expr_parent_top_level(child, i, parent)
or
parent = any(Getter g | expr_parent_top_level(child, i, g.getDeclaration())) and
i = 0
}
/**
* The `expr_parent()` relation adjusted for expandable assignments. For example,
* the assignment `x += y` is extracted as
*
* ```
* +=
* |
* 2
* |
* =
* / \
* 1 0
* / \
* x +
* / \
* 1 0
* / \
* x y
* ```
*
* in order to be able to retrieve the expanded assignment `x = x + y` as the 2nd
* child. This predicate changes the diagram above into
*
* ```
* +=
* / \
* 1 0
* / \
* x y
* ```
*/
private predicate expr_parent_adjusted(Expr child, int i, ControlFlowElement parent) {
if parent instanceof AssignOperation
then
parent =
any(AssignOperation ao |
exists(AssignExpr ae | ae = ao.getExpandedAssignment() |
i = 0 and
exists(Expr right |
// right = `x + y`
expr_parent(right, 0, ae)
|
expr_parent(child, 1, right)
)
or
i = 1 and
expr_parent(child, 1, ae)
)
or
not ao.hasExpandedAssignment() and
expr_parent(child, i, parent)
)
else expr_parent(child, i, parent)
}
/**
* INTERNAL: Do not use.
*
@@ -88,7 +20,7 @@ class ExprOrStmtParent extends Element, @exprorstmt_parent {
/** Gets the `i`th child expression of this element (zero-based). */
final Expr getChildExpr(int i) {
expr_parent_adjusted(result, i, this) or
result = getTopLevelChild(this, i)
expr_parent_top_level_adjusted(result, i, this)
}
/** Gets a child expression of this element, if any. */
@@ -97,7 +29,7 @@ class ExprOrStmtParent extends Element, @exprorstmt_parent {
/** Gets the `i`th child statement of this element (zero-based). */
final Stmt getChildStmt(int i) {
stmt_parent(result, i, this) or
result = getTopLevelChild(this, i)
stmt_parent_top_level(result, i, this)
}
/** Gets a child statement of this element, if any. */
@@ -113,242 +45,19 @@ class TopLevelExprParent extends Element, @top_level_expr_parent {
final override Expr getChild(int i) { result = this.getChildExpr(i) }
/** Gets the `i`th child expression of this element (zero-based). */
final Expr getChildExpr(int i) { result = getTopLevelChild(this, i) }
final Expr getChildExpr(int i) { expr_parent_top_level_adjusted(result, i, this) }
/** Gets a child expression of this element, if any. */
final Expr getAChildExpr() { result = this.getChildExpr(_) }
}
/**
* INTERNAL: Do not use.
*
* An element that can have a child statement or expression, and where we have
* encountered multiple potential implementations at compile-time. For example,
* if we compile both `A.cs`
*
* ```csharp
* namespaces N {
* public class C {
* public int M() => 0;
* }
* }
* ```
*
* and later `B.cs`
*
* ```csharp
* namespaces N {
* public class C {
* public int M() => 1;
* }
* }
* ```
*
* then the method `N.C.M` has two implementations, returning `0` and `1`,
* respectively.
*
* The implementation used at run-time is in this case unknown (indeed, it could
* be a third implementation not encountered during compilation), so we make a
* guess for the "most likely" implementation in `getBestChild()`.
*/
class MultiImplementationsParent extends ExprOrStmtParent {
MultiImplementationsParent() {
exists(int i |
strictcount(File f |
exists(ControlFlowElement implementation, Location l | f = l.getFile() |
stmt_parent_top_level(implementation, i, this) and
stmt_location(implementation, l)
or
expr_parent_top_level_adjusted(implementation, i, this) and
expr_location(implementation, l)
)
or
hasAccessorAutoImplementation(this, f) and
i = 0
) > 1
)
}
/**
* Gets a file that contains an implementation `cfe` for the `i`th child of this
* element.
*/
private File getAnImplementation(int i, ControlFlowElement cfe) {
exists(Location l | result = l.getFile() |
stmt_parent_top_level(cfe, i, this) and
stmt_location(cfe, l)
or
expr_parent_top_level_adjusted(cfe, i, this) and
expr_location(cfe, l)
)
}
/**
* Gets a file that contains an implementation `cfe` for the `i`th child of this
* element, where `t` is the top-level type containing this element (that is,
* `t` is not a nested type).
*/
File getAnImplementationInTopLevelType(int i, ControlFlowElement cfe, ValueOrRefType t) {
result = this.getAnImplementation(i, cfe) and
t = getTopLevelDeclaringType(this)
}
/**
* Gets a file that contains an auto-implementation for this element, where
* `t` is the top-level type containing this element (that is, `t` is not a
* nested type).
*/
File getAnAutoImplementationFileInTopLevelType(ValueOrRefType t) {
hasAccessorAutoImplementation(this, result) and
t = getTopLevelDeclaringType(this)
}
private File getAnImplementationFileInTopLevelType(int i, ValueOrRefType t) {
result = getAnImplementationInTopLevelType(i, _, t)
or
result = this.getAnAutoImplementationFileInTopLevelType(t) and
i = 0
}
/**
* Gets the file containing the "best" implementation of this element, that is, the
* file considered most likely to contain the actual run-time implementation.
*
* The heuristics we use is to choose the implementation belonging to the top-level type
* with the most control flow elements (excluding `throw` elements). In the case of a tie,
* we arbitrarily choose the implementation belonging to the last file (in lexicographic
* order).
*
* By counting elements for the top-level type, we ensure that all definitions belonging
* to the same top-level type will get implementations belonging to the same file.
*/
File getBestFile() {
exists(ValueOrRefType t |
result =
max(this.getAnImplementationFileInTopLevelType(_, t) as file
order by
getImplementationSize(t, file), file.toString()
)
)
}
/**
* Gets the i`th child of this element. Only the "best" child among all the possible
* run-time implementations is returned, namely the child considered most likely to
* be the actual run-time implementation.
*/
ControlFlowElement getBestChild(int i) {
exists(File f, ValueOrRefType t | f = getBestFile() |
f = this.getAnImplementationInTopLevelType(i, result, t)
)
}
}
/** Gets the top-level type containing declaration `d`. */
private ValueOrRefType getTopLevelDeclaringType(Declaration d) {
result = getDeclaringType+(d) and
not result instanceof NestedType
}
/** Gets the declaring type of element `e`. */
private ValueOrRefType getDeclaringType(Declaration d) {
methods(d, _, result, _, _)
or
constructors(d, _, result, _)
or
destructors(d, _, result, _)
or
operators(d, _, _, result, _, _)
or
properties(d, _, result, _, _)
or
indexers(d, _, result, _, _)
or
nested_types(d, result, _)
or
fields(d, _, _, result, _, _)
or
exists(DeclarationWithAccessors decl | d = decl.getAnAccessor() | result = getDeclaringType(decl))
or
exists(Parameterizable p | params(d, _, _, _, _, p, _) | result = getDeclaringType(p))
}
private ControlFlowElement getAChild(ControlFlowElement cfe) {
expr_parent_adjusted(result, _, cfe) or
stmt_parent(result, _, cfe)
}
private int getImplementationSize0(ValueOrRefType t, File f) {
result =
strictcount(ControlFlowElement cfe |
exists(MultiImplementationsParent p, ControlFlowElement child |
cfe = getAChild*(child) and
not cfe = getAChild*(any(ThrowElement te))
|
f = p.getAnImplementationInTopLevelType(_, child, t)
or
// Merge stats for partial implementations belonging to the same folder
t.isPartial() and
f = p.getAnImplementationInTopLevelType(_, _, t) and
exists(File fOther, MultiImplementationsParent pOther |
f.getParentContainer() = fOther.getParentContainer()
|
fOther = pOther.getAnImplementationInTopLevelType(_, child, t)
)
)
)
}
private int getImplementationSize1(ValueOrRefType t, File f) {
result =
strictsum(MultiImplementationsParent p, int c |
// Count each auto-implemented accessor as size 4 (getter) or 5 (setter)
f = p.getAnAutoImplementationFileInTopLevelType(t) and
if p instanceof Getter then c = 4 else c = 5
|
c
)
}
private int getImplementationSize(ValueOrRefType t, File f) {
if exists(getImplementationSize0(t, f))
then
if exists(getImplementationSize1(t, f))
then result = getImplementationSize0(t, f) + getImplementationSize1(t, f)
else result = getImplementationSize0(t, f)
else result = getImplementationSize1(t, f)
}
/**
* Holds if declaration `d` should have a location in file `f`, because it is part of a
* type with multiple implementations, where the most likely run-time implementation is
* in `f`.
*/
private predicate mustHaveLocationInFile(Declaration d, File f) {
exists(MultiImplementationsParent p, ValueOrRefType t |
t = getTopLevelDeclaringType(p) and
f = p.getBestFile()
|
t = getTopLevelDeclaringType(d) or d = t or d = p
)
}
private predicate hasNoSourceLocation(Element e) { not e.getALocation() instanceof SourceLocation }
cached
private module Cached {
cached
ControlFlowElement getTopLevelChild(ExprOrStmtParent p, int i) {
result = p.(MultiImplementationsParent).getBestChild(i)
or
not p instanceof MultiImplementationsParent and
(stmt_parent_top_level(result, i, p) or expr_parent_top_level_adjusted(result, i, p))
}
cached
Location bestLocation(Element e) {
result = e.getALocation().(SourceLocation) and
(mustHaveLocationInFile(e, _) implies mustHaveLocationInFile(e, result.getFile()))
result = e.getALocation().(SourceLocation)
or
hasNoSourceLocation(e) and
result = min(Location l | l = e.getALocation() | l order by l.getFile().toString())
@@ -360,20 +69,71 @@ private module Cached {
/**
* INTERNAL: Do not use.
*
* Holds if accessor `a` has an auto-implementation in file `f`.
* The `expr_parent_top_level()` relation extended to include a relation
* between getters and expression bodies in properties such as `int P => 0`.
*/
cached
predicate hasAccessorAutoImplementation(Accessor a, File f) {
exists(SourceLocation sl | sl = a.getALocation() |
f = sl.getFile() and
not exists(ControlFlowElement cfe, Location l | sl.getFile() = l.getFile() |
stmt_parent_top_level(cfe, _, a) and
stmt_location(cfe, l)
or
expr_parent_top_level_adjusted(cfe, 0, a) and
expr_location(cfe, l)
)
)
predicate expr_parent_top_level_adjusted(Expr child, int i, @top_level_exprorstmt_parent parent) {
expr_parent_top_level(child, i, parent)
or
parent = any(Getter g | expr_parent_top_level(child, i, g.getDeclaration())) and
i = 0
}
/**
* The `expr_parent()` relation adjusted for expandable assignments. For example,
* the assignment `x += y` is extracted as
*
* ```
* +=
* |
* 2
* |
* =
* / \
* 1 0
* / \
* x +
* / \
* 1 0
* / \
* x y
* ```
*
* in order to be able to retrieve the expanded assignment `x = x + y` as the 2nd
* child. This predicate changes the diagram above into
*
* ```
* +=
* / \
* 1 0
* / \
* x y
* ```
*/
cached
predicate expr_parent_adjusted(Expr child, int i, ControlFlowElement parent) {
if parent instanceof AssignOperation
then
parent =
any(AssignOperation ao |
exists(AssignExpr ae | ae = ao.getExpandedAssignment() |
i = 0 and
exists(Expr right |
// right = `x + y`
expr_parent(right, 0, ae)
|
expr_parent(child, 1, right)
)
or
i = 1 and
expr_parent(child, 1, ae)
)
or
not ao.hasExpandedAssignment() and
expr_parent(child, i, parent)
)
else expr_parent(child, i, parent)
}
}

View File

@@ -16,6 +16,7 @@
import Location
import Namespace
private import dotnet
private import TypeRef
/**
* A generic declaration. Either an unbound generic (`UnboundGeneric`) or a

View File

@@ -1,11 +1,12 @@
/** Provides classes relating to declarations and type members. */
import Element
import Variable
import Callable
import Element
import Modifier
private import Implements
import Variable
private import dotnet
private import Implements
private import TypeRef
/**
* A declaration.

View File

@@ -2,12 +2,13 @@
* Provides classes for properties, indexers, and accessors.
*/
import Type
import Member
import Stmt
private import semmle.code.csharp.ExprOrStmtParent
private import dotnet
import Type
private import cil
private import dotnet
private import semmle.code.csharp.ExprOrStmtParent
private import TypeRef
/**
* A declaration that may have accessors. Either an event (`Event`), a property

View File

@@ -4,12 +4,13 @@
* All statements have the common base class `Stmt`.
*/
import Location
import Element
import Location
import Member
import exprs.Expr
private import semmle.code.csharp.Enclosing::Internal
private import semmle.code.csharp.frameworks.System
private import TypeRef
/**
* A statement.

View File

@@ -1,14 +1,15 @@
/** Provides classes for types. */
import Location
import Namespace
import Callable
import Property
import Event
import Generics
import Location
import Namespace
import Property
private import Conversion
private import semmle.code.csharp.metrics.Coupling
private import dotnet
private import semmle.code.csharp.metrics.Coupling
private import TypeRef
/**
* A type.
@@ -45,6 +46,9 @@ class Type extends DotNet::Type, Member, TypeContainer, @type {
predicate isValueType() { none() }
}
pragma[nomagic]
private predicate isObjectClass(Class c) { c instanceof ObjectType }
/**
* A value or reference type.
*
@@ -111,7 +115,15 @@ class ValueOrRefType extends DotNet::ValueOrRefType, Type, Attributable, @value_
}
/** Gets the immediate base class of this class, if any. */
Class getBaseClass() { extend(this, getTypeRef(result)) }
final Class getBaseClass() {
extend(this, getTypeRef(result))
or
not extend(this, _) and
not isObjectClass(this) and
not this instanceof DynamicType and
not this instanceof NullType and
isObjectClass(result)
}
/** Gets an immediate base interface of this type, if any. */
Interface getABaseInterface() { implement(this, getTypeRef(result)) }
@@ -1002,15 +1014,3 @@ class TypeMention extends @type_mention {
/** Gets the location of this type mention. */
Location getLocation() { type_mention_location(this, result) }
}
/**
* INTERNAL: Do not use.
* Gets a type reference for a given type `type`.
* This is used for extensionals that can be supplied
* as either type references or types.
*/
@type_or_ref getTypeRef(@type type) {
result = type
or
typeref_type(result, type)
}

View File

@@ -0,0 +1,29 @@
/**
* INTERNAL: Do not use.
*
* Provides support for type-references.
*/
import csharp
/** A typeref is a reference to a type in some assembly. */
private class TypeRef extends @typeref {
string getName() { typerefs(this, result) }
string toString() { result = this.getName() }
Type getReferencedType() { typeref_type(this, result) }
}
/**
* INTERNAL: Do not use.
*
* Gets a type reference for a given type `type`.
* This is used for extensionals that can be supplied
* as either type references or types.
*/
@type_or_ref getTypeRef(Type type) {
result = type
or
result.(TypeRef).getReferencedType() = type
}

View File

@@ -5,6 +5,7 @@
*/
import Element
private import TypeRef
/**
* A `using` directive. Either a namespace `using` directive

View File

@@ -3,12 +3,13 @@
* constants.
*/
import Element
import Callable
import Type
import Assignable
import Callable
import Element
import Type
private import dotnet
private import semmle.code.csharp.ExprOrStmtParent
private import TypeRef
/**
* A variable. Either a variable with local scope (`LocalScopeVariable`) or a field (`Field`).

View File

@@ -288,7 +288,7 @@ class ForwarderAssertMethod extends AssertMethod {
ForwarderAssertMethod() {
p = this.getAParameter() and
strictcount(AssignableDefinition def | def.getTarget() = p) = 1 and
forex(ControlFlowElement body | body = this.getABody() |
forex(ControlFlowElement body | body = this.getBody() |
bodyAsserts(this, body, a) and
a.getExpr() = p.getAnAccess()
)
@@ -306,7 +306,7 @@ class ForwarderAssertMethod extends AssertMethod {
pragma[noinline]
private predicate bodyAsserts(Callable c, ControlFlowElement body, Assertion a) {
c.getABody() = body and
c.getBody() = body and
body = getAnAssertingElement(a)
}

View File

@@ -55,10 +55,13 @@ private class ThrowingCall extends NonReturningCall {
override ThrowCompletion getACompletion() { result = c }
}
/** Holds if accessor `a` has an auto-implementation. */
private predicate hasAccessorAutoImplementation(Accessor a) { not a.hasBody() }
abstract private class NonReturningCallable extends Callable {
NonReturningCallable() {
not exists(ReturnStmt ret | ret.getEnclosingCallable() = this) and
not hasAccessorAutoImplementation(this, _) and
not hasAccessorAutoImplementation(this) and
not exists(Virtualizable v | v.isOverridableOrImplementable() |
v = this or
v = this.(Accessor).getDeclaration()
@@ -80,7 +83,7 @@ private class DirectlyExitingCallable extends ExitingCallable {
private class IndirectlyExitingCallable extends ExitingCallable {
IndirectlyExitingCallable() {
forex(ControlFlowElement body | body = this.getABody() | body = getAnExitingElement())
forex(ControlFlowElement body | body = this.getBody() | body = getAnExitingElement())
}
}
@@ -104,11 +107,11 @@ private Stmt getAnExitingStmt() {
private class ThrowingCallable extends NonReturningCallable {
ThrowingCallable() {
forex(ControlFlowElement body | body = this.getABody() | body = getAThrowingElement(_))
forex(ControlFlowElement body | body = this.getBody() | body = getAThrowingElement(_))
}
/** Gets a valid completion for a call to this throwing callable. */
ThrowCompletion getACallCompletion() { this.getABody() = getAThrowingElement(result) }
ThrowCompletion getACallCompletion() { this.getBody() = getAThrowingElement(result) }
}
private predicate directlyThrows(ThrowElement te, ThrowCompletion c) {

View File

@@ -4,10 +4,6 @@
* All expressions have the common base class `Expr`.
*/
import semmle.code.csharp.Location
import semmle.code.csharp.Stmt
import semmle.code.csharp.Callable
import semmle.code.csharp.Type
import Access
import ArithmeticOperation
import Assignment
@@ -19,9 +15,14 @@ import Dynamic
import Literal
import LogicalOperation
import semmle.code.csharp.controlflow.ControlFlowElement
import semmle.code.csharp.Callable
import semmle.code.csharp.Location
import semmle.code.csharp.Stmt
import semmle.code.csharp.Type
private import dotnet
private import semmle.code.csharp.Enclosing::Internal
private import semmle.code.csharp.frameworks.System
private import dotnet
private import semmle.code.csharp.TypeRef
/**
* An expression. Either an access (`Access`), a call (`Call`), an object or

View File

@@ -1,3 +1 @@
| Assembly1.dll:0:0:0:0 | Class |
| Assembly2.dll:0:0:0:0 | Class |
| Program.cs:10:7:10:11 | Class |

View File

@@ -1,3 +1,3 @@
| Program.cs:18:21:18:22 | c1 | Assembly1.dll:0:0:0:0 | Class |
| Program.cs:19:21:19:22 | c2 | Assembly2.dll:0:0:0:0 | Class |
| Program.cs:18:21:18:22 | c1 | Program.cs:10:7:10:11 | Class |
| Program.cs:19:21:19:22 | c2 | Program.cs:10:7:10:11 | Class |
| Program.cs:20:15:20:16 | c3 | Program.cs:10:7:10:11 | Class |

View File

@@ -1,3 +1,4 @@
tooManyHandles
tooManyMatchingHandles
missingCil
csharpLocationViolation

View File

@@ -10,8 +10,19 @@ class MetadataEntity extends DotNet::NamedElement, @metadata_entity {
Assembly getAssembly() { metadata_handle(this, result, _) }
}
query predicate tooManyMatchingHandles(MetadataEntity e) {
strictcount(MetadataEntity e2 | e.matchesHandle(e2)) > 2
query predicate tooManyHandles(string s) {
exists(MetadataEntity e, Assembly a |
strictcount(int handle | metadata_handle(e, a, handle)) > 1 and
s = e.getQualifiedName()
)
}
query predicate tooManyMatchingHandles(string s) {
exists(MetadataEntity e, Assembly a, int handle |
metadata_handle(e, a, handle) and
strictcount(MetadataEntity e2 | metadata_handle(e2, a, handle)) > 2 and
s = e.getQualifiedName()
)
}
query predicate missingCil(Element e) {

View File

@@ -452,6 +452,149 @@
| LoopUnrolling.cs:71:9:71:21 | ...; | LoopUnrolling.cs:72:28:72:31 | access to parameter args | 4 |
| LoopUnrolling.cs:72:9:73:35 | foreach (... ... in ...) ... | LoopUnrolling.cs:72:9:73:35 | foreach (... ... in ...) ... | 1 |
| LoopUnrolling.cs:72:21:72:23 | String arg | LoopUnrolling.cs:73:13:73:34 | call to method WriteLine | 4 |
| MultiImplementationA.cs:6:22:6:31 | enter get_P1 | MultiImplementationA.cs:6:22:6:31 | enter get_P1 | 1 |
| MultiImplementationA.cs:6:22:6:31 | enter get_P1 | MultiImplementationB.cs:3:22:3:22 | enter get_P1 | 1 |
| MultiImplementationA.cs:6:22:6:31 | exit get_P1 | MultiImplementationA.cs:6:22:6:31 | exit get_P1 | 1 |
| MultiImplementationA.cs:6:22:6:31 | exit get_P1 | MultiImplementationB.cs:3:22:3:22 | exit get_P1 | 1 |
| MultiImplementationA.cs:6:28:6:31 | null | MultiImplementationA.cs:6:22:6:31 | throw ... | 2 |
| MultiImplementationA.cs:7:21:7:23 | enter get_P2 | MultiImplementationA.cs:7:21:7:23 | enter get_P2 | 1 |
| MultiImplementationA.cs:7:21:7:23 | enter get_P2 | MultiImplementationB.cs:4:21:4:23 | enter get_P2 | 1 |
| MultiImplementationA.cs:7:21:7:23 | exit get_P2 | MultiImplementationA.cs:7:21:7:23 | exit get_P2 | 1 |
| MultiImplementationA.cs:7:21:7:23 | exit get_P2 | MultiImplementationB.cs:4:21:4:23 | exit get_P2 | 1 |
| MultiImplementationA.cs:7:25:7:39 | {...} | MultiImplementationA.cs:7:27:7:37 | throw ...; | 3 |
| MultiImplementationA.cs:7:41:7:43 | enter set_P2 | MultiImplementationA.cs:7:41:7:43 | enter set_P2 | 1 |
| MultiImplementationA.cs:7:41:7:43 | enter set_P2 | MultiImplementationB.cs:4:39:4:41 | enter set_P2 | 1 |
| MultiImplementationA.cs:7:41:7:43 | exit set_P2 | MultiImplementationA.cs:7:41:7:43 | exit set_P2 | 1 |
| MultiImplementationA.cs:7:41:7:43 | exit set_P2 | MultiImplementationB.cs:4:39:4:41 | exit set_P2 | 1 |
| MultiImplementationA.cs:7:45:7:59 | {...} | MultiImplementationA.cs:7:47:7:57 | throw ...; | 3 |
| MultiImplementationA.cs:8:16:8:16 | enter M | MultiImplementationA.cs:8:16:8:16 | enter M | 1 |
| MultiImplementationA.cs:8:16:8:16 | enter M | MultiImplementationB.cs:5:16:5:16 | enter M | 1 |
| MultiImplementationA.cs:8:16:8:16 | exit M | MultiImplementationA.cs:8:16:8:16 | exit M | 1 |
| MultiImplementationA.cs:8:16:8:16 | exit M | MultiImplementationB.cs:5:16:5:16 | exit M | 1 |
| MultiImplementationA.cs:8:29:8:32 | null | MultiImplementationA.cs:8:23:8:32 | throw ... | 2 |
| MultiImplementationA.cs:13:16:13:16 | this access | MultiImplementationA.cs:13:16:13:20 | ... = ... | 3 |
| MultiImplementationA.cs:14:31:14:31 | access to parameter i | MultiImplementationA.cs:14:31:14:31 | access to parameter i | 1 |
| MultiImplementationA.cs:14:31:14:31 | enter get_Item | MultiImplementationA.cs:14:31:14:31 | enter get_Item | 1 |
| MultiImplementationA.cs:14:31:14:31 | enter get_Item | MultiImplementationB.cs:12:31:12:40 | enter get_Item | 1 |
| MultiImplementationA.cs:14:31:14:31 | exit get_Item | MultiImplementationA.cs:14:31:14:31 | exit get_Item | 1 |
| MultiImplementationA.cs:14:31:14:31 | exit get_Item | MultiImplementationB.cs:12:31:12:40 | exit get_Item | 1 |
| MultiImplementationA.cs:15:36:15:38 | enter get_Item | MultiImplementationA.cs:15:36:15:38 | enter get_Item | 1 |
| MultiImplementationA.cs:15:36:15:38 | enter get_Item | MultiImplementationB.cs:13:36:13:38 | enter get_Item | 1 |
| MultiImplementationA.cs:15:36:15:38 | exit get_Item | MultiImplementationA.cs:15:36:15:38 | exit get_Item | 1 |
| MultiImplementationA.cs:15:36:15:38 | exit get_Item | MultiImplementationB.cs:13:36:13:38 | exit get_Item | 1 |
| MultiImplementationA.cs:15:40:15:52 | {...} | MultiImplementationA.cs:15:42:15:50 | return ...; | 3 |
| MultiImplementationA.cs:15:54:15:56 | enter set_Item | MultiImplementationA.cs:15:54:15:56 | enter set_Item | 1 |
| MultiImplementationA.cs:15:54:15:56 | enter set_Item | MultiImplementationB.cs:13:56:13:58 | enter set_Item | 1 |
| MultiImplementationA.cs:15:54:15:56 | exit set_Item | MultiImplementationA.cs:15:54:15:56 | exit set_Item | 1 |
| MultiImplementationA.cs:15:54:15:56 | exit set_Item | MultiImplementationB.cs:13:56:13:58 | exit set_Item | 1 |
| MultiImplementationA.cs:15:58:15:60 | {...} | MultiImplementationA.cs:15:58:15:60 | {...} | 1 |
| MultiImplementationA.cs:16:17:16:18 | enter M1 | MultiImplementationA.cs:16:17:16:18 | enter M1 | 1 |
| MultiImplementationA.cs:16:17:16:18 | enter M1 | MultiImplementationB.cs:14:17:14:18 | enter M1 | 1 |
| MultiImplementationA.cs:16:17:16:18 | exit M1 | MultiImplementationA.cs:16:17:16:18 | exit M1 | 1 |
| MultiImplementationA.cs:16:17:16:18 | exit M1 | MultiImplementationB.cs:14:17:14:18 | exit M1 | 1 |
| MultiImplementationA.cs:17:5:19:5 | {...} | MultiImplementationA.cs:18:9:18:22 | M2(...) | 2 |
| MultiImplementationA.cs:18:9:18:22 | enter M2 | MultiImplementationA.cs:18:9:18:22 | exit M2 | 3 |
| MultiImplementationA.cs:20:12:20:13 | enter C2 | MultiImplementationA.cs:20:12:20:13 | enter C2 | 1 |
| MultiImplementationA.cs:20:12:20:13 | enter C2 | MultiImplementationB.cs:18:12:18:13 | enter C2 | 1 |
| MultiImplementationA.cs:20:12:20:13 | exit C2 | MultiImplementationA.cs:20:12:20:13 | exit C2 | 1 |
| MultiImplementationA.cs:20:12:20:13 | exit C2 | MultiImplementationB.cs:18:12:18:13 | exit C2 | 1 |
| MultiImplementationA.cs:20:22:20:31 | {...} | MultiImplementationA.cs:20:24:20:28 | ... = ... | 5 |
| MultiImplementationA.cs:21:12:21:13 | enter C2 | MultiImplementationA.cs:21:12:21:13 | enter C2 | 1 |
| MultiImplementationA.cs:21:12:21:13 | enter C2 | MultiImplementationB.cs:19:12:19:13 | enter C2 | 1 |
| MultiImplementationA.cs:21:12:21:13 | exit C2 | MultiImplementationA.cs:21:12:21:13 | exit C2 | 1 |
| MultiImplementationA.cs:21:12:21:13 | exit C2 | MultiImplementationB.cs:19:12:19:13 | exit C2 | 1 |
| MultiImplementationA.cs:21:24:21:24 | 0 | MultiImplementationA.cs:21:19:21:22 | call to constructor C2 | 2 |
| MultiImplementationA.cs:21:27:21:29 | {...} | MultiImplementationA.cs:21:27:21:29 | {...} | 1 |
| MultiImplementationA.cs:22:6:22:7 | enter ~C2 | MultiImplementationA.cs:22:6:22:7 | enter ~C2 | 1 |
| MultiImplementationA.cs:22:6:22:7 | enter ~C2 | MultiImplementationB.cs:20:6:20:7 | enter ~C2 | 1 |
| MultiImplementationA.cs:22:6:22:7 | exit ~C2 | MultiImplementationA.cs:22:6:22:7 | exit ~C2 | 1 |
| MultiImplementationA.cs:22:6:22:7 | exit ~C2 | MultiImplementationB.cs:20:6:20:7 | exit ~C2 | 1 |
| MultiImplementationA.cs:22:11:22:13 | {...} | MultiImplementationA.cs:22:11:22:13 | {...} | 1 |
| MultiImplementationA.cs:23:28:23:35 | enter implicit conversion | MultiImplementationA.cs:23:28:23:35 | enter implicit conversion | 1 |
| MultiImplementationA.cs:23:28:23:35 | enter implicit conversion | MultiImplementationB.cs:21:28:21:35 | enter implicit conversion | 1 |
| MultiImplementationA.cs:23:28:23:35 | exit implicit conversion | MultiImplementationA.cs:23:28:23:35 | exit implicit conversion | 1 |
| MultiImplementationA.cs:23:28:23:35 | exit implicit conversion | MultiImplementationB.cs:21:28:21:35 | exit implicit conversion | 1 |
| MultiImplementationA.cs:23:50:23:53 | null | MultiImplementationA.cs:23:50:23:53 | null | 1 |
| MultiImplementationA.cs:24:16:24:16 | this access | MultiImplementationA.cs:24:32:24:34 | ... = ... | 4 |
| MultiImplementationA.cs:30:21:30:23 | enter get_P3 | MultiImplementationA.cs:30:21:30:23 | exit get_P3 | 4 |
| MultiImplementationA.cs:30:21:30:23 | enter get_P3 | MultiImplementationB.cs:27:21:27:23 | exit get_P3 | 4 |
| MultiImplementationA.cs:36:9:36:10 | enter M1 | MultiImplementationA.cs:36:9:36:10 | enter M1 | 1 |
| MultiImplementationA.cs:36:9:36:10 | enter M1 | MultiImplementationB.cs:32:9:32:10 | enter M1 | 1 |
| MultiImplementationA.cs:36:9:36:10 | exit M1 | MultiImplementationA.cs:36:9:36:10 | exit M1 | 1 |
| MultiImplementationA.cs:36:9:36:10 | exit M1 | MultiImplementationB.cs:32:9:32:10 | exit M1 | 1 |
| MultiImplementationA.cs:36:14:36:28 | {...} | MultiImplementationA.cs:36:16:36:26 | throw ...; | 3 |
| MultiImplementationA.cs:37:9:37:10 | enter M2 | MultiImplementationA.cs:37:9:37:10 | exit M2 | 5 |
| MultiImplementationB.cs:3:22:3:22 | 0 | MultiImplementationB.cs:3:22:3:22 | 0 | 1 |
| MultiImplementationB.cs:3:22:3:22 | enter get_P1 | MultiImplementationA.cs:6:22:6:31 | enter get_P1 | 1 |
| MultiImplementationB.cs:3:22:3:22 | enter get_P1 | MultiImplementationB.cs:3:22:3:22 | enter get_P1 | 1 |
| MultiImplementationB.cs:3:22:3:22 | exit get_P1 | MultiImplementationA.cs:6:22:6:31 | exit get_P1 | 1 |
| MultiImplementationB.cs:3:22:3:22 | exit get_P1 | MultiImplementationB.cs:3:22:3:22 | exit get_P1 | 1 |
| MultiImplementationB.cs:4:21:4:23 | enter get_P2 | MultiImplementationA.cs:7:21:7:23 | enter get_P2 | 1 |
| MultiImplementationB.cs:4:21:4:23 | enter get_P2 | MultiImplementationB.cs:4:21:4:23 | enter get_P2 | 1 |
| MultiImplementationB.cs:4:21:4:23 | exit get_P2 | MultiImplementationA.cs:7:21:7:23 | exit get_P2 | 1 |
| MultiImplementationB.cs:4:21:4:23 | exit get_P2 | MultiImplementationB.cs:4:21:4:23 | exit get_P2 | 1 |
| MultiImplementationB.cs:4:25:4:37 | {...} | MultiImplementationB.cs:4:27:4:35 | return ...; | 3 |
| MultiImplementationB.cs:4:39:4:41 | enter set_P2 | MultiImplementationA.cs:7:41:7:43 | enter set_P2 | 1 |
| MultiImplementationB.cs:4:39:4:41 | enter set_P2 | MultiImplementationB.cs:4:39:4:41 | enter set_P2 | 1 |
| MultiImplementationB.cs:4:39:4:41 | exit set_P2 | MultiImplementationA.cs:7:41:7:43 | exit set_P2 | 1 |
| MultiImplementationB.cs:4:39:4:41 | exit set_P2 | MultiImplementationB.cs:4:39:4:41 | exit set_P2 | 1 |
| MultiImplementationB.cs:4:43:4:45 | {...} | MultiImplementationB.cs:4:43:4:45 | {...} | 1 |
| MultiImplementationB.cs:5:16:5:16 | enter M | MultiImplementationA.cs:8:16:8:16 | enter M | 1 |
| MultiImplementationB.cs:5:16:5:16 | enter M | MultiImplementationB.cs:5:16:5:16 | enter M | 1 |
| MultiImplementationB.cs:5:16:5:16 | exit M | MultiImplementationA.cs:8:16:8:16 | exit M | 1 |
| MultiImplementationB.cs:5:16:5:16 | exit M | MultiImplementationB.cs:5:16:5:16 | exit M | 1 |
| MultiImplementationB.cs:5:23:5:23 | 2 | MultiImplementationB.cs:5:23:5:23 | 2 | 1 |
| MultiImplementationB.cs:11:16:11:16 | this access | MultiImplementationB.cs:11:16:11:20 | ... = ... | 3 |
| MultiImplementationB.cs:12:31:12:40 | enter get_Item | MultiImplementationA.cs:14:31:14:31 | enter get_Item | 1 |
| MultiImplementationB.cs:12:31:12:40 | enter get_Item | MultiImplementationB.cs:12:31:12:40 | enter get_Item | 1 |
| MultiImplementationB.cs:12:31:12:40 | exit get_Item | MultiImplementationA.cs:14:31:14:31 | exit get_Item | 1 |
| MultiImplementationB.cs:12:31:12:40 | exit get_Item | MultiImplementationB.cs:12:31:12:40 | exit get_Item | 1 |
| MultiImplementationB.cs:12:37:12:40 | null | MultiImplementationB.cs:12:31:12:40 | throw ... | 2 |
| MultiImplementationB.cs:13:36:13:38 | enter get_Item | MultiImplementationA.cs:15:36:15:38 | enter get_Item | 1 |
| MultiImplementationB.cs:13:36:13:38 | enter get_Item | MultiImplementationB.cs:13:36:13:38 | enter get_Item | 1 |
| MultiImplementationB.cs:13:36:13:38 | exit get_Item | MultiImplementationA.cs:15:36:15:38 | exit get_Item | 1 |
| MultiImplementationB.cs:13:36:13:38 | exit get_Item | MultiImplementationB.cs:13:36:13:38 | exit get_Item | 1 |
| MultiImplementationB.cs:13:40:13:54 | {...} | MultiImplementationB.cs:13:42:13:52 | throw ...; | 3 |
| MultiImplementationB.cs:13:56:13:58 | enter set_Item | MultiImplementationA.cs:15:54:15:56 | enter set_Item | 1 |
| MultiImplementationB.cs:13:56:13:58 | enter set_Item | MultiImplementationB.cs:13:56:13:58 | enter set_Item | 1 |
| MultiImplementationB.cs:13:56:13:58 | exit set_Item | MultiImplementationA.cs:15:54:15:56 | exit set_Item | 1 |
| MultiImplementationB.cs:13:56:13:58 | exit set_Item | MultiImplementationB.cs:13:56:13:58 | exit set_Item | 1 |
| MultiImplementationB.cs:13:60:13:62 | {...} | MultiImplementationB.cs:13:60:13:62 | {...} | 1 |
| MultiImplementationB.cs:14:17:14:18 | enter M1 | MultiImplementationA.cs:16:17:16:18 | enter M1 | 1 |
| MultiImplementationB.cs:14:17:14:18 | enter M1 | MultiImplementationB.cs:14:17:14:18 | enter M1 | 1 |
| MultiImplementationB.cs:14:17:14:18 | exit M1 | MultiImplementationA.cs:16:17:16:18 | exit M1 | 1 |
| MultiImplementationB.cs:14:17:14:18 | exit M1 | MultiImplementationB.cs:14:17:14:18 | exit M1 | 1 |
| MultiImplementationB.cs:15:5:17:5 | {...} | MultiImplementationB.cs:16:9:16:31 | M2(...) | 2 |
| MultiImplementationB.cs:16:9:16:31 | enter M2 | MultiImplementationB.cs:16:9:16:31 | exit M2 | 4 |
| MultiImplementationB.cs:18:12:18:13 | enter C2 | MultiImplementationA.cs:20:12:20:13 | enter C2 | 1 |
| MultiImplementationB.cs:18:12:18:13 | enter C2 | MultiImplementationB.cs:18:12:18:13 | enter C2 | 1 |
| MultiImplementationB.cs:18:12:18:13 | exit C2 | MultiImplementationA.cs:20:12:20:13 | exit C2 | 1 |
| MultiImplementationB.cs:18:12:18:13 | exit C2 | MultiImplementationB.cs:18:12:18:13 | exit C2 | 1 |
| MultiImplementationB.cs:18:22:18:36 | {...} | MultiImplementationB.cs:18:24:18:34 | throw ...; | 3 |
| MultiImplementationB.cs:19:12:19:13 | enter C2 | MultiImplementationA.cs:21:12:21:13 | enter C2 | 1 |
| MultiImplementationB.cs:19:12:19:13 | enter C2 | MultiImplementationB.cs:19:12:19:13 | enter C2 | 1 |
| MultiImplementationB.cs:19:12:19:13 | exit C2 | MultiImplementationA.cs:21:12:21:13 | exit C2 | 1 |
| MultiImplementationB.cs:19:12:19:13 | exit C2 | MultiImplementationB.cs:19:12:19:13 | exit C2 | 1 |
| MultiImplementationB.cs:19:24:19:24 | 1 | MultiImplementationB.cs:19:19:19:22 | call to constructor C2 | 2 |
| MultiImplementationB.cs:19:27:19:29 | {...} | MultiImplementationB.cs:19:27:19:29 | {...} | 1 |
| MultiImplementationB.cs:20:6:20:7 | enter ~C2 | MultiImplementationA.cs:22:6:22:7 | enter ~C2 | 1 |
| MultiImplementationB.cs:20:6:20:7 | enter ~C2 | MultiImplementationB.cs:20:6:20:7 | enter ~C2 | 1 |
| MultiImplementationB.cs:20:6:20:7 | exit ~C2 | MultiImplementationA.cs:22:6:22:7 | exit ~C2 | 1 |
| MultiImplementationB.cs:20:6:20:7 | exit ~C2 | MultiImplementationB.cs:20:6:20:7 | exit ~C2 | 1 |
| MultiImplementationB.cs:20:11:20:25 | {...} | MultiImplementationB.cs:20:13:20:23 | throw ...; | 3 |
| MultiImplementationB.cs:21:28:21:35 | enter implicit conversion | MultiImplementationA.cs:23:28:23:35 | enter implicit conversion | 1 |
| MultiImplementationB.cs:21:28:21:35 | enter implicit conversion | MultiImplementationB.cs:21:28:21:35 | enter implicit conversion | 1 |
| MultiImplementationB.cs:21:28:21:35 | exit implicit conversion | MultiImplementationA.cs:23:28:23:35 | exit implicit conversion | 1 |
| MultiImplementationB.cs:21:28:21:35 | exit implicit conversion | MultiImplementationB.cs:21:28:21:35 | exit implicit conversion | 1 |
| MultiImplementationB.cs:21:56:21:59 | null | MultiImplementationB.cs:21:50:21:59 | throw ... | 2 |
| MultiImplementationB.cs:22:16:22:16 | this access | MultiImplementationB.cs:22:32:22:34 | ... = ... | 4 |
| MultiImplementationB.cs:27:21:27:23 | enter get_P3 | MultiImplementationA.cs:30:21:30:23 | exit get_P3 | 4 |
| MultiImplementationB.cs:27:21:27:23 | enter get_P3 | MultiImplementationB.cs:27:21:27:23 | exit get_P3 | 4 |
| MultiImplementationB.cs:32:9:32:10 | enter M1 | MultiImplementationA.cs:36:9:36:10 | enter M1 | 1 |
| MultiImplementationB.cs:32:9:32:10 | enter M1 | MultiImplementationB.cs:32:9:32:10 | enter M1 | 1 |
| MultiImplementationB.cs:32:9:32:10 | exit M1 | MultiImplementationA.cs:36:9:36:10 | exit M1 | 1 |
| MultiImplementationB.cs:32:9:32:10 | exit M1 | MultiImplementationB.cs:32:9:32:10 | exit M1 | 1 |
| MultiImplementationB.cs:32:17:32:17 | 0 | MultiImplementationB.cs:32:17:32:17 | 0 | 1 |
| NullCoalescing.cs:3:9:3:10 | enter M1 | NullCoalescing.cs:3:23:3:23 | access to parameter i | 3 |
| NullCoalescing.cs:3:9:3:10 | exit M1 | NullCoalescing.cs:3:9:3:10 | exit M1 | 1 |
| NullCoalescing.cs:3:28:3:28 | 0 | NullCoalescing.cs:3:28:3:28 | 0 | 1 |

View File

@@ -7,3 +7,75 @@ breakInvariant5
multipleSuccessors
| ConditionalAccess.cs:30:28:30:32 | ... = ... | successor | ConditionalAccess.cs:1:7:1:23 | exit ConditionalAccess |
| ConditionalAccess.cs:30:28:30:32 | ... = ... | successor | ConditionalAccess.cs:30:10:30:12 | exit Out |
| MultiImplementationA.cs:6:22:6:31 | enter get_P1 | successor | MultiImplementationA.cs:6:28:6:31 | null |
| MultiImplementationA.cs:6:22:6:31 | enter get_P1 | successor | MultiImplementationB.cs:3:22:3:22 | 0 |
| MultiImplementationA.cs:7:21:7:23 | enter get_P2 | successor | MultiImplementationA.cs:7:25:7:39 | {...} |
| MultiImplementationA.cs:7:21:7:23 | enter get_P2 | successor | MultiImplementationB.cs:4:25:4:37 | {...} |
| MultiImplementationA.cs:7:41:7:43 | enter set_P2 | successor | MultiImplementationA.cs:7:45:7:59 | {...} |
| MultiImplementationA.cs:7:41:7:43 | enter set_P2 | successor | MultiImplementationB.cs:4:43:4:45 | {...} |
| MultiImplementationA.cs:8:16:8:16 | enter M | successor | MultiImplementationA.cs:8:29:8:32 | null |
| MultiImplementationA.cs:8:16:8:16 | enter M | successor | MultiImplementationB.cs:5:23:5:23 | 2 |
| MultiImplementationA.cs:13:16:13:20 | ... = ... | successor | MultiImplementationA.cs:13:16:13:16 | this access |
| MultiImplementationA.cs:13:16:13:20 | ... = ... | successor | MultiImplementationA.cs:24:16:24:16 | this access |
| MultiImplementationA.cs:13:16:13:20 | ... = ... | successor | MultiImplementationB.cs:11:16:11:16 | this access |
| MultiImplementationA.cs:13:16:13:20 | ... = ... | successor | MultiImplementationB.cs:22:16:22:16 | this access |
| MultiImplementationA.cs:14:31:14:31 | enter get_Item | successor | MultiImplementationA.cs:14:31:14:31 | access to parameter i |
| MultiImplementationA.cs:14:31:14:31 | enter get_Item | successor | MultiImplementationB.cs:12:37:12:40 | null |
| MultiImplementationA.cs:15:36:15:38 | enter get_Item | successor | MultiImplementationA.cs:15:40:15:52 | {...} |
| MultiImplementationA.cs:15:36:15:38 | enter get_Item | successor | MultiImplementationB.cs:13:40:13:54 | {...} |
| MultiImplementationA.cs:15:54:15:56 | enter set_Item | successor | MultiImplementationA.cs:15:58:15:60 | {...} |
| MultiImplementationA.cs:15:54:15:56 | enter set_Item | successor | MultiImplementationB.cs:13:60:13:62 | {...} |
| MultiImplementationA.cs:16:17:16:18 | enter M1 | successor | MultiImplementationA.cs:17:5:19:5 | {...} |
| MultiImplementationA.cs:16:17:16:18 | enter M1 | successor | MultiImplementationB.cs:15:5:17:5 | {...} |
| MultiImplementationA.cs:20:12:20:13 | enter C2 | successor | MultiImplementationA.cs:13:16:13:16 | this access |
| MultiImplementationA.cs:20:12:20:13 | enter C2 | successor | MultiImplementationB.cs:11:16:11:16 | this access |
| MultiImplementationA.cs:21:12:21:13 | enter C2 | successor | MultiImplementationA.cs:21:24:21:24 | 0 |
| MultiImplementationA.cs:21:12:21:13 | enter C2 | successor | MultiImplementationB.cs:19:24:19:24 | 1 |
| MultiImplementationA.cs:21:19:21:22 | call to constructor C2 | successor | MultiImplementationA.cs:21:27:21:29 | {...} |
| MultiImplementationA.cs:21:19:21:22 | call to constructor C2 | successor | MultiImplementationB.cs:19:27:19:29 | {...} |
| MultiImplementationA.cs:22:6:22:7 | enter ~C2 | successor | MultiImplementationA.cs:22:11:22:13 | {...} |
| MultiImplementationA.cs:22:6:22:7 | enter ~C2 | successor | MultiImplementationB.cs:20:11:20:25 | {...} |
| MultiImplementationA.cs:23:28:23:35 | enter implicit conversion | successor | MultiImplementationA.cs:23:50:23:53 | null |
| MultiImplementationA.cs:23:28:23:35 | enter implicit conversion | successor | MultiImplementationB.cs:21:56:21:59 | null |
| MultiImplementationA.cs:24:32:24:34 | ... = ... | successor | MultiImplementationA.cs:20:22:20:31 | {...} |
| MultiImplementationA.cs:24:32:24:34 | ... = ... | successor | MultiImplementationA.cs:24:16:24:16 | this access |
| MultiImplementationA.cs:24:32:24:34 | ... = ... | successor | MultiImplementationB.cs:18:22:18:36 | {...} |
| MultiImplementationA.cs:24:32:24:34 | ... = ... | successor | MultiImplementationB.cs:22:16:22:16 | this access |
| MultiImplementationA.cs:36:9:36:10 | enter M1 | successor | MultiImplementationA.cs:36:14:36:28 | {...} |
| MultiImplementationA.cs:36:9:36:10 | enter M1 | successor | MultiImplementationB.cs:32:17:32:17 | 0 |
| MultiImplementationB.cs:3:22:3:22 | enter get_P1 | successor | MultiImplementationA.cs:6:28:6:31 | null |
| MultiImplementationB.cs:3:22:3:22 | enter get_P1 | successor | MultiImplementationB.cs:3:22:3:22 | 0 |
| MultiImplementationB.cs:4:21:4:23 | enter get_P2 | successor | MultiImplementationA.cs:7:25:7:39 | {...} |
| MultiImplementationB.cs:4:21:4:23 | enter get_P2 | successor | MultiImplementationB.cs:4:25:4:37 | {...} |
| MultiImplementationB.cs:4:39:4:41 | enter set_P2 | successor | MultiImplementationA.cs:7:45:7:59 | {...} |
| MultiImplementationB.cs:4:39:4:41 | enter set_P2 | successor | MultiImplementationB.cs:4:43:4:45 | {...} |
| MultiImplementationB.cs:5:16:5:16 | enter M | successor | MultiImplementationA.cs:8:29:8:32 | null |
| MultiImplementationB.cs:5:16:5:16 | enter M | successor | MultiImplementationB.cs:5:23:5:23 | 2 |
| MultiImplementationB.cs:11:16:11:20 | ... = ... | successor | MultiImplementationA.cs:13:16:13:16 | this access |
| MultiImplementationB.cs:11:16:11:20 | ... = ... | successor | MultiImplementationA.cs:24:16:24:16 | this access |
| MultiImplementationB.cs:11:16:11:20 | ... = ... | successor | MultiImplementationB.cs:11:16:11:16 | this access |
| MultiImplementationB.cs:11:16:11:20 | ... = ... | successor | MultiImplementationB.cs:22:16:22:16 | this access |
| MultiImplementationB.cs:12:31:12:40 | enter get_Item | successor | MultiImplementationA.cs:14:31:14:31 | access to parameter i |
| MultiImplementationB.cs:12:31:12:40 | enter get_Item | successor | MultiImplementationB.cs:12:37:12:40 | null |
| MultiImplementationB.cs:13:36:13:38 | enter get_Item | successor | MultiImplementationA.cs:15:40:15:52 | {...} |
| MultiImplementationB.cs:13:36:13:38 | enter get_Item | successor | MultiImplementationB.cs:13:40:13:54 | {...} |
| MultiImplementationB.cs:13:56:13:58 | enter set_Item | successor | MultiImplementationA.cs:15:58:15:60 | {...} |
| MultiImplementationB.cs:13:56:13:58 | enter set_Item | successor | MultiImplementationB.cs:13:60:13:62 | {...} |
| MultiImplementationB.cs:14:17:14:18 | enter M1 | successor | MultiImplementationA.cs:17:5:19:5 | {...} |
| MultiImplementationB.cs:14:17:14:18 | enter M1 | successor | MultiImplementationB.cs:15:5:17:5 | {...} |
| MultiImplementationB.cs:18:12:18:13 | enter C2 | successor | MultiImplementationA.cs:13:16:13:16 | this access |
| MultiImplementationB.cs:18:12:18:13 | enter C2 | successor | MultiImplementationB.cs:11:16:11:16 | this access |
| MultiImplementationB.cs:19:12:19:13 | enter C2 | successor | MultiImplementationA.cs:21:24:21:24 | 0 |
| MultiImplementationB.cs:19:12:19:13 | enter C2 | successor | MultiImplementationB.cs:19:24:19:24 | 1 |
| MultiImplementationB.cs:19:19:19:22 | call to constructor C2 | successor | MultiImplementationA.cs:21:27:21:29 | {...} |
| MultiImplementationB.cs:19:19:19:22 | call to constructor C2 | successor | MultiImplementationB.cs:19:27:19:29 | {...} |
| MultiImplementationB.cs:20:6:20:7 | enter ~C2 | successor | MultiImplementationA.cs:22:11:22:13 | {...} |
| MultiImplementationB.cs:20:6:20:7 | enter ~C2 | successor | MultiImplementationB.cs:20:11:20:25 | {...} |
| MultiImplementationB.cs:21:28:21:35 | enter implicit conversion | successor | MultiImplementationA.cs:23:50:23:53 | null |
| MultiImplementationB.cs:21:28:21:35 | enter implicit conversion | successor | MultiImplementationB.cs:21:56:21:59 | null |
| MultiImplementationB.cs:22:32:22:34 | ... = ... | successor | MultiImplementationA.cs:20:22:20:31 | {...} |
| MultiImplementationB.cs:22:32:22:34 | ... = ... | successor | MultiImplementationA.cs:24:16:24:16 | this access |
| MultiImplementationB.cs:22:32:22:34 | ... = ... | successor | MultiImplementationB.cs:18:22:18:36 | {...} |
| MultiImplementationB.cs:22:32:22:34 | ... = ... | successor | MultiImplementationB.cs:22:16:22:16 | this access |
| MultiImplementationB.cs:32:9:32:10 | enter M1 | successor | MultiImplementationA.cs:36:14:36:28 | {...} |
| MultiImplementationB.cs:32:9:32:10 | enter M1 | successor | MultiImplementationB.cs:32:17:32:17 | 0 |

View File

@@ -2038,6 +2038,110 @@ dominance
| LoopUnrolling.cs:72:28:72:31 | access to parameter args | LoopUnrolling.cs:72:9:73:35 | foreach (... ... in ...) ... |
| LoopUnrolling.cs:73:13:73:35 | ...; | LoopUnrolling.cs:73:31:73:33 | access to local variable arg |
| LoopUnrolling.cs:73:31:73:33 | access to local variable arg | LoopUnrolling.cs:73:13:73:34 | call to method WriteLine |
| MultiImplementationA.cs:6:22:6:31 | enter get_P1 | MultiImplementationA.cs:6:28:6:31 | null |
| MultiImplementationA.cs:6:22:6:31 | enter get_P1 | MultiImplementationB.cs:3:22:3:22 | 0 |
| MultiImplementationA.cs:6:28:6:31 | null | MultiImplementationA.cs:6:22:6:31 | throw ... |
| MultiImplementationA.cs:7:21:7:23 | enter get_P2 | MultiImplementationA.cs:7:25:7:39 | {...} |
| MultiImplementationA.cs:7:21:7:23 | enter get_P2 | MultiImplementationB.cs:4:25:4:37 | {...} |
| MultiImplementationA.cs:7:25:7:39 | {...} | MultiImplementationA.cs:7:33:7:36 | null |
| MultiImplementationA.cs:7:33:7:36 | null | MultiImplementationA.cs:7:27:7:37 | throw ...; |
| MultiImplementationA.cs:7:41:7:43 | enter set_P2 | MultiImplementationA.cs:7:45:7:59 | {...} |
| MultiImplementationA.cs:7:41:7:43 | enter set_P2 | MultiImplementationB.cs:4:43:4:45 | {...} |
| MultiImplementationA.cs:7:45:7:59 | {...} | MultiImplementationA.cs:7:53:7:56 | null |
| MultiImplementationA.cs:7:53:7:56 | null | MultiImplementationA.cs:7:47:7:57 | throw ...; |
| MultiImplementationA.cs:8:16:8:16 | enter M | MultiImplementationA.cs:8:29:8:32 | null |
| MultiImplementationA.cs:8:16:8:16 | enter M | MultiImplementationB.cs:5:23:5:23 | 2 |
| MultiImplementationA.cs:8:29:8:32 | null | MultiImplementationA.cs:8:23:8:32 | throw ... |
| MultiImplementationA.cs:13:16:13:16 | this access | MultiImplementationA.cs:13:20:13:20 | 0 |
| MultiImplementationA.cs:13:20:13:20 | 0 | MultiImplementationA.cs:13:16:13:20 | ... = ... |
| MultiImplementationA.cs:14:31:14:31 | enter get_Item | MultiImplementationA.cs:14:31:14:31 | access to parameter i |
| MultiImplementationA.cs:14:31:14:31 | enter get_Item | MultiImplementationB.cs:12:37:12:40 | null |
| MultiImplementationA.cs:15:36:15:38 | enter get_Item | MultiImplementationA.cs:15:40:15:52 | {...} |
| MultiImplementationA.cs:15:36:15:38 | enter get_Item | MultiImplementationB.cs:13:40:13:54 | {...} |
| MultiImplementationA.cs:15:40:15:52 | {...} | MultiImplementationA.cs:15:49:15:49 | access to parameter s |
| MultiImplementationA.cs:15:49:15:49 | access to parameter s | MultiImplementationA.cs:15:42:15:50 | return ...; |
| MultiImplementationA.cs:15:54:15:56 | enter set_Item | MultiImplementationA.cs:15:58:15:60 | {...} |
| MultiImplementationA.cs:15:54:15:56 | enter set_Item | MultiImplementationB.cs:13:60:13:62 | {...} |
| MultiImplementationA.cs:16:17:16:18 | enter M1 | MultiImplementationA.cs:17:5:19:5 | {...} |
| MultiImplementationA.cs:16:17:16:18 | enter M1 | MultiImplementationB.cs:15:5:17:5 | {...} |
| MultiImplementationA.cs:17:5:19:5 | {...} | MultiImplementationA.cs:18:9:18:22 | M2(...) |
| MultiImplementationA.cs:18:9:18:22 | enter M2 | MultiImplementationA.cs:18:21:18:21 | 0 |
| MultiImplementationA.cs:18:21:18:21 | 0 | MultiImplementationA.cs:18:9:18:22 | exit M2 |
| MultiImplementationA.cs:20:12:20:13 | enter C2 | MultiImplementationA.cs:13:16:13:16 | this access |
| MultiImplementationA.cs:20:12:20:13 | enter C2 | MultiImplementationB.cs:11:16:11:16 | this access |
| MultiImplementationA.cs:20:22:20:31 | {...} | MultiImplementationA.cs:20:24:20:29 | ...; |
| MultiImplementationA.cs:20:24:20:24 | this access | MultiImplementationA.cs:20:28:20:28 | access to parameter i |
| MultiImplementationA.cs:20:24:20:29 | ...; | MultiImplementationA.cs:20:24:20:24 | this access |
| MultiImplementationA.cs:20:28:20:28 | access to parameter i | MultiImplementationA.cs:20:24:20:28 | ... = ... |
| MultiImplementationA.cs:21:12:21:13 | enter C2 | MultiImplementationA.cs:21:24:21:24 | 0 |
| MultiImplementationA.cs:21:12:21:13 | enter C2 | MultiImplementationB.cs:19:24:19:24 | 1 |
| MultiImplementationA.cs:21:24:21:24 | 0 | MultiImplementationA.cs:21:19:21:22 | call to constructor C2 |
| MultiImplementationA.cs:22:6:22:7 | enter ~C2 | MultiImplementationA.cs:22:11:22:13 | {...} |
| MultiImplementationA.cs:22:6:22:7 | enter ~C2 | MultiImplementationB.cs:20:11:20:25 | {...} |
| MultiImplementationA.cs:23:28:23:35 | enter implicit conversion | MultiImplementationA.cs:23:50:23:53 | null |
| MultiImplementationA.cs:23:28:23:35 | enter implicit conversion | MultiImplementationB.cs:21:56:21:59 | null |
| MultiImplementationA.cs:24:16:24:16 | access to property P | MultiImplementationA.cs:24:32:24:34 | ... = ... |
| MultiImplementationA.cs:24:16:24:16 | this access | MultiImplementationA.cs:24:34:24:34 | 0 |
| MultiImplementationA.cs:24:34:24:34 | 0 | MultiImplementationA.cs:24:16:24:16 | access to property P |
| MultiImplementationA.cs:30:21:30:23 | enter get_P3 | MultiImplementationA.cs:30:34:30:37 | null |
| MultiImplementationA.cs:30:28:30:37 | throw ... | MultiImplementationA.cs:30:21:30:23 | exit get_P3 |
| MultiImplementationA.cs:30:28:30:37 | throw ... | MultiImplementationB.cs:27:21:27:23 | exit get_P3 |
| MultiImplementationA.cs:30:34:30:37 | null | MultiImplementationA.cs:30:28:30:37 | throw ... |
| MultiImplementationA.cs:36:9:36:10 | enter M1 | MultiImplementationA.cs:36:14:36:28 | {...} |
| MultiImplementationA.cs:36:9:36:10 | enter M1 | MultiImplementationB.cs:32:17:32:17 | 0 |
| MultiImplementationA.cs:36:14:36:28 | {...} | MultiImplementationA.cs:36:22:36:25 | null |
| MultiImplementationA.cs:36:22:36:25 | null | MultiImplementationA.cs:36:16:36:26 | throw ...; |
| MultiImplementationA.cs:37:9:37:10 | enter M2 | MultiImplementationA.cs:37:14:37:28 | {...} |
| MultiImplementationA.cs:37:14:37:28 | {...} | MultiImplementationA.cs:37:22:37:25 | null |
| MultiImplementationA.cs:37:16:37:26 | throw ...; | MultiImplementationA.cs:37:9:37:10 | exit M2 |
| MultiImplementationA.cs:37:22:37:25 | null | MultiImplementationA.cs:37:16:37:26 | throw ...; |
| MultiImplementationB.cs:3:22:3:22 | enter get_P1 | MultiImplementationA.cs:6:28:6:31 | null |
| MultiImplementationB.cs:3:22:3:22 | enter get_P1 | MultiImplementationB.cs:3:22:3:22 | 0 |
| MultiImplementationB.cs:4:21:4:23 | enter get_P2 | MultiImplementationA.cs:7:25:7:39 | {...} |
| MultiImplementationB.cs:4:21:4:23 | enter get_P2 | MultiImplementationB.cs:4:25:4:37 | {...} |
| MultiImplementationB.cs:4:25:4:37 | {...} | MultiImplementationB.cs:4:34:4:34 | 1 |
| MultiImplementationB.cs:4:34:4:34 | 1 | MultiImplementationB.cs:4:27:4:35 | return ...; |
| MultiImplementationB.cs:4:39:4:41 | enter set_P2 | MultiImplementationA.cs:7:45:7:59 | {...} |
| MultiImplementationB.cs:4:39:4:41 | enter set_P2 | MultiImplementationB.cs:4:43:4:45 | {...} |
| MultiImplementationB.cs:5:16:5:16 | enter M | MultiImplementationA.cs:8:29:8:32 | null |
| MultiImplementationB.cs:5:16:5:16 | enter M | MultiImplementationB.cs:5:23:5:23 | 2 |
| MultiImplementationB.cs:11:16:11:16 | this access | MultiImplementationB.cs:11:20:11:20 | 1 |
| MultiImplementationB.cs:11:20:11:20 | 1 | MultiImplementationB.cs:11:16:11:20 | ... = ... |
| MultiImplementationB.cs:12:31:12:40 | enter get_Item | MultiImplementationA.cs:14:31:14:31 | access to parameter i |
| MultiImplementationB.cs:12:31:12:40 | enter get_Item | MultiImplementationB.cs:12:37:12:40 | null |
| MultiImplementationB.cs:12:37:12:40 | null | MultiImplementationB.cs:12:31:12:40 | throw ... |
| MultiImplementationB.cs:13:36:13:38 | enter get_Item | MultiImplementationA.cs:15:40:15:52 | {...} |
| MultiImplementationB.cs:13:36:13:38 | enter get_Item | MultiImplementationB.cs:13:40:13:54 | {...} |
| MultiImplementationB.cs:13:40:13:54 | {...} | MultiImplementationB.cs:13:48:13:51 | null |
| MultiImplementationB.cs:13:48:13:51 | null | MultiImplementationB.cs:13:42:13:52 | throw ...; |
| MultiImplementationB.cs:13:56:13:58 | enter set_Item | MultiImplementationA.cs:15:58:15:60 | {...} |
| MultiImplementationB.cs:13:56:13:58 | enter set_Item | MultiImplementationB.cs:13:60:13:62 | {...} |
| MultiImplementationB.cs:14:17:14:18 | enter M1 | MultiImplementationA.cs:17:5:19:5 | {...} |
| MultiImplementationB.cs:14:17:14:18 | enter M1 | MultiImplementationB.cs:15:5:17:5 | {...} |
| MultiImplementationB.cs:15:5:17:5 | {...} | MultiImplementationB.cs:16:9:16:31 | M2(...) |
| MultiImplementationB.cs:16:9:16:31 | enter M2 | MultiImplementationB.cs:16:27:16:30 | null |
| MultiImplementationB.cs:16:21:16:30 | throw ... | MultiImplementationB.cs:16:9:16:31 | exit M2 |
| MultiImplementationB.cs:16:27:16:30 | null | MultiImplementationB.cs:16:21:16:30 | throw ... |
| MultiImplementationB.cs:18:12:18:13 | enter C2 | MultiImplementationA.cs:13:16:13:16 | this access |
| MultiImplementationB.cs:18:12:18:13 | enter C2 | MultiImplementationB.cs:11:16:11:16 | this access |
| MultiImplementationB.cs:18:22:18:36 | {...} | MultiImplementationB.cs:18:30:18:33 | null |
| MultiImplementationB.cs:18:30:18:33 | null | MultiImplementationB.cs:18:24:18:34 | throw ...; |
| MultiImplementationB.cs:19:12:19:13 | enter C2 | MultiImplementationA.cs:21:24:21:24 | 0 |
| MultiImplementationB.cs:19:12:19:13 | enter C2 | MultiImplementationB.cs:19:24:19:24 | 1 |
| MultiImplementationB.cs:19:24:19:24 | 1 | MultiImplementationB.cs:19:19:19:22 | call to constructor C2 |
| MultiImplementationB.cs:20:6:20:7 | enter ~C2 | MultiImplementationA.cs:22:11:22:13 | {...} |
| MultiImplementationB.cs:20:6:20:7 | enter ~C2 | MultiImplementationB.cs:20:11:20:25 | {...} |
| MultiImplementationB.cs:20:11:20:25 | {...} | MultiImplementationB.cs:20:19:20:22 | null |
| MultiImplementationB.cs:20:19:20:22 | null | MultiImplementationB.cs:20:13:20:23 | throw ...; |
| MultiImplementationB.cs:21:28:21:35 | enter implicit conversion | MultiImplementationA.cs:23:50:23:53 | null |
| MultiImplementationB.cs:21:28:21:35 | enter implicit conversion | MultiImplementationB.cs:21:56:21:59 | null |
| MultiImplementationB.cs:21:56:21:59 | null | MultiImplementationB.cs:21:50:21:59 | throw ... |
| MultiImplementationB.cs:22:16:22:16 | access to property P | MultiImplementationB.cs:22:32:22:34 | ... = ... |
| MultiImplementationB.cs:22:16:22:16 | this access | MultiImplementationB.cs:22:34:22:34 | 1 |
| MultiImplementationB.cs:22:34:22:34 | 1 | MultiImplementationB.cs:22:16:22:16 | access to property P |
| MultiImplementationB.cs:27:21:27:23 | enter get_P3 | MultiImplementationA.cs:30:34:30:37 | null |
| MultiImplementationB.cs:32:9:32:10 | enter M1 | MultiImplementationA.cs:36:14:36:28 | {...} |
| MultiImplementationB.cs:32:9:32:10 | enter M1 | MultiImplementationB.cs:32:17:32:17 | 0 |
| NullCoalescing.cs:3:9:3:10 | enter M1 | NullCoalescing.cs:3:23:3:28 | ... ?? ... |
| NullCoalescing.cs:3:23:3:23 | access to parameter i | NullCoalescing.cs:3:9:3:10 | exit M1 |
| NullCoalescing.cs:3:23:3:23 | access to parameter i | NullCoalescing.cs:3:28:3:28 | 0 |
@@ -5068,6 +5172,110 @@ postDominance
| LoopUnrolling.cs:73:13:73:34 | call to method WriteLine | LoopUnrolling.cs:73:31:73:33 | access to local variable arg |
| LoopUnrolling.cs:73:13:73:35 | ...; | LoopUnrolling.cs:72:21:72:23 | String arg |
| LoopUnrolling.cs:73:31:73:33 | access to local variable arg | LoopUnrolling.cs:73:13:73:35 | ...; |
| MultiImplementationA.cs:6:22:6:31 | exit get_P1 | MultiImplementationA.cs:6:22:6:31 | throw ... |
| MultiImplementationA.cs:6:22:6:31 | exit get_P1 | MultiImplementationB.cs:3:22:3:22 | 0 |
| MultiImplementationA.cs:6:22:6:31 | throw ... | MultiImplementationA.cs:6:28:6:31 | null |
| MultiImplementationA.cs:7:21:7:23 | exit get_P2 | MultiImplementationA.cs:7:27:7:37 | throw ...; |
| MultiImplementationA.cs:7:21:7:23 | exit get_P2 | MultiImplementationB.cs:4:27:4:35 | return ...; |
| MultiImplementationA.cs:7:27:7:37 | throw ...; | MultiImplementationA.cs:7:33:7:36 | null |
| MultiImplementationA.cs:7:33:7:36 | null | MultiImplementationA.cs:7:25:7:39 | {...} |
| MultiImplementationA.cs:7:41:7:43 | exit set_P2 | MultiImplementationA.cs:7:47:7:57 | throw ...; |
| MultiImplementationA.cs:7:41:7:43 | exit set_P2 | MultiImplementationB.cs:4:43:4:45 | {...} |
| MultiImplementationA.cs:7:47:7:57 | throw ...; | MultiImplementationA.cs:7:53:7:56 | null |
| MultiImplementationA.cs:7:53:7:56 | null | MultiImplementationA.cs:7:45:7:59 | {...} |
| MultiImplementationA.cs:8:16:8:16 | exit M | MultiImplementationA.cs:8:23:8:32 | throw ... |
| MultiImplementationA.cs:8:16:8:16 | exit M | MultiImplementationB.cs:5:23:5:23 | 2 |
| MultiImplementationA.cs:8:23:8:32 | throw ... | MultiImplementationA.cs:8:29:8:32 | null |
| MultiImplementationA.cs:13:16:13:20 | ... = ... | MultiImplementationA.cs:13:20:13:20 | 0 |
| MultiImplementationA.cs:13:20:13:20 | 0 | MultiImplementationA.cs:13:16:13:16 | this access |
| MultiImplementationA.cs:14:31:14:31 | exit get_Item | MultiImplementationA.cs:14:31:14:31 | access to parameter i |
| MultiImplementationA.cs:14:31:14:31 | exit get_Item | MultiImplementationB.cs:12:31:12:40 | throw ... |
| MultiImplementationA.cs:15:36:15:38 | exit get_Item | MultiImplementationA.cs:15:42:15:50 | return ...; |
| MultiImplementationA.cs:15:36:15:38 | exit get_Item | MultiImplementationB.cs:13:42:13:52 | throw ...; |
| MultiImplementationA.cs:15:42:15:50 | return ...; | MultiImplementationA.cs:15:49:15:49 | access to parameter s |
| MultiImplementationA.cs:15:49:15:49 | access to parameter s | MultiImplementationA.cs:15:40:15:52 | {...} |
| MultiImplementationA.cs:15:54:15:56 | exit set_Item | MultiImplementationA.cs:15:58:15:60 | {...} |
| MultiImplementationA.cs:15:54:15:56 | exit set_Item | MultiImplementationB.cs:13:60:13:62 | {...} |
| MultiImplementationA.cs:16:17:16:18 | exit M1 | MultiImplementationA.cs:18:9:18:22 | M2(...) |
| MultiImplementationA.cs:16:17:16:18 | exit M1 | MultiImplementationB.cs:16:9:16:31 | M2(...) |
| MultiImplementationA.cs:18:9:18:22 | M2(...) | MultiImplementationA.cs:17:5:19:5 | {...} |
| MultiImplementationA.cs:18:9:18:22 | exit M2 | MultiImplementationA.cs:18:21:18:21 | 0 |
| MultiImplementationA.cs:18:21:18:21 | 0 | MultiImplementationA.cs:18:9:18:22 | enter M2 |
| MultiImplementationA.cs:20:12:20:13 | exit C2 | MultiImplementationA.cs:20:24:20:28 | ... = ... |
| MultiImplementationA.cs:20:12:20:13 | exit C2 | MultiImplementationB.cs:18:24:18:34 | throw ...; |
| MultiImplementationA.cs:20:24:20:24 | this access | MultiImplementationA.cs:20:24:20:29 | ...; |
| MultiImplementationA.cs:20:24:20:28 | ... = ... | MultiImplementationA.cs:20:28:20:28 | access to parameter i |
| MultiImplementationA.cs:20:24:20:29 | ...; | MultiImplementationA.cs:20:22:20:31 | {...} |
| MultiImplementationA.cs:20:28:20:28 | access to parameter i | MultiImplementationA.cs:20:24:20:24 | this access |
| MultiImplementationA.cs:21:12:21:13 | exit C2 | MultiImplementationA.cs:21:27:21:29 | {...} |
| MultiImplementationA.cs:21:12:21:13 | exit C2 | MultiImplementationB.cs:19:27:19:29 | {...} |
| MultiImplementationA.cs:21:19:21:22 | call to constructor C2 | MultiImplementationA.cs:21:24:21:24 | 0 |
| MultiImplementationA.cs:22:6:22:7 | exit ~C2 | MultiImplementationA.cs:22:11:22:13 | {...} |
| MultiImplementationA.cs:22:6:22:7 | exit ~C2 | MultiImplementationB.cs:20:13:20:23 | throw ...; |
| MultiImplementationA.cs:23:28:23:35 | exit implicit conversion | MultiImplementationA.cs:23:50:23:53 | null |
| MultiImplementationA.cs:23:28:23:35 | exit implicit conversion | MultiImplementationB.cs:21:50:21:59 | throw ... |
| MultiImplementationA.cs:24:16:24:16 | access to property P | MultiImplementationA.cs:24:34:24:34 | 0 |
| MultiImplementationA.cs:24:32:24:34 | ... = ... | MultiImplementationA.cs:24:16:24:16 | access to property P |
| MultiImplementationA.cs:24:34:24:34 | 0 | MultiImplementationA.cs:24:16:24:16 | this access |
| MultiImplementationA.cs:30:21:30:23 | exit get_P3 | MultiImplementationA.cs:30:28:30:37 | throw ... |
| MultiImplementationA.cs:30:28:30:37 | throw ... | MultiImplementationA.cs:30:34:30:37 | null |
| MultiImplementationA.cs:30:34:30:37 | null | MultiImplementationA.cs:30:21:30:23 | enter get_P3 |
| MultiImplementationA.cs:30:34:30:37 | null | MultiImplementationB.cs:27:21:27:23 | enter get_P3 |
| MultiImplementationA.cs:36:9:36:10 | exit M1 | MultiImplementationA.cs:36:16:36:26 | throw ...; |
| MultiImplementationA.cs:36:9:36:10 | exit M1 | MultiImplementationB.cs:32:17:32:17 | 0 |
| MultiImplementationA.cs:36:16:36:26 | throw ...; | MultiImplementationA.cs:36:22:36:25 | null |
| MultiImplementationA.cs:36:22:36:25 | null | MultiImplementationA.cs:36:14:36:28 | {...} |
| MultiImplementationA.cs:37:9:37:10 | exit M2 | MultiImplementationA.cs:37:16:37:26 | throw ...; |
| MultiImplementationA.cs:37:14:37:28 | {...} | MultiImplementationA.cs:37:9:37:10 | enter M2 |
| MultiImplementationA.cs:37:16:37:26 | throw ...; | MultiImplementationA.cs:37:22:37:25 | null |
| MultiImplementationA.cs:37:22:37:25 | null | MultiImplementationA.cs:37:14:37:28 | {...} |
| MultiImplementationB.cs:3:22:3:22 | exit get_P1 | MultiImplementationA.cs:6:22:6:31 | throw ... |
| MultiImplementationB.cs:3:22:3:22 | exit get_P1 | MultiImplementationB.cs:3:22:3:22 | 0 |
| MultiImplementationB.cs:4:21:4:23 | exit get_P2 | MultiImplementationA.cs:7:27:7:37 | throw ...; |
| MultiImplementationB.cs:4:21:4:23 | exit get_P2 | MultiImplementationB.cs:4:27:4:35 | return ...; |
| MultiImplementationB.cs:4:27:4:35 | return ...; | MultiImplementationB.cs:4:34:4:34 | 1 |
| MultiImplementationB.cs:4:34:4:34 | 1 | MultiImplementationB.cs:4:25:4:37 | {...} |
| MultiImplementationB.cs:4:39:4:41 | exit set_P2 | MultiImplementationA.cs:7:47:7:57 | throw ...; |
| MultiImplementationB.cs:4:39:4:41 | exit set_P2 | MultiImplementationB.cs:4:43:4:45 | {...} |
| MultiImplementationB.cs:5:16:5:16 | exit M | MultiImplementationA.cs:8:23:8:32 | throw ... |
| MultiImplementationB.cs:5:16:5:16 | exit M | MultiImplementationB.cs:5:23:5:23 | 2 |
| MultiImplementationB.cs:11:16:11:20 | ... = ... | MultiImplementationB.cs:11:20:11:20 | 1 |
| MultiImplementationB.cs:11:20:11:20 | 1 | MultiImplementationB.cs:11:16:11:16 | this access |
| MultiImplementationB.cs:12:31:12:40 | exit get_Item | MultiImplementationA.cs:14:31:14:31 | access to parameter i |
| MultiImplementationB.cs:12:31:12:40 | exit get_Item | MultiImplementationB.cs:12:31:12:40 | throw ... |
| MultiImplementationB.cs:12:31:12:40 | throw ... | MultiImplementationB.cs:12:37:12:40 | null |
| MultiImplementationB.cs:13:36:13:38 | exit get_Item | MultiImplementationA.cs:15:42:15:50 | return ...; |
| MultiImplementationB.cs:13:36:13:38 | exit get_Item | MultiImplementationB.cs:13:42:13:52 | throw ...; |
| MultiImplementationB.cs:13:42:13:52 | throw ...; | MultiImplementationB.cs:13:48:13:51 | null |
| MultiImplementationB.cs:13:48:13:51 | null | MultiImplementationB.cs:13:40:13:54 | {...} |
| MultiImplementationB.cs:13:56:13:58 | exit set_Item | MultiImplementationA.cs:15:58:15:60 | {...} |
| MultiImplementationB.cs:13:56:13:58 | exit set_Item | MultiImplementationB.cs:13:60:13:62 | {...} |
| MultiImplementationB.cs:14:17:14:18 | exit M1 | MultiImplementationA.cs:18:9:18:22 | M2(...) |
| MultiImplementationB.cs:14:17:14:18 | exit M1 | MultiImplementationB.cs:16:9:16:31 | M2(...) |
| MultiImplementationB.cs:16:9:16:31 | M2(...) | MultiImplementationB.cs:15:5:17:5 | {...} |
| MultiImplementationB.cs:16:9:16:31 | exit M2 | MultiImplementationB.cs:16:21:16:30 | throw ... |
| MultiImplementationB.cs:16:21:16:30 | throw ... | MultiImplementationB.cs:16:27:16:30 | null |
| MultiImplementationB.cs:16:27:16:30 | null | MultiImplementationB.cs:16:9:16:31 | enter M2 |
| MultiImplementationB.cs:18:12:18:13 | exit C2 | MultiImplementationA.cs:20:24:20:28 | ... = ... |
| MultiImplementationB.cs:18:12:18:13 | exit C2 | MultiImplementationB.cs:18:24:18:34 | throw ...; |
| MultiImplementationB.cs:18:24:18:34 | throw ...; | MultiImplementationB.cs:18:30:18:33 | null |
| MultiImplementationB.cs:18:30:18:33 | null | MultiImplementationB.cs:18:22:18:36 | {...} |
| MultiImplementationB.cs:19:12:19:13 | exit C2 | MultiImplementationA.cs:21:27:21:29 | {...} |
| MultiImplementationB.cs:19:12:19:13 | exit C2 | MultiImplementationB.cs:19:27:19:29 | {...} |
| MultiImplementationB.cs:19:19:19:22 | call to constructor C2 | MultiImplementationB.cs:19:24:19:24 | 1 |
| MultiImplementationB.cs:20:6:20:7 | exit ~C2 | MultiImplementationA.cs:22:11:22:13 | {...} |
| MultiImplementationB.cs:20:6:20:7 | exit ~C2 | MultiImplementationB.cs:20:13:20:23 | throw ...; |
| MultiImplementationB.cs:20:13:20:23 | throw ...; | MultiImplementationB.cs:20:19:20:22 | null |
| MultiImplementationB.cs:20:19:20:22 | null | MultiImplementationB.cs:20:11:20:25 | {...} |
| MultiImplementationB.cs:21:28:21:35 | exit implicit conversion | MultiImplementationA.cs:23:50:23:53 | null |
| MultiImplementationB.cs:21:28:21:35 | exit implicit conversion | MultiImplementationB.cs:21:50:21:59 | throw ... |
| MultiImplementationB.cs:21:50:21:59 | throw ... | MultiImplementationB.cs:21:56:21:59 | null |
| MultiImplementationB.cs:22:16:22:16 | access to property P | MultiImplementationB.cs:22:34:22:34 | 1 |
| MultiImplementationB.cs:22:32:22:34 | ... = ... | MultiImplementationB.cs:22:16:22:16 | access to property P |
| MultiImplementationB.cs:22:34:22:34 | 1 | MultiImplementationB.cs:22:16:22:16 | this access |
| MultiImplementationB.cs:27:21:27:23 | exit get_P3 | MultiImplementationA.cs:30:28:30:37 | throw ... |
| MultiImplementationB.cs:32:9:32:10 | exit M1 | MultiImplementationA.cs:36:16:36:26 | throw ...; |
| MultiImplementationB.cs:32:9:32:10 | exit M1 | MultiImplementationB.cs:32:17:32:17 | 0 |
| NullCoalescing.cs:3:9:3:10 | exit M1 | NullCoalescing.cs:3:23:3:23 | access to parameter i |
| NullCoalescing.cs:3:9:3:10 | exit M1 | NullCoalescing.cs:3:28:3:28 | 0 |
| NullCoalescing.cs:3:23:3:23 | access to parameter i | NullCoalescing.cs:3:23:3:28 | ... ?? ... |
@@ -7386,6 +7594,265 @@ blockDominance
| LoopUnrolling.cs:72:9:73:35 | foreach (... ... in ...) ... | LoopUnrolling.cs:72:9:73:35 | foreach (... ... in ...) ... |
| LoopUnrolling.cs:72:9:73:35 | foreach (... ... in ...) ... | LoopUnrolling.cs:72:21:72:23 | String arg |
| LoopUnrolling.cs:72:21:72:23 | String arg | LoopUnrolling.cs:72:21:72:23 | String arg |
| MultiImplementationA.cs:6:22:6:31 | enter get_P1 | MultiImplementationA.cs:6:22:6:31 | enter get_P1 |
| MultiImplementationA.cs:6:22:6:31 | enter get_P1 | MultiImplementationA.cs:6:22:6:31 | exit get_P1 |
| MultiImplementationA.cs:6:22:6:31 | enter get_P1 | MultiImplementationA.cs:6:28:6:31 | null |
| MultiImplementationA.cs:6:22:6:31 | enter get_P1 | MultiImplementationB.cs:3:22:3:22 | 0 |
| MultiImplementationA.cs:6:22:6:31 | enter get_P1 | MultiImplementationB.cs:3:22:3:22 | enter get_P1 |
| MultiImplementationA.cs:6:22:6:31 | enter get_P1 | MultiImplementationB.cs:3:22:3:22 | exit get_P1 |
| MultiImplementationA.cs:6:22:6:31 | exit get_P1 | MultiImplementationA.cs:6:22:6:31 | exit get_P1 |
| MultiImplementationA.cs:6:22:6:31 | exit get_P1 | MultiImplementationB.cs:3:22:3:22 | exit get_P1 |
| MultiImplementationA.cs:6:28:6:31 | null | MultiImplementationA.cs:6:28:6:31 | null |
| MultiImplementationA.cs:7:21:7:23 | enter get_P2 | MultiImplementationA.cs:7:21:7:23 | enter get_P2 |
| MultiImplementationA.cs:7:21:7:23 | enter get_P2 | MultiImplementationA.cs:7:21:7:23 | exit get_P2 |
| MultiImplementationA.cs:7:21:7:23 | enter get_P2 | MultiImplementationA.cs:7:25:7:39 | {...} |
| MultiImplementationA.cs:7:21:7:23 | enter get_P2 | MultiImplementationB.cs:4:21:4:23 | enter get_P2 |
| MultiImplementationA.cs:7:21:7:23 | enter get_P2 | MultiImplementationB.cs:4:21:4:23 | exit get_P2 |
| MultiImplementationA.cs:7:21:7:23 | enter get_P2 | MultiImplementationB.cs:4:25:4:37 | {...} |
| MultiImplementationA.cs:7:21:7:23 | exit get_P2 | MultiImplementationA.cs:7:21:7:23 | exit get_P2 |
| MultiImplementationA.cs:7:21:7:23 | exit get_P2 | MultiImplementationB.cs:4:21:4:23 | exit get_P2 |
| MultiImplementationA.cs:7:25:7:39 | {...} | MultiImplementationA.cs:7:25:7:39 | {...} |
| MultiImplementationA.cs:7:41:7:43 | enter set_P2 | MultiImplementationA.cs:7:41:7:43 | enter set_P2 |
| MultiImplementationA.cs:7:41:7:43 | enter set_P2 | MultiImplementationA.cs:7:41:7:43 | exit set_P2 |
| MultiImplementationA.cs:7:41:7:43 | enter set_P2 | MultiImplementationA.cs:7:45:7:59 | {...} |
| MultiImplementationA.cs:7:41:7:43 | enter set_P2 | MultiImplementationB.cs:4:39:4:41 | enter set_P2 |
| MultiImplementationA.cs:7:41:7:43 | enter set_P2 | MultiImplementationB.cs:4:39:4:41 | exit set_P2 |
| MultiImplementationA.cs:7:41:7:43 | enter set_P2 | MultiImplementationB.cs:4:43:4:45 | {...} |
| MultiImplementationA.cs:7:41:7:43 | exit set_P2 | MultiImplementationA.cs:7:41:7:43 | exit set_P2 |
| MultiImplementationA.cs:7:41:7:43 | exit set_P2 | MultiImplementationB.cs:4:39:4:41 | exit set_P2 |
| MultiImplementationA.cs:7:45:7:59 | {...} | MultiImplementationA.cs:7:45:7:59 | {...} |
| MultiImplementationA.cs:8:16:8:16 | enter M | MultiImplementationA.cs:8:16:8:16 | enter M |
| MultiImplementationA.cs:8:16:8:16 | enter M | MultiImplementationA.cs:8:16:8:16 | exit M |
| MultiImplementationA.cs:8:16:8:16 | enter M | MultiImplementationA.cs:8:29:8:32 | null |
| MultiImplementationA.cs:8:16:8:16 | enter M | MultiImplementationB.cs:5:16:5:16 | enter M |
| MultiImplementationA.cs:8:16:8:16 | enter M | MultiImplementationB.cs:5:16:5:16 | exit M |
| MultiImplementationA.cs:8:16:8:16 | enter M | MultiImplementationB.cs:5:23:5:23 | 2 |
| MultiImplementationA.cs:8:16:8:16 | exit M | MultiImplementationA.cs:8:16:8:16 | exit M |
| MultiImplementationA.cs:8:16:8:16 | exit M | MultiImplementationB.cs:5:16:5:16 | exit M |
| MultiImplementationA.cs:8:29:8:32 | null | MultiImplementationA.cs:8:29:8:32 | null |
| MultiImplementationA.cs:13:16:13:16 | this access | MultiImplementationA.cs:13:16:13:16 | this access |
| MultiImplementationA.cs:14:31:14:31 | access to parameter i | MultiImplementationA.cs:14:31:14:31 | access to parameter i |
| MultiImplementationA.cs:14:31:14:31 | enter get_Item | MultiImplementationA.cs:14:31:14:31 | access to parameter i |
| MultiImplementationA.cs:14:31:14:31 | enter get_Item | MultiImplementationA.cs:14:31:14:31 | enter get_Item |
| MultiImplementationA.cs:14:31:14:31 | enter get_Item | MultiImplementationA.cs:14:31:14:31 | exit get_Item |
| MultiImplementationA.cs:14:31:14:31 | enter get_Item | MultiImplementationB.cs:12:31:12:40 | enter get_Item |
| MultiImplementationA.cs:14:31:14:31 | enter get_Item | MultiImplementationB.cs:12:31:12:40 | exit get_Item |
| MultiImplementationA.cs:14:31:14:31 | enter get_Item | MultiImplementationB.cs:12:37:12:40 | null |
| MultiImplementationA.cs:14:31:14:31 | exit get_Item | MultiImplementationA.cs:14:31:14:31 | exit get_Item |
| MultiImplementationA.cs:14:31:14:31 | exit get_Item | MultiImplementationB.cs:12:31:12:40 | exit get_Item |
| MultiImplementationA.cs:15:36:15:38 | enter get_Item | MultiImplementationA.cs:15:36:15:38 | enter get_Item |
| MultiImplementationA.cs:15:36:15:38 | enter get_Item | MultiImplementationA.cs:15:36:15:38 | exit get_Item |
| MultiImplementationA.cs:15:36:15:38 | enter get_Item | MultiImplementationA.cs:15:40:15:52 | {...} |
| MultiImplementationA.cs:15:36:15:38 | enter get_Item | MultiImplementationB.cs:13:36:13:38 | enter get_Item |
| MultiImplementationA.cs:15:36:15:38 | enter get_Item | MultiImplementationB.cs:13:36:13:38 | exit get_Item |
| MultiImplementationA.cs:15:36:15:38 | enter get_Item | MultiImplementationB.cs:13:40:13:54 | {...} |
| MultiImplementationA.cs:15:36:15:38 | exit get_Item | MultiImplementationA.cs:15:36:15:38 | exit get_Item |
| MultiImplementationA.cs:15:36:15:38 | exit get_Item | MultiImplementationB.cs:13:36:13:38 | exit get_Item |
| MultiImplementationA.cs:15:40:15:52 | {...} | MultiImplementationA.cs:15:40:15:52 | {...} |
| MultiImplementationA.cs:15:54:15:56 | enter set_Item | MultiImplementationA.cs:15:54:15:56 | enter set_Item |
| MultiImplementationA.cs:15:54:15:56 | enter set_Item | MultiImplementationA.cs:15:54:15:56 | exit set_Item |
| MultiImplementationA.cs:15:54:15:56 | enter set_Item | MultiImplementationA.cs:15:58:15:60 | {...} |
| MultiImplementationA.cs:15:54:15:56 | enter set_Item | MultiImplementationB.cs:13:56:13:58 | enter set_Item |
| MultiImplementationA.cs:15:54:15:56 | enter set_Item | MultiImplementationB.cs:13:56:13:58 | exit set_Item |
| MultiImplementationA.cs:15:54:15:56 | enter set_Item | MultiImplementationB.cs:13:60:13:62 | {...} |
| MultiImplementationA.cs:15:54:15:56 | exit set_Item | MultiImplementationA.cs:15:54:15:56 | exit set_Item |
| MultiImplementationA.cs:15:54:15:56 | exit set_Item | MultiImplementationB.cs:13:56:13:58 | exit set_Item |
| MultiImplementationA.cs:15:58:15:60 | {...} | MultiImplementationA.cs:15:58:15:60 | {...} |
| MultiImplementationA.cs:16:17:16:18 | enter M1 | MultiImplementationA.cs:16:17:16:18 | enter M1 |
| MultiImplementationA.cs:16:17:16:18 | enter M1 | MultiImplementationA.cs:16:17:16:18 | exit M1 |
| MultiImplementationA.cs:16:17:16:18 | enter M1 | MultiImplementationA.cs:17:5:19:5 | {...} |
| MultiImplementationA.cs:16:17:16:18 | enter M1 | MultiImplementationB.cs:14:17:14:18 | enter M1 |
| MultiImplementationA.cs:16:17:16:18 | enter M1 | MultiImplementationB.cs:14:17:14:18 | exit M1 |
| MultiImplementationA.cs:16:17:16:18 | enter M1 | MultiImplementationB.cs:15:5:17:5 | {...} |
| MultiImplementationA.cs:16:17:16:18 | exit M1 | MultiImplementationA.cs:16:17:16:18 | exit M1 |
| MultiImplementationA.cs:16:17:16:18 | exit M1 | MultiImplementationB.cs:14:17:14:18 | exit M1 |
| MultiImplementationA.cs:17:5:19:5 | {...} | MultiImplementationA.cs:17:5:19:5 | {...} |
| MultiImplementationA.cs:18:9:18:22 | enter M2 | MultiImplementationA.cs:18:9:18:22 | enter M2 |
| MultiImplementationA.cs:20:12:20:13 | enter C2 | MultiImplementationA.cs:13:16:13:16 | this access |
| MultiImplementationA.cs:20:12:20:13 | enter C2 | MultiImplementationA.cs:20:12:20:13 | enter C2 |
| MultiImplementationA.cs:20:12:20:13 | enter C2 | MultiImplementationA.cs:20:12:20:13 | exit C2 |
| MultiImplementationA.cs:20:12:20:13 | enter C2 | MultiImplementationA.cs:20:22:20:31 | {...} |
| MultiImplementationA.cs:20:12:20:13 | enter C2 | MultiImplementationA.cs:24:16:24:16 | this access |
| MultiImplementationA.cs:20:12:20:13 | enter C2 | MultiImplementationB.cs:11:16:11:16 | this access |
| MultiImplementationA.cs:20:12:20:13 | enter C2 | MultiImplementationB.cs:18:12:18:13 | enter C2 |
| MultiImplementationA.cs:20:12:20:13 | enter C2 | MultiImplementationB.cs:18:12:18:13 | exit C2 |
| MultiImplementationA.cs:20:12:20:13 | enter C2 | MultiImplementationB.cs:18:22:18:36 | {...} |
| MultiImplementationA.cs:20:12:20:13 | enter C2 | MultiImplementationB.cs:22:16:22:16 | this access |
| MultiImplementationA.cs:20:12:20:13 | exit C2 | MultiImplementationA.cs:20:12:20:13 | exit C2 |
| MultiImplementationA.cs:20:12:20:13 | exit C2 | MultiImplementationB.cs:18:12:18:13 | exit C2 |
| MultiImplementationA.cs:20:22:20:31 | {...} | MultiImplementationA.cs:20:22:20:31 | {...} |
| MultiImplementationA.cs:21:12:21:13 | enter C2 | MultiImplementationA.cs:21:12:21:13 | enter C2 |
| MultiImplementationA.cs:21:12:21:13 | enter C2 | MultiImplementationA.cs:21:12:21:13 | exit C2 |
| MultiImplementationA.cs:21:12:21:13 | enter C2 | MultiImplementationA.cs:21:24:21:24 | 0 |
| MultiImplementationA.cs:21:12:21:13 | enter C2 | MultiImplementationA.cs:21:27:21:29 | {...} |
| MultiImplementationA.cs:21:12:21:13 | enter C2 | MultiImplementationB.cs:19:12:19:13 | enter C2 |
| MultiImplementationA.cs:21:12:21:13 | enter C2 | MultiImplementationB.cs:19:12:19:13 | exit C2 |
| MultiImplementationA.cs:21:12:21:13 | enter C2 | MultiImplementationB.cs:19:24:19:24 | 1 |
| MultiImplementationA.cs:21:12:21:13 | enter C2 | MultiImplementationB.cs:19:27:19:29 | {...} |
| MultiImplementationA.cs:21:12:21:13 | exit C2 | MultiImplementationA.cs:21:12:21:13 | exit C2 |
| MultiImplementationA.cs:21:12:21:13 | exit C2 | MultiImplementationB.cs:19:12:19:13 | exit C2 |
| MultiImplementationA.cs:21:24:21:24 | 0 | MultiImplementationA.cs:21:24:21:24 | 0 |
| MultiImplementationA.cs:21:27:21:29 | {...} | MultiImplementationA.cs:21:27:21:29 | {...} |
| MultiImplementationA.cs:22:6:22:7 | enter ~C2 | MultiImplementationA.cs:22:6:22:7 | enter ~C2 |
| MultiImplementationA.cs:22:6:22:7 | enter ~C2 | MultiImplementationA.cs:22:6:22:7 | exit ~C2 |
| MultiImplementationA.cs:22:6:22:7 | enter ~C2 | MultiImplementationA.cs:22:11:22:13 | {...} |
| MultiImplementationA.cs:22:6:22:7 | enter ~C2 | MultiImplementationB.cs:20:6:20:7 | enter ~C2 |
| MultiImplementationA.cs:22:6:22:7 | enter ~C2 | MultiImplementationB.cs:20:6:20:7 | exit ~C2 |
| MultiImplementationA.cs:22:6:22:7 | enter ~C2 | MultiImplementationB.cs:20:11:20:25 | {...} |
| MultiImplementationA.cs:22:6:22:7 | exit ~C2 | MultiImplementationA.cs:22:6:22:7 | exit ~C2 |
| MultiImplementationA.cs:22:6:22:7 | exit ~C2 | MultiImplementationB.cs:20:6:20:7 | exit ~C2 |
| MultiImplementationA.cs:22:11:22:13 | {...} | MultiImplementationA.cs:22:11:22:13 | {...} |
| MultiImplementationA.cs:23:28:23:35 | enter implicit conversion | MultiImplementationA.cs:23:28:23:35 | enter implicit conversion |
| MultiImplementationA.cs:23:28:23:35 | enter implicit conversion | MultiImplementationA.cs:23:28:23:35 | exit implicit conversion |
| MultiImplementationA.cs:23:28:23:35 | enter implicit conversion | MultiImplementationA.cs:23:50:23:53 | null |
| MultiImplementationA.cs:23:28:23:35 | enter implicit conversion | MultiImplementationB.cs:21:28:21:35 | enter implicit conversion |
| MultiImplementationA.cs:23:28:23:35 | enter implicit conversion | MultiImplementationB.cs:21:28:21:35 | exit implicit conversion |
| MultiImplementationA.cs:23:28:23:35 | enter implicit conversion | MultiImplementationB.cs:21:56:21:59 | null |
| MultiImplementationA.cs:23:28:23:35 | exit implicit conversion | MultiImplementationA.cs:23:28:23:35 | exit implicit conversion |
| MultiImplementationA.cs:23:28:23:35 | exit implicit conversion | MultiImplementationB.cs:21:28:21:35 | exit implicit conversion |
| MultiImplementationA.cs:23:50:23:53 | null | MultiImplementationA.cs:23:50:23:53 | null |
| MultiImplementationA.cs:24:16:24:16 | this access | MultiImplementationA.cs:24:16:24:16 | this access |
| MultiImplementationA.cs:30:21:30:23 | enter get_P3 | MultiImplementationA.cs:30:21:30:23 | enter get_P3 |
| MultiImplementationA.cs:30:21:30:23 | enter get_P3 | MultiImplementationB.cs:27:21:27:23 | enter get_P3 |
| MultiImplementationA.cs:36:9:36:10 | enter M1 | MultiImplementationA.cs:36:9:36:10 | enter M1 |
| MultiImplementationA.cs:36:9:36:10 | enter M1 | MultiImplementationA.cs:36:9:36:10 | exit M1 |
| MultiImplementationA.cs:36:9:36:10 | enter M1 | MultiImplementationA.cs:36:14:36:28 | {...} |
| MultiImplementationA.cs:36:9:36:10 | enter M1 | MultiImplementationB.cs:32:9:32:10 | enter M1 |
| MultiImplementationA.cs:36:9:36:10 | enter M1 | MultiImplementationB.cs:32:9:32:10 | exit M1 |
| MultiImplementationA.cs:36:9:36:10 | enter M1 | MultiImplementationB.cs:32:17:32:17 | 0 |
| MultiImplementationA.cs:36:9:36:10 | exit M1 | MultiImplementationA.cs:36:9:36:10 | exit M1 |
| MultiImplementationA.cs:36:9:36:10 | exit M1 | MultiImplementationB.cs:32:9:32:10 | exit M1 |
| MultiImplementationA.cs:36:14:36:28 | {...} | MultiImplementationA.cs:36:14:36:28 | {...} |
| MultiImplementationA.cs:37:9:37:10 | enter M2 | MultiImplementationA.cs:37:9:37:10 | enter M2 |
| MultiImplementationB.cs:3:22:3:22 | 0 | MultiImplementationB.cs:3:22:3:22 | 0 |
| MultiImplementationB.cs:3:22:3:22 | enter get_P1 | MultiImplementationA.cs:6:22:6:31 | enter get_P1 |
| MultiImplementationB.cs:3:22:3:22 | enter get_P1 | MultiImplementationA.cs:6:22:6:31 | exit get_P1 |
| MultiImplementationB.cs:3:22:3:22 | enter get_P1 | MultiImplementationA.cs:6:28:6:31 | null |
| MultiImplementationB.cs:3:22:3:22 | enter get_P1 | MultiImplementationB.cs:3:22:3:22 | 0 |
| MultiImplementationB.cs:3:22:3:22 | enter get_P1 | MultiImplementationB.cs:3:22:3:22 | enter get_P1 |
| MultiImplementationB.cs:3:22:3:22 | enter get_P1 | MultiImplementationB.cs:3:22:3:22 | exit get_P1 |
| MultiImplementationB.cs:3:22:3:22 | exit get_P1 | MultiImplementationA.cs:6:22:6:31 | exit get_P1 |
| MultiImplementationB.cs:3:22:3:22 | exit get_P1 | MultiImplementationB.cs:3:22:3:22 | exit get_P1 |
| MultiImplementationB.cs:4:21:4:23 | enter get_P2 | MultiImplementationA.cs:7:21:7:23 | enter get_P2 |
| MultiImplementationB.cs:4:21:4:23 | enter get_P2 | MultiImplementationA.cs:7:21:7:23 | exit get_P2 |
| MultiImplementationB.cs:4:21:4:23 | enter get_P2 | MultiImplementationA.cs:7:25:7:39 | {...} |
| MultiImplementationB.cs:4:21:4:23 | enter get_P2 | MultiImplementationB.cs:4:21:4:23 | enter get_P2 |
| MultiImplementationB.cs:4:21:4:23 | enter get_P2 | MultiImplementationB.cs:4:21:4:23 | exit get_P2 |
| MultiImplementationB.cs:4:21:4:23 | enter get_P2 | MultiImplementationB.cs:4:25:4:37 | {...} |
| MultiImplementationB.cs:4:21:4:23 | exit get_P2 | MultiImplementationA.cs:7:21:7:23 | exit get_P2 |
| MultiImplementationB.cs:4:21:4:23 | exit get_P2 | MultiImplementationB.cs:4:21:4:23 | exit get_P2 |
| MultiImplementationB.cs:4:25:4:37 | {...} | MultiImplementationB.cs:4:25:4:37 | {...} |
| MultiImplementationB.cs:4:39:4:41 | enter set_P2 | MultiImplementationA.cs:7:41:7:43 | enter set_P2 |
| MultiImplementationB.cs:4:39:4:41 | enter set_P2 | MultiImplementationA.cs:7:41:7:43 | exit set_P2 |
| MultiImplementationB.cs:4:39:4:41 | enter set_P2 | MultiImplementationA.cs:7:45:7:59 | {...} |
| MultiImplementationB.cs:4:39:4:41 | enter set_P2 | MultiImplementationB.cs:4:39:4:41 | enter set_P2 |
| MultiImplementationB.cs:4:39:4:41 | enter set_P2 | MultiImplementationB.cs:4:39:4:41 | exit set_P2 |
| MultiImplementationB.cs:4:39:4:41 | enter set_P2 | MultiImplementationB.cs:4:43:4:45 | {...} |
| MultiImplementationB.cs:4:39:4:41 | exit set_P2 | MultiImplementationA.cs:7:41:7:43 | exit set_P2 |
| MultiImplementationB.cs:4:39:4:41 | exit set_P2 | MultiImplementationB.cs:4:39:4:41 | exit set_P2 |
| MultiImplementationB.cs:4:43:4:45 | {...} | MultiImplementationB.cs:4:43:4:45 | {...} |
| MultiImplementationB.cs:5:16:5:16 | enter M | MultiImplementationA.cs:8:16:8:16 | enter M |
| MultiImplementationB.cs:5:16:5:16 | enter M | MultiImplementationA.cs:8:16:8:16 | exit M |
| MultiImplementationB.cs:5:16:5:16 | enter M | MultiImplementationA.cs:8:29:8:32 | null |
| MultiImplementationB.cs:5:16:5:16 | enter M | MultiImplementationB.cs:5:16:5:16 | enter M |
| MultiImplementationB.cs:5:16:5:16 | enter M | MultiImplementationB.cs:5:16:5:16 | exit M |
| MultiImplementationB.cs:5:16:5:16 | enter M | MultiImplementationB.cs:5:23:5:23 | 2 |
| MultiImplementationB.cs:5:16:5:16 | exit M | MultiImplementationA.cs:8:16:8:16 | exit M |
| MultiImplementationB.cs:5:16:5:16 | exit M | MultiImplementationB.cs:5:16:5:16 | exit M |
| MultiImplementationB.cs:5:23:5:23 | 2 | MultiImplementationB.cs:5:23:5:23 | 2 |
| MultiImplementationB.cs:11:16:11:16 | this access | MultiImplementationB.cs:11:16:11:16 | this access |
| MultiImplementationB.cs:12:31:12:40 | enter get_Item | MultiImplementationA.cs:14:31:14:31 | access to parameter i |
| MultiImplementationB.cs:12:31:12:40 | enter get_Item | MultiImplementationA.cs:14:31:14:31 | enter get_Item |
| MultiImplementationB.cs:12:31:12:40 | enter get_Item | MultiImplementationA.cs:14:31:14:31 | exit get_Item |
| MultiImplementationB.cs:12:31:12:40 | enter get_Item | MultiImplementationB.cs:12:31:12:40 | enter get_Item |
| MultiImplementationB.cs:12:31:12:40 | enter get_Item | MultiImplementationB.cs:12:31:12:40 | exit get_Item |
| MultiImplementationB.cs:12:31:12:40 | enter get_Item | MultiImplementationB.cs:12:37:12:40 | null |
| MultiImplementationB.cs:12:31:12:40 | exit get_Item | MultiImplementationA.cs:14:31:14:31 | exit get_Item |
| MultiImplementationB.cs:12:31:12:40 | exit get_Item | MultiImplementationB.cs:12:31:12:40 | exit get_Item |
| MultiImplementationB.cs:12:37:12:40 | null | MultiImplementationB.cs:12:37:12:40 | null |
| MultiImplementationB.cs:13:36:13:38 | enter get_Item | MultiImplementationA.cs:15:36:15:38 | enter get_Item |
| MultiImplementationB.cs:13:36:13:38 | enter get_Item | MultiImplementationA.cs:15:36:15:38 | exit get_Item |
| MultiImplementationB.cs:13:36:13:38 | enter get_Item | MultiImplementationA.cs:15:40:15:52 | {...} |
| MultiImplementationB.cs:13:36:13:38 | enter get_Item | MultiImplementationB.cs:13:36:13:38 | enter get_Item |
| MultiImplementationB.cs:13:36:13:38 | enter get_Item | MultiImplementationB.cs:13:36:13:38 | exit get_Item |
| MultiImplementationB.cs:13:36:13:38 | enter get_Item | MultiImplementationB.cs:13:40:13:54 | {...} |
| MultiImplementationB.cs:13:36:13:38 | exit get_Item | MultiImplementationA.cs:15:36:15:38 | exit get_Item |
| MultiImplementationB.cs:13:36:13:38 | exit get_Item | MultiImplementationB.cs:13:36:13:38 | exit get_Item |
| MultiImplementationB.cs:13:40:13:54 | {...} | MultiImplementationB.cs:13:40:13:54 | {...} |
| MultiImplementationB.cs:13:56:13:58 | enter set_Item | MultiImplementationA.cs:15:54:15:56 | enter set_Item |
| MultiImplementationB.cs:13:56:13:58 | enter set_Item | MultiImplementationA.cs:15:54:15:56 | exit set_Item |
| MultiImplementationB.cs:13:56:13:58 | enter set_Item | MultiImplementationA.cs:15:58:15:60 | {...} |
| MultiImplementationB.cs:13:56:13:58 | enter set_Item | MultiImplementationB.cs:13:56:13:58 | enter set_Item |
| MultiImplementationB.cs:13:56:13:58 | enter set_Item | MultiImplementationB.cs:13:56:13:58 | exit set_Item |
| MultiImplementationB.cs:13:56:13:58 | enter set_Item | MultiImplementationB.cs:13:60:13:62 | {...} |
| MultiImplementationB.cs:13:56:13:58 | exit set_Item | MultiImplementationA.cs:15:54:15:56 | exit set_Item |
| MultiImplementationB.cs:13:56:13:58 | exit set_Item | MultiImplementationB.cs:13:56:13:58 | exit set_Item |
| MultiImplementationB.cs:13:60:13:62 | {...} | MultiImplementationB.cs:13:60:13:62 | {...} |
| MultiImplementationB.cs:14:17:14:18 | enter M1 | MultiImplementationA.cs:16:17:16:18 | enter M1 |
| MultiImplementationB.cs:14:17:14:18 | enter M1 | MultiImplementationA.cs:16:17:16:18 | exit M1 |
| MultiImplementationB.cs:14:17:14:18 | enter M1 | MultiImplementationA.cs:17:5:19:5 | {...} |
| MultiImplementationB.cs:14:17:14:18 | enter M1 | MultiImplementationB.cs:14:17:14:18 | enter M1 |
| MultiImplementationB.cs:14:17:14:18 | enter M1 | MultiImplementationB.cs:14:17:14:18 | exit M1 |
| MultiImplementationB.cs:14:17:14:18 | enter M1 | MultiImplementationB.cs:15:5:17:5 | {...} |
| MultiImplementationB.cs:14:17:14:18 | exit M1 | MultiImplementationA.cs:16:17:16:18 | exit M1 |
| MultiImplementationB.cs:14:17:14:18 | exit M1 | MultiImplementationB.cs:14:17:14:18 | exit M1 |
| MultiImplementationB.cs:15:5:17:5 | {...} | MultiImplementationB.cs:15:5:17:5 | {...} |
| MultiImplementationB.cs:16:9:16:31 | enter M2 | MultiImplementationB.cs:16:9:16:31 | enter M2 |
| MultiImplementationB.cs:18:12:18:13 | enter C2 | MultiImplementationA.cs:13:16:13:16 | this access |
| MultiImplementationB.cs:18:12:18:13 | enter C2 | MultiImplementationA.cs:20:12:20:13 | enter C2 |
| MultiImplementationB.cs:18:12:18:13 | enter C2 | MultiImplementationA.cs:20:12:20:13 | exit C2 |
| MultiImplementationB.cs:18:12:18:13 | enter C2 | MultiImplementationA.cs:20:22:20:31 | {...} |
| MultiImplementationB.cs:18:12:18:13 | enter C2 | MultiImplementationA.cs:24:16:24:16 | this access |
| MultiImplementationB.cs:18:12:18:13 | enter C2 | MultiImplementationB.cs:11:16:11:16 | this access |
| MultiImplementationB.cs:18:12:18:13 | enter C2 | MultiImplementationB.cs:18:12:18:13 | enter C2 |
| MultiImplementationB.cs:18:12:18:13 | enter C2 | MultiImplementationB.cs:18:12:18:13 | exit C2 |
| MultiImplementationB.cs:18:12:18:13 | enter C2 | MultiImplementationB.cs:18:22:18:36 | {...} |
| MultiImplementationB.cs:18:12:18:13 | enter C2 | MultiImplementationB.cs:22:16:22:16 | this access |
| MultiImplementationB.cs:18:12:18:13 | exit C2 | MultiImplementationA.cs:20:12:20:13 | exit C2 |
| MultiImplementationB.cs:18:12:18:13 | exit C2 | MultiImplementationB.cs:18:12:18:13 | exit C2 |
| MultiImplementationB.cs:18:22:18:36 | {...} | MultiImplementationB.cs:18:22:18:36 | {...} |
| MultiImplementationB.cs:19:12:19:13 | enter C2 | MultiImplementationA.cs:21:12:21:13 | enter C2 |
| MultiImplementationB.cs:19:12:19:13 | enter C2 | MultiImplementationA.cs:21:12:21:13 | exit C2 |
| MultiImplementationB.cs:19:12:19:13 | enter C2 | MultiImplementationA.cs:21:24:21:24 | 0 |
| MultiImplementationB.cs:19:12:19:13 | enter C2 | MultiImplementationA.cs:21:27:21:29 | {...} |
| MultiImplementationB.cs:19:12:19:13 | enter C2 | MultiImplementationB.cs:19:12:19:13 | enter C2 |
| MultiImplementationB.cs:19:12:19:13 | enter C2 | MultiImplementationB.cs:19:12:19:13 | exit C2 |
| MultiImplementationB.cs:19:12:19:13 | enter C2 | MultiImplementationB.cs:19:24:19:24 | 1 |
| MultiImplementationB.cs:19:12:19:13 | enter C2 | MultiImplementationB.cs:19:27:19:29 | {...} |
| MultiImplementationB.cs:19:12:19:13 | exit C2 | MultiImplementationA.cs:21:12:21:13 | exit C2 |
| MultiImplementationB.cs:19:12:19:13 | exit C2 | MultiImplementationB.cs:19:12:19:13 | exit C2 |
| MultiImplementationB.cs:19:24:19:24 | 1 | MultiImplementationB.cs:19:24:19:24 | 1 |
| MultiImplementationB.cs:19:27:19:29 | {...} | MultiImplementationB.cs:19:27:19:29 | {...} |
| MultiImplementationB.cs:20:6:20:7 | enter ~C2 | MultiImplementationA.cs:22:6:22:7 | enter ~C2 |
| MultiImplementationB.cs:20:6:20:7 | enter ~C2 | MultiImplementationA.cs:22:6:22:7 | exit ~C2 |
| MultiImplementationB.cs:20:6:20:7 | enter ~C2 | MultiImplementationA.cs:22:11:22:13 | {...} |
| MultiImplementationB.cs:20:6:20:7 | enter ~C2 | MultiImplementationB.cs:20:6:20:7 | enter ~C2 |
| MultiImplementationB.cs:20:6:20:7 | enter ~C2 | MultiImplementationB.cs:20:6:20:7 | exit ~C2 |
| MultiImplementationB.cs:20:6:20:7 | enter ~C2 | MultiImplementationB.cs:20:11:20:25 | {...} |
| MultiImplementationB.cs:20:6:20:7 | exit ~C2 | MultiImplementationA.cs:22:6:22:7 | exit ~C2 |
| MultiImplementationB.cs:20:6:20:7 | exit ~C2 | MultiImplementationB.cs:20:6:20:7 | exit ~C2 |
| MultiImplementationB.cs:20:11:20:25 | {...} | MultiImplementationB.cs:20:11:20:25 | {...} |
| MultiImplementationB.cs:21:28:21:35 | enter implicit conversion | MultiImplementationA.cs:23:28:23:35 | enter implicit conversion |
| MultiImplementationB.cs:21:28:21:35 | enter implicit conversion | MultiImplementationA.cs:23:28:23:35 | exit implicit conversion |
| MultiImplementationB.cs:21:28:21:35 | enter implicit conversion | MultiImplementationA.cs:23:50:23:53 | null |
| MultiImplementationB.cs:21:28:21:35 | enter implicit conversion | MultiImplementationB.cs:21:28:21:35 | enter implicit conversion |
| MultiImplementationB.cs:21:28:21:35 | enter implicit conversion | MultiImplementationB.cs:21:28:21:35 | exit implicit conversion |
| MultiImplementationB.cs:21:28:21:35 | enter implicit conversion | MultiImplementationB.cs:21:56:21:59 | null |
| MultiImplementationB.cs:21:28:21:35 | exit implicit conversion | MultiImplementationA.cs:23:28:23:35 | exit implicit conversion |
| MultiImplementationB.cs:21:28:21:35 | exit implicit conversion | MultiImplementationB.cs:21:28:21:35 | exit implicit conversion |
| MultiImplementationB.cs:21:56:21:59 | null | MultiImplementationB.cs:21:56:21:59 | null |
| MultiImplementationB.cs:22:16:22:16 | this access | MultiImplementationB.cs:22:16:22:16 | this access |
| MultiImplementationB.cs:27:21:27:23 | enter get_P3 | MultiImplementationA.cs:30:21:30:23 | enter get_P3 |
| MultiImplementationB.cs:27:21:27:23 | enter get_P3 | MultiImplementationB.cs:27:21:27:23 | enter get_P3 |
| MultiImplementationB.cs:32:9:32:10 | enter M1 | MultiImplementationA.cs:36:9:36:10 | enter M1 |
| MultiImplementationB.cs:32:9:32:10 | enter M1 | MultiImplementationA.cs:36:9:36:10 | exit M1 |
| MultiImplementationB.cs:32:9:32:10 | enter M1 | MultiImplementationA.cs:36:14:36:28 | {...} |
| MultiImplementationB.cs:32:9:32:10 | enter M1 | MultiImplementationB.cs:32:9:32:10 | enter M1 |
| MultiImplementationB.cs:32:9:32:10 | enter M1 | MultiImplementationB.cs:32:9:32:10 | exit M1 |
| MultiImplementationB.cs:32:9:32:10 | enter M1 | MultiImplementationB.cs:32:17:32:17 | 0 |
| MultiImplementationB.cs:32:9:32:10 | exit M1 | MultiImplementationA.cs:36:9:36:10 | exit M1 |
| MultiImplementationB.cs:32:9:32:10 | exit M1 | MultiImplementationB.cs:32:9:32:10 | exit M1 |
| MultiImplementationB.cs:32:17:32:17 | 0 | MultiImplementationB.cs:32:17:32:17 | 0 |
| NullCoalescing.cs:3:9:3:10 | enter M1 | NullCoalescing.cs:3:9:3:10 | enter M1 |
| NullCoalescing.cs:3:9:3:10 | enter M1 | NullCoalescing.cs:3:9:3:10 | exit M1 |
| NullCoalescing.cs:3:9:3:10 | enter M1 | NullCoalescing.cs:3:28:3:28 | 0 |
@@ -9210,6 +9677,265 @@ postBlockDominance
| LoopUnrolling.cs:72:9:73:35 | foreach (... ... in ...) ... | LoopUnrolling.cs:72:9:73:35 | foreach (... ... in ...) ... |
| LoopUnrolling.cs:72:9:73:35 | foreach (... ... in ...) ... | LoopUnrolling.cs:72:21:72:23 | String arg |
| LoopUnrolling.cs:72:21:72:23 | String arg | LoopUnrolling.cs:72:21:72:23 | String arg |
| MultiImplementationA.cs:6:22:6:31 | enter get_P1 | MultiImplementationA.cs:6:22:6:31 | enter get_P1 |
| MultiImplementationA.cs:6:22:6:31 | enter get_P1 | MultiImplementationB.cs:3:22:3:22 | enter get_P1 |
| MultiImplementationA.cs:6:22:6:31 | exit get_P1 | MultiImplementationA.cs:6:22:6:31 | enter get_P1 |
| MultiImplementationA.cs:6:22:6:31 | exit get_P1 | MultiImplementationA.cs:6:22:6:31 | exit get_P1 |
| MultiImplementationA.cs:6:22:6:31 | exit get_P1 | MultiImplementationA.cs:6:28:6:31 | null |
| MultiImplementationA.cs:6:22:6:31 | exit get_P1 | MultiImplementationB.cs:3:22:3:22 | 0 |
| MultiImplementationA.cs:6:22:6:31 | exit get_P1 | MultiImplementationB.cs:3:22:3:22 | enter get_P1 |
| MultiImplementationA.cs:6:22:6:31 | exit get_P1 | MultiImplementationB.cs:3:22:3:22 | exit get_P1 |
| MultiImplementationA.cs:6:28:6:31 | null | MultiImplementationA.cs:6:28:6:31 | null |
| MultiImplementationA.cs:7:21:7:23 | enter get_P2 | MultiImplementationA.cs:7:21:7:23 | enter get_P2 |
| MultiImplementationA.cs:7:21:7:23 | enter get_P2 | MultiImplementationB.cs:4:21:4:23 | enter get_P2 |
| MultiImplementationA.cs:7:21:7:23 | exit get_P2 | MultiImplementationA.cs:7:21:7:23 | enter get_P2 |
| MultiImplementationA.cs:7:21:7:23 | exit get_P2 | MultiImplementationA.cs:7:21:7:23 | exit get_P2 |
| MultiImplementationA.cs:7:21:7:23 | exit get_P2 | MultiImplementationA.cs:7:25:7:39 | {...} |
| MultiImplementationA.cs:7:21:7:23 | exit get_P2 | MultiImplementationB.cs:4:21:4:23 | enter get_P2 |
| MultiImplementationA.cs:7:21:7:23 | exit get_P2 | MultiImplementationB.cs:4:21:4:23 | exit get_P2 |
| MultiImplementationA.cs:7:21:7:23 | exit get_P2 | MultiImplementationB.cs:4:25:4:37 | {...} |
| MultiImplementationA.cs:7:25:7:39 | {...} | MultiImplementationA.cs:7:25:7:39 | {...} |
| MultiImplementationA.cs:7:41:7:43 | enter set_P2 | MultiImplementationA.cs:7:41:7:43 | enter set_P2 |
| MultiImplementationA.cs:7:41:7:43 | enter set_P2 | MultiImplementationB.cs:4:39:4:41 | enter set_P2 |
| MultiImplementationA.cs:7:41:7:43 | exit set_P2 | MultiImplementationA.cs:7:41:7:43 | enter set_P2 |
| MultiImplementationA.cs:7:41:7:43 | exit set_P2 | MultiImplementationA.cs:7:41:7:43 | exit set_P2 |
| MultiImplementationA.cs:7:41:7:43 | exit set_P2 | MultiImplementationA.cs:7:45:7:59 | {...} |
| MultiImplementationA.cs:7:41:7:43 | exit set_P2 | MultiImplementationB.cs:4:39:4:41 | enter set_P2 |
| MultiImplementationA.cs:7:41:7:43 | exit set_P2 | MultiImplementationB.cs:4:39:4:41 | exit set_P2 |
| MultiImplementationA.cs:7:41:7:43 | exit set_P2 | MultiImplementationB.cs:4:43:4:45 | {...} |
| MultiImplementationA.cs:7:45:7:59 | {...} | MultiImplementationA.cs:7:45:7:59 | {...} |
| MultiImplementationA.cs:8:16:8:16 | enter M | MultiImplementationA.cs:8:16:8:16 | enter M |
| MultiImplementationA.cs:8:16:8:16 | enter M | MultiImplementationB.cs:5:16:5:16 | enter M |
| MultiImplementationA.cs:8:16:8:16 | exit M | MultiImplementationA.cs:8:16:8:16 | enter M |
| MultiImplementationA.cs:8:16:8:16 | exit M | MultiImplementationA.cs:8:16:8:16 | exit M |
| MultiImplementationA.cs:8:16:8:16 | exit M | MultiImplementationA.cs:8:29:8:32 | null |
| MultiImplementationA.cs:8:16:8:16 | exit M | MultiImplementationB.cs:5:16:5:16 | enter M |
| MultiImplementationA.cs:8:16:8:16 | exit M | MultiImplementationB.cs:5:16:5:16 | exit M |
| MultiImplementationA.cs:8:16:8:16 | exit M | MultiImplementationB.cs:5:23:5:23 | 2 |
| MultiImplementationA.cs:8:29:8:32 | null | MultiImplementationA.cs:8:29:8:32 | null |
| MultiImplementationA.cs:13:16:13:16 | this access | MultiImplementationA.cs:13:16:13:16 | this access |
| MultiImplementationA.cs:14:31:14:31 | access to parameter i | MultiImplementationA.cs:14:31:14:31 | access to parameter i |
| MultiImplementationA.cs:14:31:14:31 | enter get_Item | MultiImplementationA.cs:14:31:14:31 | enter get_Item |
| MultiImplementationA.cs:14:31:14:31 | enter get_Item | MultiImplementationB.cs:12:31:12:40 | enter get_Item |
| MultiImplementationA.cs:14:31:14:31 | exit get_Item | MultiImplementationA.cs:14:31:14:31 | access to parameter i |
| MultiImplementationA.cs:14:31:14:31 | exit get_Item | MultiImplementationA.cs:14:31:14:31 | enter get_Item |
| MultiImplementationA.cs:14:31:14:31 | exit get_Item | MultiImplementationA.cs:14:31:14:31 | exit get_Item |
| MultiImplementationA.cs:14:31:14:31 | exit get_Item | MultiImplementationB.cs:12:31:12:40 | enter get_Item |
| MultiImplementationA.cs:14:31:14:31 | exit get_Item | MultiImplementationB.cs:12:31:12:40 | exit get_Item |
| MultiImplementationA.cs:14:31:14:31 | exit get_Item | MultiImplementationB.cs:12:37:12:40 | null |
| MultiImplementationA.cs:15:36:15:38 | enter get_Item | MultiImplementationA.cs:15:36:15:38 | enter get_Item |
| MultiImplementationA.cs:15:36:15:38 | enter get_Item | MultiImplementationB.cs:13:36:13:38 | enter get_Item |
| MultiImplementationA.cs:15:36:15:38 | exit get_Item | MultiImplementationA.cs:15:36:15:38 | enter get_Item |
| MultiImplementationA.cs:15:36:15:38 | exit get_Item | MultiImplementationA.cs:15:36:15:38 | exit get_Item |
| MultiImplementationA.cs:15:36:15:38 | exit get_Item | MultiImplementationA.cs:15:40:15:52 | {...} |
| MultiImplementationA.cs:15:36:15:38 | exit get_Item | MultiImplementationB.cs:13:36:13:38 | enter get_Item |
| MultiImplementationA.cs:15:36:15:38 | exit get_Item | MultiImplementationB.cs:13:36:13:38 | exit get_Item |
| MultiImplementationA.cs:15:36:15:38 | exit get_Item | MultiImplementationB.cs:13:40:13:54 | {...} |
| MultiImplementationA.cs:15:40:15:52 | {...} | MultiImplementationA.cs:15:40:15:52 | {...} |
| MultiImplementationA.cs:15:54:15:56 | enter set_Item | MultiImplementationA.cs:15:54:15:56 | enter set_Item |
| MultiImplementationA.cs:15:54:15:56 | enter set_Item | MultiImplementationB.cs:13:56:13:58 | enter set_Item |
| MultiImplementationA.cs:15:54:15:56 | exit set_Item | MultiImplementationA.cs:15:54:15:56 | enter set_Item |
| MultiImplementationA.cs:15:54:15:56 | exit set_Item | MultiImplementationA.cs:15:54:15:56 | exit set_Item |
| MultiImplementationA.cs:15:54:15:56 | exit set_Item | MultiImplementationA.cs:15:58:15:60 | {...} |
| MultiImplementationA.cs:15:54:15:56 | exit set_Item | MultiImplementationB.cs:13:56:13:58 | enter set_Item |
| MultiImplementationA.cs:15:54:15:56 | exit set_Item | MultiImplementationB.cs:13:56:13:58 | exit set_Item |
| MultiImplementationA.cs:15:54:15:56 | exit set_Item | MultiImplementationB.cs:13:60:13:62 | {...} |
| MultiImplementationA.cs:15:58:15:60 | {...} | MultiImplementationA.cs:15:58:15:60 | {...} |
| MultiImplementationA.cs:16:17:16:18 | enter M1 | MultiImplementationA.cs:16:17:16:18 | enter M1 |
| MultiImplementationA.cs:16:17:16:18 | enter M1 | MultiImplementationB.cs:14:17:14:18 | enter M1 |
| MultiImplementationA.cs:16:17:16:18 | exit M1 | MultiImplementationA.cs:16:17:16:18 | enter M1 |
| MultiImplementationA.cs:16:17:16:18 | exit M1 | MultiImplementationA.cs:16:17:16:18 | exit M1 |
| MultiImplementationA.cs:16:17:16:18 | exit M1 | MultiImplementationA.cs:17:5:19:5 | {...} |
| MultiImplementationA.cs:16:17:16:18 | exit M1 | MultiImplementationB.cs:14:17:14:18 | enter M1 |
| MultiImplementationA.cs:16:17:16:18 | exit M1 | MultiImplementationB.cs:14:17:14:18 | exit M1 |
| MultiImplementationA.cs:16:17:16:18 | exit M1 | MultiImplementationB.cs:15:5:17:5 | {...} |
| MultiImplementationA.cs:17:5:19:5 | {...} | MultiImplementationA.cs:17:5:19:5 | {...} |
| MultiImplementationA.cs:18:9:18:22 | enter M2 | MultiImplementationA.cs:18:9:18:22 | enter M2 |
| MultiImplementationA.cs:20:12:20:13 | enter C2 | MultiImplementationA.cs:20:12:20:13 | enter C2 |
| MultiImplementationA.cs:20:12:20:13 | enter C2 | MultiImplementationB.cs:18:12:18:13 | enter C2 |
| MultiImplementationA.cs:20:12:20:13 | exit C2 | MultiImplementationA.cs:13:16:13:16 | this access |
| MultiImplementationA.cs:20:12:20:13 | exit C2 | MultiImplementationA.cs:20:12:20:13 | enter C2 |
| MultiImplementationA.cs:20:12:20:13 | exit C2 | MultiImplementationA.cs:20:12:20:13 | exit C2 |
| MultiImplementationA.cs:20:12:20:13 | exit C2 | MultiImplementationA.cs:20:22:20:31 | {...} |
| MultiImplementationA.cs:20:12:20:13 | exit C2 | MultiImplementationA.cs:24:16:24:16 | this access |
| MultiImplementationA.cs:20:12:20:13 | exit C2 | MultiImplementationB.cs:11:16:11:16 | this access |
| MultiImplementationA.cs:20:12:20:13 | exit C2 | MultiImplementationB.cs:18:12:18:13 | enter C2 |
| MultiImplementationA.cs:20:12:20:13 | exit C2 | MultiImplementationB.cs:18:12:18:13 | exit C2 |
| MultiImplementationA.cs:20:12:20:13 | exit C2 | MultiImplementationB.cs:18:22:18:36 | {...} |
| MultiImplementationA.cs:20:12:20:13 | exit C2 | MultiImplementationB.cs:22:16:22:16 | this access |
| MultiImplementationA.cs:20:22:20:31 | {...} | MultiImplementationA.cs:20:22:20:31 | {...} |
| MultiImplementationA.cs:21:12:21:13 | enter C2 | MultiImplementationA.cs:21:12:21:13 | enter C2 |
| MultiImplementationA.cs:21:12:21:13 | enter C2 | MultiImplementationB.cs:19:12:19:13 | enter C2 |
| MultiImplementationA.cs:21:12:21:13 | exit C2 | MultiImplementationA.cs:21:12:21:13 | enter C2 |
| MultiImplementationA.cs:21:12:21:13 | exit C2 | MultiImplementationA.cs:21:12:21:13 | exit C2 |
| MultiImplementationA.cs:21:12:21:13 | exit C2 | MultiImplementationA.cs:21:24:21:24 | 0 |
| MultiImplementationA.cs:21:12:21:13 | exit C2 | MultiImplementationA.cs:21:27:21:29 | {...} |
| MultiImplementationA.cs:21:12:21:13 | exit C2 | MultiImplementationB.cs:19:12:19:13 | enter C2 |
| MultiImplementationA.cs:21:12:21:13 | exit C2 | MultiImplementationB.cs:19:12:19:13 | exit C2 |
| MultiImplementationA.cs:21:12:21:13 | exit C2 | MultiImplementationB.cs:19:24:19:24 | 1 |
| MultiImplementationA.cs:21:12:21:13 | exit C2 | MultiImplementationB.cs:19:27:19:29 | {...} |
| MultiImplementationA.cs:21:24:21:24 | 0 | MultiImplementationA.cs:21:24:21:24 | 0 |
| MultiImplementationA.cs:21:27:21:29 | {...} | MultiImplementationA.cs:21:27:21:29 | {...} |
| MultiImplementationA.cs:22:6:22:7 | enter ~C2 | MultiImplementationA.cs:22:6:22:7 | enter ~C2 |
| MultiImplementationA.cs:22:6:22:7 | enter ~C2 | MultiImplementationB.cs:20:6:20:7 | enter ~C2 |
| MultiImplementationA.cs:22:6:22:7 | exit ~C2 | MultiImplementationA.cs:22:6:22:7 | enter ~C2 |
| MultiImplementationA.cs:22:6:22:7 | exit ~C2 | MultiImplementationA.cs:22:6:22:7 | exit ~C2 |
| MultiImplementationA.cs:22:6:22:7 | exit ~C2 | MultiImplementationA.cs:22:11:22:13 | {...} |
| MultiImplementationA.cs:22:6:22:7 | exit ~C2 | MultiImplementationB.cs:20:6:20:7 | enter ~C2 |
| MultiImplementationA.cs:22:6:22:7 | exit ~C2 | MultiImplementationB.cs:20:6:20:7 | exit ~C2 |
| MultiImplementationA.cs:22:6:22:7 | exit ~C2 | MultiImplementationB.cs:20:11:20:25 | {...} |
| MultiImplementationA.cs:22:11:22:13 | {...} | MultiImplementationA.cs:22:11:22:13 | {...} |
| MultiImplementationA.cs:23:28:23:35 | enter implicit conversion | MultiImplementationA.cs:23:28:23:35 | enter implicit conversion |
| MultiImplementationA.cs:23:28:23:35 | enter implicit conversion | MultiImplementationB.cs:21:28:21:35 | enter implicit conversion |
| MultiImplementationA.cs:23:28:23:35 | exit implicit conversion | MultiImplementationA.cs:23:28:23:35 | enter implicit conversion |
| MultiImplementationA.cs:23:28:23:35 | exit implicit conversion | MultiImplementationA.cs:23:28:23:35 | exit implicit conversion |
| MultiImplementationA.cs:23:28:23:35 | exit implicit conversion | MultiImplementationA.cs:23:50:23:53 | null |
| MultiImplementationA.cs:23:28:23:35 | exit implicit conversion | MultiImplementationB.cs:21:28:21:35 | enter implicit conversion |
| MultiImplementationA.cs:23:28:23:35 | exit implicit conversion | MultiImplementationB.cs:21:28:21:35 | exit implicit conversion |
| MultiImplementationA.cs:23:28:23:35 | exit implicit conversion | MultiImplementationB.cs:21:56:21:59 | null |
| MultiImplementationA.cs:23:50:23:53 | null | MultiImplementationA.cs:23:50:23:53 | null |
| MultiImplementationA.cs:24:16:24:16 | this access | MultiImplementationA.cs:24:16:24:16 | this access |
| MultiImplementationA.cs:30:21:30:23 | enter get_P3 | MultiImplementationA.cs:30:21:30:23 | enter get_P3 |
| MultiImplementationA.cs:30:21:30:23 | enter get_P3 | MultiImplementationB.cs:27:21:27:23 | enter get_P3 |
| MultiImplementationA.cs:36:9:36:10 | enter M1 | MultiImplementationA.cs:36:9:36:10 | enter M1 |
| MultiImplementationA.cs:36:9:36:10 | enter M1 | MultiImplementationB.cs:32:9:32:10 | enter M1 |
| MultiImplementationA.cs:36:9:36:10 | exit M1 | MultiImplementationA.cs:36:9:36:10 | enter M1 |
| MultiImplementationA.cs:36:9:36:10 | exit M1 | MultiImplementationA.cs:36:9:36:10 | exit M1 |
| MultiImplementationA.cs:36:9:36:10 | exit M1 | MultiImplementationA.cs:36:14:36:28 | {...} |
| MultiImplementationA.cs:36:9:36:10 | exit M1 | MultiImplementationB.cs:32:9:32:10 | enter M1 |
| MultiImplementationA.cs:36:9:36:10 | exit M1 | MultiImplementationB.cs:32:9:32:10 | exit M1 |
| MultiImplementationA.cs:36:9:36:10 | exit M1 | MultiImplementationB.cs:32:17:32:17 | 0 |
| MultiImplementationA.cs:36:14:36:28 | {...} | MultiImplementationA.cs:36:14:36:28 | {...} |
| MultiImplementationA.cs:37:9:37:10 | enter M2 | MultiImplementationA.cs:37:9:37:10 | enter M2 |
| MultiImplementationB.cs:3:22:3:22 | 0 | MultiImplementationB.cs:3:22:3:22 | 0 |
| MultiImplementationB.cs:3:22:3:22 | enter get_P1 | MultiImplementationA.cs:6:22:6:31 | enter get_P1 |
| MultiImplementationB.cs:3:22:3:22 | enter get_P1 | MultiImplementationB.cs:3:22:3:22 | enter get_P1 |
| MultiImplementationB.cs:3:22:3:22 | exit get_P1 | MultiImplementationA.cs:6:22:6:31 | enter get_P1 |
| MultiImplementationB.cs:3:22:3:22 | exit get_P1 | MultiImplementationA.cs:6:22:6:31 | exit get_P1 |
| MultiImplementationB.cs:3:22:3:22 | exit get_P1 | MultiImplementationA.cs:6:28:6:31 | null |
| MultiImplementationB.cs:3:22:3:22 | exit get_P1 | MultiImplementationB.cs:3:22:3:22 | 0 |
| MultiImplementationB.cs:3:22:3:22 | exit get_P1 | MultiImplementationB.cs:3:22:3:22 | enter get_P1 |
| MultiImplementationB.cs:3:22:3:22 | exit get_P1 | MultiImplementationB.cs:3:22:3:22 | exit get_P1 |
| MultiImplementationB.cs:4:21:4:23 | enter get_P2 | MultiImplementationA.cs:7:21:7:23 | enter get_P2 |
| MultiImplementationB.cs:4:21:4:23 | enter get_P2 | MultiImplementationB.cs:4:21:4:23 | enter get_P2 |
| MultiImplementationB.cs:4:21:4:23 | exit get_P2 | MultiImplementationA.cs:7:21:7:23 | enter get_P2 |
| MultiImplementationB.cs:4:21:4:23 | exit get_P2 | MultiImplementationA.cs:7:21:7:23 | exit get_P2 |
| MultiImplementationB.cs:4:21:4:23 | exit get_P2 | MultiImplementationA.cs:7:25:7:39 | {...} |
| MultiImplementationB.cs:4:21:4:23 | exit get_P2 | MultiImplementationB.cs:4:21:4:23 | enter get_P2 |
| MultiImplementationB.cs:4:21:4:23 | exit get_P2 | MultiImplementationB.cs:4:21:4:23 | exit get_P2 |
| MultiImplementationB.cs:4:21:4:23 | exit get_P2 | MultiImplementationB.cs:4:25:4:37 | {...} |
| MultiImplementationB.cs:4:25:4:37 | {...} | MultiImplementationB.cs:4:25:4:37 | {...} |
| MultiImplementationB.cs:4:39:4:41 | enter set_P2 | MultiImplementationA.cs:7:41:7:43 | enter set_P2 |
| MultiImplementationB.cs:4:39:4:41 | enter set_P2 | MultiImplementationB.cs:4:39:4:41 | enter set_P2 |
| MultiImplementationB.cs:4:39:4:41 | exit set_P2 | MultiImplementationA.cs:7:41:7:43 | enter set_P2 |
| MultiImplementationB.cs:4:39:4:41 | exit set_P2 | MultiImplementationA.cs:7:41:7:43 | exit set_P2 |
| MultiImplementationB.cs:4:39:4:41 | exit set_P2 | MultiImplementationA.cs:7:45:7:59 | {...} |
| MultiImplementationB.cs:4:39:4:41 | exit set_P2 | MultiImplementationB.cs:4:39:4:41 | enter set_P2 |
| MultiImplementationB.cs:4:39:4:41 | exit set_P2 | MultiImplementationB.cs:4:39:4:41 | exit set_P2 |
| MultiImplementationB.cs:4:39:4:41 | exit set_P2 | MultiImplementationB.cs:4:43:4:45 | {...} |
| MultiImplementationB.cs:4:43:4:45 | {...} | MultiImplementationB.cs:4:43:4:45 | {...} |
| MultiImplementationB.cs:5:16:5:16 | enter M | MultiImplementationA.cs:8:16:8:16 | enter M |
| MultiImplementationB.cs:5:16:5:16 | enter M | MultiImplementationB.cs:5:16:5:16 | enter M |
| MultiImplementationB.cs:5:16:5:16 | exit M | MultiImplementationA.cs:8:16:8:16 | enter M |
| MultiImplementationB.cs:5:16:5:16 | exit M | MultiImplementationA.cs:8:16:8:16 | exit M |
| MultiImplementationB.cs:5:16:5:16 | exit M | MultiImplementationA.cs:8:29:8:32 | null |
| MultiImplementationB.cs:5:16:5:16 | exit M | MultiImplementationB.cs:5:16:5:16 | enter M |
| MultiImplementationB.cs:5:16:5:16 | exit M | MultiImplementationB.cs:5:16:5:16 | exit M |
| MultiImplementationB.cs:5:16:5:16 | exit M | MultiImplementationB.cs:5:23:5:23 | 2 |
| MultiImplementationB.cs:5:23:5:23 | 2 | MultiImplementationB.cs:5:23:5:23 | 2 |
| MultiImplementationB.cs:11:16:11:16 | this access | MultiImplementationB.cs:11:16:11:16 | this access |
| MultiImplementationB.cs:12:31:12:40 | enter get_Item | MultiImplementationA.cs:14:31:14:31 | enter get_Item |
| MultiImplementationB.cs:12:31:12:40 | enter get_Item | MultiImplementationB.cs:12:31:12:40 | enter get_Item |
| MultiImplementationB.cs:12:31:12:40 | exit get_Item | MultiImplementationA.cs:14:31:14:31 | access to parameter i |
| MultiImplementationB.cs:12:31:12:40 | exit get_Item | MultiImplementationA.cs:14:31:14:31 | enter get_Item |
| MultiImplementationB.cs:12:31:12:40 | exit get_Item | MultiImplementationA.cs:14:31:14:31 | exit get_Item |
| MultiImplementationB.cs:12:31:12:40 | exit get_Item | MultiImplementationB.cs:12:31:12:40 | enter get_Item |
| MultiImplementationB.cs:12:31:12:40 | exit get_Item | MultiImplementationB.cs:12:31:12:40 | exit get_Item |
| MultiImplementationB.cs:12:31:12:40 | exit get_Item | MultiImplementationB.cs:12:37:12:40 | null |
| MultiImplementationB.cs:12:37:12:40 | null | MultiImplementationB.cs:12:37:12:40 | null |
| MultiImplementationB.cs:13:36:13:38 | enter get_Item | MultiImplementationA.cs:15:36:15:38 | enter get_Item |
| MultiImplementationB.cs:13:36:13:38 | enter get_Item | MultiImplementationB.cs:13:36:13:38 | enter get_Item |
| MultiImplementationB.cs:13:36:13:38 | exit get_Item | MultiImplementationA.cs:15:36:15:38 | enter get_Item |
| MultiImplementationB.cs:13:36:13:38 | exit get_Item | MultiImplementationA.cs:15:36:15:38 | exit get_Item |
| MultiImplementationB.cs:13:36:13:38 | exit get_Item | MultiImplementationA.cs:15:40:15:52 | {...} |
| MultiImplementationB.cs:13:36:13:38 | exit get_Item | MultiImplementationB.cs:13:36:13:38 | enter get_Item |
| MultiImplementationB.cs:13:36:13:38 | exit get_Item | MultiImplementationB.cs:13:36:13:38 | exit get_Item |
| MultiImplementationB.cs:13:36:13:38 | exit get_Item | MultiImplementationB.cs:13:40:13:54 | {...} |
| MultiImplementationB.cs:13:40:13:54 | {...} | MultiImplementationB.cs:13:40:13:54 | {...} |
| MultiImplementationB.cs:13:56:13:58 | enter set_Item | MultiImplementationA.cs:15:54:15:56 | enter set_Item |
| MultiImplementationB.cs:13:56:13:58 | enter set_Item | MultiImplementationB.cs:13:56:13:58 | enter set_Item |
| MultiImplementationB.cs:13:56:13:58 | exit set_Item | MultiImplementationA.cs:15:54:15:56 | enter set_Item |
| MultiImplementationB.cs:13:56:13:58 | exit set_Item | MultiImplementationA.cs:15:54:15:56 | exit set_Item |
| MultiImplementationB.cs:13:56:13:58 | exit set_Item | MultiImplementationA.cs:15:58:15:60 | {...} |
| MultiImplementationB.cs:13:56:13:58 | exit set_Item | MultiImplementationB.cs:13:56:13:58 | enter set_Item |
| MultiImplementationB.cs:13:56:13:58 | exit set_Item | MultiImplementationB.cs:13:56:13:58 | exit set_Item |
| MultiImplementationB.cs:13:56:13:58 | exit set_Item | MultiImplementationB.cs:13:60:13:62 | {...} |
| MultiImplementationB.cs:13:60:13:62 | {...} | MultiImplementationB.cs:13:60:13:62 | {...} |
| MultiImplementationB.cs:14:17:14:18 | enter M1 | MultiImplementationA.cs:16:17:16:18 | enter M1 |
| MultiImplementationB.cs:14:17:14:18 | enter M1 | MultiImplementationB.cs:14:17:14:18 | enter M1 |
| MultiImplementationB.cs:14:17:14:18 | exit M1 | MultiImplementationA.cs:16:17:16:18 | enter M1 |
| MultiImplementationB.cs:14:17:14:18 | exit M1 | MultiImplementationA.cs:16:17:16:18 | exit M1 |
| MultiImplementationB.cs:14:17:14:18 | exit M1 | MultiImplementationA.cs:17:5:19:5 | {...} |
| MultiImplementationB.cs:14:17:14:18 | exit M1 | MultiImplementationB.cs:14:17:14:18 | enter M1 |
| MultiImplementationB.cs:14:17:14:18 | exit M1 | MultiImplementationB.cs:14:17:14:18 | exit M1 |
| MultiImplementationB.cs:14:17:14:18 | exit M1 | MultiImplementationB.cs:15:5:17:5 | {...} |
| MultiImplementationB.cs:15:5:17:5 | {...} | MultiImplementationB.cs:15:5:17:5 | {...} |
| MultiImplementationB.cs:16:9:16:31 | enter M2 | MultiImplementationB.cs:16:9:16:31 | enter M2 |
| MultiImplementationB.cs:18:12:18:13 | enter C2 | MultiImplementationA.cs:20:12:20:13 | enter C2 |
| MultiImplementationB.cs:18:12:18:13 | enter C2 | MultiImplementationB.cs:18:12:18:13 | enter C2 |
| MultiImplementationB.cs:18:12:18:13 | exit C2 | MultiImplementationA.cs:13:16:13:16 | this access |
| MultiImplementationB.cs:18:12:18:13 | exit C2 | MultiImplementationA.cs:20:12:20:13 | enter C2 |
| MultiImplementationB.cs:18:12:18:13 | exit C2 | MultiImplementationA.cs:20:12:20:13 | exit C2 |
| MultiImplementationB.cs:18:12:18:13 | exit C2 | MultiImplementationA.cs:20:22:20:31 | {...} |
| MultiImplementationB.cs:18:12:18:13 | exit C2 | MultiImplementationA.cs:24:16:24:16 | this access |
| MultiImplementationB.cs:18:12:18:13 | exit C2 | MultiImplementationB.cs:11:16:11:16 | this access |
| MultiImplementationB.cs:18:12:18:13 | exit C2 | MultiImplementationB.cs:18:12:18:13 | enter C2 |
| MultiImplementationB.cs:18:12:18:13 | exit C2 | MultiImplementationB.cs:18:12:18:13 | exit C2 |
| MultiImplementationB.cs:18:12:18:13 | exit C2 | MultiImplementationB.cs:18:22:18:36 | {...} |
| MultiImplementationB.cs:18:12:18:13 | exit C2 | MultiImplementationB.cs:22:16:22:16 | this access |
| MultiImplementationB.cs:18:22:18:36 | {...} | MultiImplementationB.cs:18:22:18:36 | {...} |
| MultiImplementationB.cs:19:12:19:13 | enter C2 | MultiImplementationA.cs:21:12:21:13 | enter C2 |
| MultiImplementationB.cs:19:12:19:13 | enter C2 | MultiImplementationB.cs:19:12:19:13 | enter C2 |
| MultiImplementationB.cs:19:12:19:13 | exit C2 | MultiImplementationA.cs:21:12:21:13 | enter C2 |
| MultiImplementationB.cs:19:12:19:13 | exit C2 | MultiImplementationA.cs:21:12:21:13 | exit C2 |
| MultiImplementationB.cs:19:12:19:13 | exit C2 | MultiImplementationA.cs:21:24:21:24 | 0 |
| MultiImplementationB.cs:19:12:19:13 | exit C2 | MultiImplementationA.cs:21:27:21:29 | {...} |
| MultiImplementationB.cs:19:12:19:13 | exit C2 | MultiImplementationB.cs:19:12:19:13 | enter C2 |
| MultiImplementationB.cs:19:12:19:13 | exit C2 | MultiImplementationB.cs:19:12:19:13 | exit C2 |
| MultiImplementationB.cs:19:12:19:13 | exit C2 | MultiImplementationB.cs:19:24:19:24 | 1 |
| MultiImplementationB.cs:19:12:19:13 | exit C2 | MultiImplementationB.cs:19:27:19:29 | {...} |
| MultiImplementationB.cs:19:24:19:24 | 1 | MultiImplementationB.cs:19:24:19:24 | 1 |
| MultiImplementationB.cs:19:27:19:29 | {...} | MultiImplementationB.cs:19:27:19:29 | {...} |
| MultiImplementationB.cs:20:6:20:7 | enter ~C2 | MultiImplementationA.cs:22:6:22:7 | enter ~C2 |
| MultiImplementationB.cs:20:6:20:7 | enter ~C2 | MultiImplementationB.cs:20:6:20:7 | enter ~C2 |
| MultiImplementationB.cs:20:6:20:7 | exit ~C2 | MultiImplementationA.cs:22:6:22:7 | enter ~C2 |
| MultiImplementationB.cs:20:6:20:7 | exit ~C2 | MultiImplementationA.cs:22:6:22:7 | exit ~C2 |
| MultiImplementationB.cs:20:6:20:7 | exit ~C2 | MultiImplementationA.cs:22:11:22:13 | {...} |
| MultiImplementationB.cs:20:6:20:7 | exit ~C2 | MultiImplementationB.cs:20:6:20:7 | enter ~C2 |
| MultiImplementationB.cs:20:6:20:7 | exit ~C2 | MultiImplementationB.cs:20:6:20:7 | exit ~C2 |
| MultiImplementationB.cs:20:6:20:7 | exit ~C2 | MultiImplementationB.cs:20:11:20:25 | {...} |
| MultiImplementationB.cs:20:11:20:25 | {...} | MultiImplementationB.cs:20:11:20:25 | {...} |
| MultiImplementationB.cs:21:28:21:35 | enter implicit conversion | MultiImplementationA.cs:23:28:23:35 | enter implicit conversion |
| MultiImplementationB.cs:21:28:21:35 | enter implicit conversion | MultiImplementationB.cs:21:28:21:35 | enter implicit conversion |
| MultiImplementationB.cs:21:28:21:35 | exit implicit conversion | MultiImplementationA.cs:23:28:23:35 | enter implicit conversion |
| MultiImplementationB.cs:21:28:21:35 | exit implicit conversion | MultiImplementationA.cs:23:28:23:35 | exit implicit conversion |
| MultiImplementationB.cs:21:28:21:35 | exit implicit conversion | MultiImplementationA.cs:23:50:23:53 | null |
| MultiImplementationB.cs:21:28:21:35 | exit implicit conversion | MultiImplementationB.cs:21:28:21:35 | enter implicit conversion |
| MultiImplementationB.cs:21:28:21:35 | exit implicit conversion | MultiImplementationB.cs:21:28:21:35 | exit implicit conversion |
| MultiImplementationB.cs:21:28:21:35 | exit implicit conversion | MultiImplementationB.cs:21:56:21:59 | null |
| MultiImplementationB.cs:21:56:21:59 | null | MultiImplementationB.cs:21:56:21:59 | null |
| MultiImplementationB.cs:22:16:22:16 | this access | MultiImplementationB.cs:22:16:22:16 | this access |
| MultiImplementationB.cs:27:21:27:23 | enter get_P3 | MultiImplementationA.cs:30:21:30:23 | enter get_P3 |
| MultiImplementationB.cs:27:21:27:23 | enter get_P3 | MultiImplementationB.cs:27:21:27:23 | enter get_P3 |
| MultiImplementationB.cs:32:9:32:10 | enter M1 | MultiImplementationA.cs:36:9:36:10 | enter M1 |
| MultiImplementationB.cs:32:9:32:10 | enter M1 | MultiImplementationB.cs:32:9:32:10 | enter M1 |
| MultiImplementationB.cs:32:9:32:10 | exit M1 | MultiImplementationA.cs:36:9:36:10 | enter M1 |
| MultiImplementationB.cs:32:9:32:10 | exit M1 | MultiImplementationA.cs:36:9:36:10 | exit M1 |
| MultiImplementationB.cs:32:9:32:10 | exit M1 | MultiImplementationA.cs:36:14:36:28 | {...} |
| MultiImplementationB.cs:32:9:32:10 | exit M1 | MultiImplementationB.cs:32:9:32:10 | enter M1 |
| MultiImplementationB.cs:32:9:32:10 | exit M1 | MultiImplementationB.cs:32:9:32:10 | exit M1 |
| MultiImplementationB.cs:32:9:32:10 | exit M1 | MultiImplementationB.cs:32:17:32:17 | 0 |
| MultiImplementationB.cs:32:17:32:17 | 0 | MultiImplementationB.cs:32:17:32:17 | 0 |
| NullCoalescing.cs:3:9:3:10 | enter M1 | NullCoalescing.cs:3:9:3:10 | enter M1 |
| NullCoalescing.cs:3:9:3:10 | exit M1 | NullCoalescing.cs:3:9:3:10 | enter M1 |
| NullCoalescing.cs:3:9:3:10 | exit M1 | NullCoalescing.cs:3:9:3:10 | exit M1 |

View File

@@ -2190,6 +2190,274 @@ nodeEnclosing
| LoopUnrolling.cs:73:13:73:34 | call to method WriteLine | LoopUnrolling.cs:67:10:67:11 | M8 |
| LoopUnrolling.cs:73:13:73:35 | ...; | LoopUnrolling.cs:67:10:67:11 | M8 |
| LoopUnrolling.cs:73:31:73:33 | access to local variable arg | LoopUnrolling.cs:67:10:67:11 | M8 |
| MultiImplementationA.cs:6:22:6:31 | enter get_P1 | MultiImplementationA.cs:6:22:6:31 | get_P1 |
| MultiImplementationA.cs:6:22:6:31 | enter get_P1 | MultiImplementationB.cs:3:22:3:22 | get_P1 |
| MultiImplementationA.cs:6:22:6:31 | exit get_P1 | MultiImplementationA.cs:6:22:6:31 | get_P1 |
| MultiImplementationA.cs:6:22:6:31 | exit get_P1 | MultiImplementationB.cs:3:22:3:22 | get_P1 |
| MultiImplementationA.cs:6:22:6:31 | throw ... | MultiImplementationA.cs:6:22:6:31 | get_P1 |
| MultiImplementationA.cs:6:22:6:31 | throw ... | MultiImplementationB.cs:3:22:3:22 | get_P1 |
| MultiImplementationA.cs:6:28:6:31 | null | MultiImplementationA.cs:6:22:6:31 | get_P1 |
| MultiImplementationA.cs:6:28:6:31 | null | MultiImplementationB.cs:3:22:3:22 | get_P1 |
| MultiImplementationA.cs:7:21:7:23 | enter get_P2 | MultiImplementationA.cs:7:21:7:23 | get_P2 |
| MultiImplementationA.cs:7:21:7:23 | enter get_P2 | MultiImplementationB.cs:4:21:4:23 | get_P2 |
| MultiImplementationA.cs:7:21:7:23 | exit get_P2 | MultiImplementationA.cs:7:21:7:23 | get_P2 |
| MultiImplementationA.cs:7:21:7:23 | exit get_P2 | MultiImplementationB.cs:4:21:4:23 | get_P2 |
| MultiImplementationA.cs:7:25:7:39 | {...} | MultiImplementationA.cs:7:21:7:23 | get_P2 |
| MultiImplementationA.cs:7:25:7:39 | {...} | MultiImplementationB.cs:4:21:4:23 | get_P2 |
| MultiImplementationA.cs:7:27:7:37 | throw ...; | MultiImplementationA.cs:7:21:7:23 | get_P2 |
| MultiImplementationA.cs:7:27:7:37 | throw ...; | MultiImplementationB.cs:4:21:4:23 | get_P2 |
| MultiImplementationA.cs:7:33:7:36 | null | MultiImplementationA.cs:7:21:7:23 | get_P2 |
| MultiImplementationA.cs:7:33:7:36 | null | MultiImplementationB.cs:4:21:4:23 | get_P2 |
| MultiImplementationA.cs:7:41:7:43 | enter set_P2 | MultiImplementationA.cs:7:41:7:43 | set_P2 |
| MultiImplementationA.cs:7:41:7:43 | enter set_P2 | MultiImplementationB.cs:4:39:4:41 | set_P2 |
| MultiImplementationA.cs:7:41:7:43 | exit set_P2 | MultiImplementationA.cs:7:41:7:43 | set_P2 |
| MultiImplementationA.cs:7:41:7:43 | exit set_P2 | MultiImplementationB.cs:4:39:4:41 | set_P2 |
| MultiImplementationA.cs:7:45:7:59 | {...} | MultiImplementationA.cs:7:41:7:43 | set_P2 |
| MultiImplementationA.cs:7:45:7:59 | {...} | MultiImplementationB.cs:4:39:4:41 | set_P2 |
| MultiImplementationA.cs:7:47:7:57 | throw ...; | MultiImplementationA.cs:7:41:7:43 | set_P2 |
| MultiImplementationA.cs:7:47:7:57 | throw ...; | MultiImplementationB.cs:4:39:4:41 | set_P2 |
| MultiImplementationA.cs:7:53:7:56 | null | MultiImplementationA.cs:7:41:7:43 | set_P2 |
| MultiImplementationA.cs:7:53:7:56 | null | MultiImplementationB.cs:4:39:4:41 | set_P2 |
| MultiImplementationA.cs:8:16:8:16 | enter M | MultiImplementationA.cs:8:16:8:16 | M |
| MultiImplementationA.cs:8:16:8:16 | enter M | MultiImplementationB.cs:5:16:5:16 | M |
| MultiImplementationA.cs:8:16:8:16 | exit M | MultiImplementationA.cs:8:16:8:16 | M |
| MultiImplementationA.cs:8:16:8:16 | exit M | MultiImplementationB.cs:5:16:5:16 | M |
| MultiImplementationA.cs:8:23:8:32 | throw ... | MultiImplementationA.cs:8:16:8:16 | M |
| MultiImplementationA.cs:8:23:8:32 | throw ... | MultiImplementationB.cs:5:16:5:16 | M |
| MultiImplementationA.cs:8:29:8:32 | null | MultiImplementationA.cs:8:16:8:16 | M |
| MultiImplementationA.cs:8:29:8:32 | null | MultiImplementationB.cs:5:16:5:16 | M |
| MultiImplementationA.cs:13:16:13:16 | this access | MultiImplementationA.cs:20:12:20:13 | C2 |
| MultiImplementationA.cs:13:16:13:16 | this access | MultiImplementationB.cs:18:12:18:13 | C2 |
| MultiImplementationA.cs:13:16:13:20 | ... = ... | MultiImplementationA.cs:20:12:20:13 | C2 |
| MultiImplementationA.cs:13:16:13:20 | ... = ... | MultiImplementationB.cs:18:12:18:13 | C2 |
| MultiImplementationA.cs:13:20:13:20 | 0 | MultiImplementationA.cs:20:12:20:13 | C2 |
| MultiImplementationA.cs:13:20:13:20 | 0 | MultiImplementationB.cs:18:12:18:13 | C2 |
| MultiImplementationA.cs:14:31:14:31 | access to parameter i | MultiImplementationA.cs:14:31:14:31 | get_Item |
| MultiImplementationA.cs:14:31:14:31 | access to parameter i | MultiImplementationB.cs:12:31:12:40 | get_Item |
| MultiImplementationA.cs:14:31:14:31 | enter get_Item | MultiImplementationA.cs:14:31:14:31 | get_Item |
| MultiImplementationA.cs:14:31:14:31 | enter get_Item | MultiImplementationB.cs:12:31:12:40 | get_Item |
| MultiImplementationA.cs:14:31:14:31 | exit get_Item | MultiImplementationA.cs:14:31:14:31 | get_Item |
| MultiImplementationA.cs:14:31:14:31 | exit get_Item | MultiImplementationB.cs:12:31:12:40 | get_Item |
| MultiImplementationA.cs:15:36:15:38 | enter get_Item | MultiImplementationA.cs:15:36:15:38 | get_Item |
| MultiImplementationA.cs:15:36:15:38 | enter get_Item | MultiImplementationB.cs:13:36:13:38 | get_Item |
| MultiImplementationA.cs:15:36:15:38 | exit get_Item | MultiImplementationA.cs:15:36:15:38 | get_Item |
| MultiImplementationA.cs:15:36:15:38 | exit get_Item | MultiImplementationB.cs:13:36:13:38 | get_Item |
| MultiImplementationA.cs:15:40:15:52 | {...} | MultiImplementationA.cs:15:36:15:38 | get_Item |
| MultiImplementationA.cs:15:40:15:52 | {...} | MultiImplementationB.cs:13:36:13:38 | get_Item |
| MultiImplementationA.cs:15:42:15:50 | return ...; | MultiImplementationA.cs:15:36:15:38 | get_Item |
| MultiImplementationA.cs:15:42:15:50 | return ...; | MultiImplementationB.cs:13:36:13:38 | get_Item |
| MultiImplementationA.cs:15:49:15:49 | access to parameter s | MultiImplementationA.cs:15:36:15:38 | get_Item |
| MultiImplementationA.cs:15:49:15:49 | access to parameter s | MultiImplementationB.cs:13:36:13:38 | get_Item |
| MultiImplementationA.cs:15:54:15:56 | enter set_Item | MultiImplementationA.cs:15:54:15:56 | set_Item |
| MultiImplementationA.cs:15:54:15:56 | enter set_Item | MultiImplementationB.cs:13:56:13:58 | set_Item |
| MultiImplementationA.cs:15:54:15:56 | exit set_Item | MultiImplementationA.cs:15:54:15:56 | set_Item |
| MultiImplementationA.cs:15:54:15:56 | exit set_Item | MultiImplementationB.cs:13:56:13:58 | set_Item |
| MultiImplementationA.cs:15:58:15:60 | {...} | MultiImplementationA.cs:15:54:15:56 | set_Item |
| MultiImplementationA.cs:15:58:15:60 | {...} | MultiImplementationB.cs:13:56:13:58 | set_Item |
| MultiImplementationA.cs:16:17:16:18 | enter M1 | MultiImplementationA.cs:16:17:16:18 | M1 |
| MultiImplementationA.cs:16:17:16:18 | enter M1 | MultiImplementationB.cs:14:17:14:18 | M1 |
| MultiImplementationA.cs:16:17:16:18 | exit M1 | MultiImplementationA.cs:16:17:16:18 | M1 |
| MultiImplementationA.cs:16:17:16:18 | exit M1 | MultiImplementationB.cs:14:17:14:18 | M1 |
| MultiImplementationA.cs:17:5:19:5 | {...} | MultiImplementationA.cs:16:17:16:18 | M1 |
| MultiImplementationA.cs:17:5:19:5 | {...} | MultiImplementationB.cs:14:17:14:18 | M1 |
| MultiImplementationA.cs:18:9:18:22 | M2(...) | MultiImplementationA.cs:16:17:16:18 | M1 |
| MultiImplementationA.cs:18:9:18:22 | M2(...) | MultiImplementationB.cs:14:17:14:18 | M1 |
| MultiImplementationA.cs:18:9:18:22 | enter M2 | MultiImplementationA.cs:18:9:18:22 | M2 |
| MultiImplementationA.cs:18:9:18:22 | exit M2 | MultiImplementationA.cs:18:9:18:22 | M2 |
| MultiImplementationA.cs:18:21:18:21 | 0 | MultiImplementationA.cs:18:9:18:22 | M2 |
| MultiImplementationA.cs:20:12:20:13 | enter C2 | MultiImplementationA.cs:20:12:20:13 | C2 |
| MultiImplementationA.cs:20:12:20:13 | enter C2 | MultiImplementationB.cs:18:12:18:13 | C2 |
| MultiImplementationA.cs:20:12:20:13 | exit C2 | MultiImplementationA.cs:20:12:20:13 | C2 |
| MultiImplementationA.cs:20:12:20:13 | exit C2 | MultiImplementationB.cs:18:12:18:13 | C2 |
| MultiImplementationA.cs:20:22:20:31 | {...} | MultiImplementationA.cs:20:12:20:13 | C2 |
| MultiImplementationA.cs:20:22:20:31 | {...} | MultiImplementationB.cs:18:12:18:13 | C2 |
| MultiImplementationA.cs:20:24:20:24 | this access | MultiImplementationA.cs:20:12:20:13 | C2 |
| MultiImplementationA.cs:20:24:20:24 | this access | MultiImplementationB.cs:18:12:18:13 | C2 |
| MultiImplementationA.cs:20:24:20:28 | ... = ... | MultiImplementationA.cs:20:12:20:13 | C2 |
| MultiImplementationA.cs:20:24:20:28 | ... = ... | MultiImplementationB.cs:18:12:18:13 | C2 |
| MultiImplementationA.cs:20:24:20:29 | ...; | MultiImplementationA.cs:20:12:20:13 | C2 |
| MultiImplementationA.cs:20:24:20:29 | ...; | MultiImplementationB.cs:18:12:18:13 | C2 |
| MultiImplementationA.cs:20:28:20:28 | access to parameter i | MultiImplementationA.cs:20:12:20:13 | C2 |
| MultiImplementationA.cs:20:28:20:28 | access to parameter i | MultiImplementationB.cs:18:12:18:13 | C2 |
| MultiImplementationA.cs:21:12:21:13 | enter C2 | MultiImplementationA.cs:21:12:21:13 | C2 |
| MultiImplementationA.cs:21:12:21:13 | enter C2 | MultiImplementationB.cs:19:12:19:13 | C2 |
| MultiImplementationA.cs:21:12:21:13 | exit C2 | MultiImplementationA.cs:21:12:21:13 | C2 |
| MultiImplementationA.cs:21:12:21:13 | exit C2 | MultiImplementationB.cs:19:12:19:13 | C2 |
| MultiImplementationA.cs:21:19:21:22 | call to constructor C2 | MultiImplementationA.cs:21:12:21:13 | C2 |
| MultiImplementationA.cs:21:19:21:22 | call to constructor C2 | MultiImplementationB.cs:19:12:19:13 | C2 |
| MultiImplementationA.cs:21:24:21:24 | 0 | MultiImplementationA.cs:21:12:21:13 | C2 |
| MultiImplementationA.cs:21:24:21:24 | 0 | MultiImplementationB.cs:19:12:19:13 | C2 |
| MultiImplementationA.cs:21:27:21:29 | {...} | MultiImplementationA.cs:21:12:21:13 | C2 |
| MultiImplementationA.cs:21:27:21:29 | {...} | MultiImplementationB.cs:19:12:19:13 | C2 |
| MultiImplementationA.cs:22:6:22:7 | enter ~C2 | MultiImplementationA.cs:22:6:22:7 | ~C2 |
| MultiImplementationA.cs:22:6:22:7 | enter ~C2 | MultiImplementationB.cs:20:6:20:7 | ~C2 |
| MultiImplementationA.cs:22:6:22:7 | exit ~C2 | MultiImplementationA.cs:22:6:22:7 | ~C2 |
| MultiImplementationA.cs:22:6:22:7 | exit ~C2 | MultiImplementationB.cs:20:6:20:7 | ~C2 |
| MultiImplementationA.cs:22:11:22:13 | {...} | MultiImplementationA.cs:22:6:22:7 | ~C2 |
| MultiImplementationA.cs:22:11:22:13 | {...} | MultiImplementationB.cs:20:6:20:7 | ~C2 |
| MultiImplementationA.cs:23:28:23:35 | enter implicit conversion | MultiImplementationA.cs:23:28:23:35 | implicit conversion |
| MultiImplementationA.cs:23:28:23:35 | enter implicit conversion | MultiImplementationB.cs:21:28:21:35 | implicit conversion |
| MultiImplementationA.cs:23:28:23:35 | exit implicit conversion | MultiImplementationA.cs:23:28:23:35 | implicit conversion |
| MultiImplementationA.cs:23:28:23:35 | exit implicit conversion | MultiImplementationB.cs:21:28:21:35 | implicit conversion |
| MultiImplementationA.cs:23:50:23:53 | null | MultiImplementationA.cs:23:28:23:35 | implicit conversion |
| MultiImplementationA.cs:23:50:23:53 | null | MultiImplementationB.cs:21:28:21:35 | implicit conversion |
| MultiImplementationA.cs:24:16:24:16 | access to property P | MultiImplementationA.cs:20:12:20:13 | C2 |
| MultiImplementationA.cs:24:16:24:16 | access to property P | MultiImplementationB.cs:18:12:18:13 | C2 |
| MultiImplementationA.cs:24:16:24:16 | this access | MultiImplementationA.cs:20:12:20:13 | C2 |
| MultiImplementationA.cs:24:16:24:16 | this access | MultiImplementationB.cs:18:12:18:13 | C2 |
| MultiImplementationA.cs:24:32:24:34 | ... = ... | MultiImplementationA.cs:20:12:20:13 | C2 |
| MultiImplementationA.cs:24:32:24:34 | ... = ... | MultiImplementationB.cs:18:12:18:13 | C2 |
| MultiImplementationA.cs:24:34:24:34 | 0 | MultiImplementationA.cs:20:12:20:13 | C2 |
| MultiImplementationA.cs:24:34:24:34 | 0 | MultiImplementationB.cs:18:12:18:13 | C2 |
| MultiImplementationA.cs:30:21:30:23 | enter get_P3 | MultiImplementationA.cs:30:21:30:23 | get_P3 |
| MultiImplementationA.cs:30:21:30:23 | enter get_P3 | MultiImplementationB.cs:27:21:27:23 | get_P3 |
| MultiImplementationA.cs:30:21:30:23 | exit get_P3 | MultiImplementationA.cs:30:21:30:23 | get_P3 |
| MultiImplementationA.cs:30:21:30:23 | exit get_P3 | MultiImplementationB.cs:27:21:27:23 | get_P3 |
| MultiImplementationA.cs:30:28:30:37 | throw ... | MultiImplementationA.cs:30:21:30:23 | get_P3 |
| MultiImplementationA.cs:30:28:30:37 | throw ... | MultiImplementationB.cs:27:21:27:23 | get_P3 |
| MultiImplementationA.cs:30:34:30:37 | null | MultiImplementationA.cs:30:21:30:23 | get_P3 |
| MultiImplementationA.cs:30:34:30:37 | null | MultiImplementationB.cs:27:21:27:23 | get_P3 |
| MultiImplementationA.cs:36:9:36:10 | enter M1 | MultiImplementationA.cs:36:9:36:10 | M1 |
| MultiImplementationA.cs:36:9:36:10 | enter M1 | MultiImplementationB.cs:32:9:32:10 | M1 |
| MultiImplementationA.cs:36:9:36:10 | exit M1 | MultiImplementationA.cs:36:9:36:10 | M1 |
| MultiImplementationA.cs:36:9:36:10 | exit M1 | MultiImplementationB.cs:32:9:32:10 | M1 |
| MultiImplementationA.cs:36:14:36:28 | {...} | MultiImplementationA.cs:36:9:36:10 | M1 |
| MultiImplementationA.cs:36:14:36:28 | {...} | MultiImplementationB.cs:32:9:32:10 | M1 |
| MultiImplementationA.cs:36:16:36:26 | throw ...; | MultiImplementationA.cs:36:9:36:10 | M1 |
| MultiImplementationA.cs:36:16:36:26 | throw ...; | MultiImplementationB.cs:32:9:32:10 | M1 |
| MultiImplementationA.cs:36:22:36:25 | null | MultiImplementationA.cs:36:9:36:10 | M1 |
| MultiImplementationA.cs:36:22:36:25 | null | MultiImplementationB.cs:32:9:32:10 | M1 |
| MultiImplementationA.cs:37:9:37:10 | enter M2 | MultiImplementationA.cs:37:9:37:10 | M2 |
| MultiImplementationA.cs:37:9:37:10 | exit M2 | MultiImplementationA.cs:37:9:37:10 | M2 |
| MultiImplementationA.cs:37:14:37:28 | {...} | MultiImplementationA.cs:37:9:37:10 | M2 |
| MultiImplementationA.cs:37:16:37:26 | throw ...; | MultiImplementationA.cs:37:9:37:10 | M2 |
| MultiImplementationA.cs:37:22:37:25 | null | MultiImplementationA.cs:37:9:37:10 | M2 |
| MultiImplementationB.cs:3:22:3:22 | 0 | MultiImplementationA.cs:6:22:6:31 | get_P1 |
| MultiImplementationB.cs:3:22:3:22 | 0 | MultiImplementationB.cs:3:22:3:22 | get_P1 |
| MultiImplementationB.cs:3:22:3:22 | enter get_P1 | MultiImplementationA.cs:6:22:6:31 | get_P1 |
| MultiImplementationB.cs:3:22:3:22 | enter get_P1 | MultiImplementationB.cs:3:22:3:22 | get_P1 |
| MultiImplementationB.cs:3:22:3:22 | exit get_P1 | MultiImplementationA.cs:6:22:6:31 | get_P1 |
| MultiImplementationB.cs:3:22:3:22 | exit get_P1 | MultiImplementationB.cs:3:22:3:22 | get_P1 |
| MultiImplementationB.cs:4:21:4:23 | enter get_P2 | MultiImplementationA.cs:7:21:7:23 | get_P2 |
| MultiImplementationB.cs:4:21:4:23 | enter get_P2 | MultiImplementationB.cs:4:21:4:23 | get_P2 |
| MultiImplementationB.cs:4:21:4:23 | exit get_P2 | MultiImplementationA.cs:7:21:7:23 | get_P2 |
| MultiImplementationB.cs:4:21:4:23 | exit get_P2 | MultiImplementationB.cs:4:21:4:23 | get_P2 |
| MultiImplementationB.cs:4:25:4:37 | {...} | MultiImplementationA.cs:7:21:7:23 | get_P2 |
| MultiImplementationB.cs:4:25:4:37 | {...} | MultiImplementationB.cs:4:21:4:23 | get_P2 |
| MultiImplementationB.cs:4:27:4:35 | return ...; | MultiImplementationA.cs:7:21:7:23 | get_P2 |
| MultiImplementationB.cs:4:27:4:35 | return ...; | MultiImplementationB.cs:4:21:4:23 | get_P2 |
| MultiImplementationB.cs:4:34:4:34 | 1 | MultiImplementationA.cs:7:21:7:23 | get_P2 |
| MultiImplementationB.cs:4:34:4:34 | 1 | MultiImplementationB.cs:4:21:4:23 | get_P2 |
| MultiImplementationB.cs:4:39:4:41 | enter set_P2 | MultiImplementationA.cs:7:41:7:43 | set_P2 |
| MultiImplementationB.cs:4:39:4:41 | enter set_P2 | MultiImplementationB.cs:4:39:4:41 | set_P2 |
| MultiImplementationB.cs:4:39:4:41 | exit set_P2 | MultiImplementationA.cs:7:41:7:43 | set_P2 |
| MultiImplementationB.cs:4:39:4:41 | exit set_P2 | MultiImplementationB.cs:4:39:4:41 | set_P2 |
| MultiImplementationB.cs:4:43:4:45 | {...} | MultiImplementationA.cs:7:41:7:43 | set_P2 |
| MultiImplementationB.cs:4:43:4:45 | {...} | MultiImplementationB.cs:4:39:4:41 | set_P2 |
| MultiImplementationB.cs:5:16:5:16 | enter M | MultiImplementationA.cs:8:16:8:16 | M |
| MultiImplementationB.cs:5:16:5:16 | enter M | MultiImplementationB.cs:5:16:5:16 | M |
| MultiImplementationB.cs:5:16:5:16 | exit M | MultiImplementationA.cs:8:16:8:16 | M |
| MultiImplementationB.cs:5:16:5:16 | exit M | MultiImplementationB.cs:5:16:5:16 | M |
| MultiImplementationB.cs:5:23:5:23 | 2 | MultiImplementationA.cs:8:16:8:16 | M |
| MultiImplementationB.cs:5:23:5:23 | 2 | MultiImplementationB.cs:5:16:5:16 | M |
| MultiImplementationB.cs:11:16:11:16 | this access | MultiImplementationA.cs:20:12:20:13 | C2 |
| MultiImplementationB.cs:11:16:11:16 | this access | MultiImplementationB.cs:18:12:18:13 | C2 |
| MultiImplementationB.cs:11:16:11:20 | ... = ... | MultiImplementationA.cs:20:12:20:13 | C2 |
| MultiImplementationB.cs:11:16:11:20 | ... = ... | MultiImplementationB.cs:18:12:18:13 | C2 |
| MultiImplementationB.cs:11:20:11:20 | 1 | MultiImplementationA.cs:20:12:20:13 | C2 |
| MultiImplementationB.cs:11:20:11:20 | 1 | MultiImplementationB.cs:18:12:18:13 | C2 |
| MultiImplementationB.cs:12:31:12:40 | enter get_Item | MultiImplementationA.cs:14:31:14:31 | get_Item |
| MultiImplementationB.cs:12:31:12:40 | enter get_Item | MultiImplementationB.cs:12:31:12:40 | get_Item |
| MultiImplementationB.cs:12:31:12:40 | exit get_Item | MultiImplementationA.cs:14:31:14:31 | get_Item |
| MultiImplementationB.cs:12:31:12:40 | exit get_Item | MultiImplementationB.cs:12:31:12:40 | get_Item |
| MultiImplementationB.cs:12:31:12:40 | throw ... | MultiImplementationA.cs:14:31:14:31 | get_Item |
| MultiImplementationB.cs:12:31:12:40 | throw ... | MultiImplementationB.cs:12:31:12:40 | get_Item |
| MultiImplementationB.cs:12:37:12:40 | null | MultiImplementationA.cs:14:31:14:31 | get_Item |
| MultiImplementationB.cs:12:37:12:40 | null | MultiImplementationB.cs:12:31:12:40 | get_Item |
| MultiImplementationB.cs:13:36:13:38 | enter get_Item | MultiImplementationA.cs:15:36:15:38 | get_Item |
| MultiImplementationB.cs:13:36:13:38 | enter get_Item | MultiImplementationB.cs:13:36:13:38 | get_Item |
| MultiImplementationB.cs:13:36:13:38 | exit get_Item | MultiImplementationA.cs:15:36:15:38 | get_Item |
| MultiImplementationB.cs:13:36:13:38 | exit get_Item | MultiImplementationB.cs:13:36:13:38 | get_Item |
| MultiImplementationB.cs:13:40:13:54 | {...} | MultiImplementationA.cs:15:36:15:38 | get_Item |
| MultiImplementationB.cs:13:40:13:54 | {...} | MultiImplementationB.cs:13:36:13:38 | get_Item |
| MultiImplementationB.cs:13:42:13:52 | throw ...; | MultiImplementationA.cs:15:36:15:38 | get_Item |
| MultiImplementationB.cs:13:42:13:52 | throw ...; | MultiImplementationB.cs:13:36:13:38 | get_Item |
| MultiImplementationB.cs:13:48:13:51 | null | MultiImplementationA.cs:15:36:15:38 | get_Item |
| MultiImplementationB.cs:13:48:13:51 | null | MultiImplementationB.cs:13:36:13:38 | get_Item |
| MultiImplementationB.cs:13:56:13:58 | enter set_Item | MultiImplementationA.cs:15:54:15:56 | set_Item |
| MultiImplementationB.cs:13:56:13:58 | enter set_Item | MultiImplementationB.cs:13:56:13:58 | set_Item |
| MultiImplementationB.cs:13:56:13:58 | exit set_Item | MultiImplementationA.cs:15:54:15:56 | set_Item |
| MultiImplementationB.cs:13:56:13:58 | exit set_Item | MultiImplementationB.cs:13:56:13:58 | set_Item |
| MultiImplementationB.cs:13:60:13:62 | {...} | MultiImplementationA.cs:15:54:15:56 | set_Item |
| MultiImplementationB.cs:13:60:13:62 | {...} | MultiImplementationB.cs:13:56:13:58 | set_Item |
| MultiImplementationB.cs:14:17:14:18 | enter M1 | MultiImplementationA.cs:16:17:16:18 | M1 |
| MultiImplementationB.cs:14:17:14:18 | enter M1 | MultiImplementationB.cs:14:17:14:18 | M1 |
| MultiImplementationB.cs:14:17:14:18 | exit M1 | MultiImplementationA.cs:16:17:16:18 | M1 |
| MultiImplementationB.cs:14:17:14:18 | exit M1 | MultiImplementationB.cs:14:17:14:18 | M1 |
| MultiImplementationB.cs:15:5:17:5 | {...} | MultiImplementationA.cs:16:17:16:18 | M1 |
| MultiImplementationB.cs:15:5:17:5 | {...} | MultiImplementationB.cs:14:17:14:18 | M1 |
| MultiImplementationB.cs:16:9:16:31 | M2(...) | MultiImplementationA.cs:16:17:16:18 | M1 |
| MultiImplementationB.cs:16:9:16:31 | M2(...) | MultiImplementationB.cs:14:17:14:18 | M1 |
| MultiImplementationB.cs:16:9:16:31 | enter M2 | MultiImplementationB.cs:16:9:16:31 | M2 |
| MultiImplementationB.cs:16:9:16:31 | exit M2 | MultiImplementationB.cs:16:9:16:31 | M2 |
| MultiImplementationB.cs:16:21:16:30 | throw ... | MultiImplementationB.cs:16:9:16:31 | M2 |
| MultiImplementationB.cs:16:27:16:30 | null | MultiImplementationB.cs:16:9:16:31 | M2 |
| MultiImplementationB.cs:18:12:18:13 | enter C2 | MultiImplementationA.cs:20:12:20:13 | C2 |
| MultiImplementationB.cs:18:12:18:13 | enter C2 | MultiImplementationB.cs:18:12:18:13 | C2 |
| MultiImplementationB.cs:18:12:18:13 | exit C2 | MultiImplementationA.cs:20:12:20:13 | C2 |
| MultiImplementationB.cs:18:12:18:13 | exit C2 | MultiImplementationB.cs:18:12:18:13 | C2 |
| MultiImplementationB.cs:18:22:18:36 | {...} | MultiImplementationA.cs:20:12:20:13 | C2 |
| MultiImplementationB.cs:18:22:18:36 | {...} | MultiImplementationB.cs:18:12:18:13 | C2 |
| MultiImplementationB.cs:18:24:18:34 | throw ...; | MultiImplementationA.cs:20:12:20:13 | C2 |
| MultiImplementationB.cs:18:24:18:34 | throw ...; | MultiImplementationB.cs:18:12:18:13 | C2 |
| MultiImplementationB.cs:18:30:18:33 | null | MultiImplementationA.cs:20:12:20:13 | C2 |
| MultiImplementationB.cs:18:30:18:33 | null | MultiImplementationB.cs:18:12:18:13 | C2 |
| MultiImplementationB.cs:19:12:19:13 | enter C2 | MultiImplementationA.cs:21:12:21:13 | C2 |
| MultiImplementationB.cs:19:12:19:13 | enter C2 | MultiImplementationB.cs:19:12:19:13 | C2 |
| MultiImplementationB.cs:19:12:19:13 | exit C2 | MultiImplementationA.cs:21:12:21:13 | C2 |
| MultiImplementationB.cs:19:12:19:13 | exit C2 | MultiImplementationB.cs:19:12:19:13 | C2 |
| MultiImplementationB.cs:19:19:19:22 | call to constructor C2 | MultiImplementationA.cs:21:12:21:13 | C2 |
| MultiImplementationB.cs:19:19:19:22 | call to constructor C2 | MultiImplementationB.cs:19:12:19:13 | C2 |
| MultiImplementationB.cs:19:24:19:24 | 1 | MultiImplementationA.cs:21:12:21:13 | C2 |
| MultiImplementationB.cs:19:24:19:24 | 1 | MultiImplementationB.cs:19:12:19:13 | C2 |
| MultiImplementationB.cs:19:27:19:29 | {...} | MultiImplementationA.cs:21:12:21:13 | C2 |
| MultiImplementationB.cs:19:27:19:29 | {...} | MultiImplementationB.cs:19:12:19:13 | C2 |
| MultiImplementationB.cs:20:6:20:7 | enter ~C2 | MultiImplementationA.cs:22:6:22:7 | ~C2 |
| MultiImplementationB.cs:20:6:20:7 | enter ~C2 | MultiImplementationB.cs:20:6:20:7 | ~C2 |
| MultiImplementationB.cs:20:6:20:7 | exit ~C2 | MultiImplementationA.cs:22:6:22:7 | ~C2 |
| MultiImplementationB.cs:20:6:20:7 | exit ~C2 | MultiImplementationB.cs:20:6:20:7 | ~C2 |
| MultiImplementationB.cs:20:11:20:25 | {...} | MultiImplementationA.cs:22:6:22:7 | ~C2 |
| MultiImplementationB.cs:20:11:20:25 | {...} | MultiImplementationB.cs:20:6:20:7 | ~C2 |
| MultiImplementationB.cs:20:13:20:23 | throw ...; | MultiImplementationA.cs:22:6:22:7 | ~C2 |
| MultiImplementationB.cs:20:13:20:23 | throw ...; | MultiImplementationB.cs:20:6:20:7 | ~C2 |
| MultiImplementationB.cs:20:19:20:22 | null | MultiImplementationA.cs:22:6:22:7 | ~C2 |
| MultiImplementationB.cs:20:19:20:22 | null | MultiImplementationB.cs:20:6:20:7 | ~C2 |
| MultiImplementationB.cs:21:28:21:35 | enter implicit conversion | MultiImplementationA.cs:23:28:23:35 | implicit conversion |
| MultiImplementationB.cs:21:28:21:35 | enter implicit conversion | MultiImplementationB.cs:21:28:21:35 | implicit conversion |
| MultiImplementationB.cs:21:28:21:35 | exit implicit conversion | MultiImplementationA.cs:23:28:23:35 | implicit conversion |
| MultiImplementationB.cs:21:28:21:35 | exit implicit conversion | MultiImplementationB.cs:21:28:21:35 | implicit conversion |
| MultiImplementationB.cs:21:50:21:59 | throw ... | MultiImplementationA.cs:23:28:23:35 | implicit conversion |
| MultiImplementationB.cs:21:50:21:59 | throw ... | MultiImplementationB.cs:21:28:21:35 | implicit conversion |
| MultiImplementationB.cs:21:56:21:59 | null | MultiImplementationA.cs:23:28:23:35 | implicit conversion |
| MultiImplementationB.cs:21:56:21:59 | null | MultiImplementationB.cs:21:28:21:35 | implicit conversion |
| MultiImplementationB.cs:22:16:22:16 | access to property P | MultiImplementationA.cs:20:12:20:13 | C2 |
| MultiImplementationB.cs:22:16:22:16 | access to property P | MultiImplementationB.cs:18:12:18:13 | C2 |
| MultiImplementationB.cs:22:16:22:16 | this access | MultiImplementationA.cs:20:12:20:13 | C2 |
| MultiImplementationB.cs:22:16:22:16 | this access | MultiImplementationB.cs:18:12:18:13 | C2 |
| MultiImplementationB.cs:22:32:22:34 | ... = ... | MultiImplementationA.cs:20:12:20:13 | C2 |
| MultiImplementationB.cs:22:32:22:34 | ... = ... | MultiImplementationB.cs:18:12:18:13 | C2 |
| MultiImplementationB.cs:22:34:22:34 | 1 | MultiImplementationA.cs:20:12:20:13 | C2 |
| MultiImplementationB.cs:22:34:22:34 | 1 | MultiImplementationB.cs:18:12:18:13 | C2 |
| MultiImplementationB.cs:27:21:27:23 | enter get_P3 | MultiImplementationA.cs:30:21:30:23 | get_P3 |
| MultiImplementationB.cs:27:21:27:23 | enter get_P3 | MultiImplementationB.cs:27:21:27:23 | get_P3 |
| MultiImplementationB.cs:27:21:27:23 | exit get_P3 | MultiImplementationA.cs:30:21:30:23 | get_P3 |
| MultiImplementationB.cs:27:21:27:23 | exit get_P3 | MultiImplementationB.cs:27:21:27:23 | get_P3 |
| MultiImplementationB.cs:32:9:32:10 | enter M1 | MultiImplementationA.cs:36:9:36:10 | M1 |
| MultiImplementationB.cs:32:9:32:10 | enter M1 | MultiImplementationB.cs:32:9:32:10 | M1 |
| MultiImplementationB.cs:32:9:32:10 | exit M1 | MultiImplementationA.cs:36:9:36:10 | M1 |
| MultiImplementationB.cs:32:9:32:10 | exit M1 | MultiImplementationB.cs:32:9:32:10 | M1 |
| MultiImplementationB.cs:32:17:32:17 | 0 | MultiImplementationA.cs:36:9:36:10 | M1 |
| MultiImplementationB.cs:32:17:32:17 | 0 | MultiImplementationB.cs:32:9:32:10 | M1 |
| NullCoalescing.cs:3:9:3:10 | enter M1 | NullCoalescing.cs:3:9:3:10 | M1 |
| NullCoalescing.cs:3:9:3:10 | exit M1 | NullCoalescing.cs:3:9:3:10 | M1 |
| NullCoalescing.cs:3:23:3:23 | access to parameter i | NullCoalescing.cs:3:9:3:10 | M1 |
@@ -3773,6 +4041,181 @@ blockEnclosing
| LoopUnrolling.cs:71:9:71:21 | ...; | LoopUnrolling.cs:67:10:67:11 | M8 |
| LoopUnrolling.cs:72:9:73:35 | foreach (... ... in ...) ... | LoopUnrolling.cs:67:10:67:11 | M8 |
| LoopUnrolling.cs:72:21:72:23 | String arg | LoopUnrolling.cs:67:10:67:11 | M8 |
| MultiImplementationA.cs:6:22:6:31 | enter get_P1 | MultiImplementationA.cs:6:22:6:31 | get_P1 |
| MultiImplementationA.cs:6:22:6:31 | enter get_P1 | MultiImplementationB.cs:3:22:3:22 | get_P1 |
| MultiImplementationA.cs:6:22:6:31 | exit get_P1 | MultiImplementationA.cs:6:22:6:31 | get_P1 |
| MultiImplementationA.cs:6:22:6:31 | exit get_P1 | MultiImplementationB.cs:3:22:3:22 | get_P1 |
| MultiImplementationA.cs:6:28:6:31 | null | MultiImplementationA.cs:6:22:6:31 | get_P1 |
| MultiImplementationA.cs:6:28:6:31 | null | MultiImplementationB.cs:3:22:3:22 | get_P1 |
| MultiImplementationA.cs:7:21:7:23 | enter get_P2 | MultiImplementationA.cs:7:21:7:23 | get_P2 |
| MultiImplementationA.cs:7:21:7:23 | enter get_P2 | MultiImplementationB.cs:4:21:4:23 | get_P2 |
| MultiImplementationA.cs:7:21:7:23 | exit get_P2 | MultiImplementationA.cs:7:21:7:23 | get_P2 |
| MultiImplementationA.cs:7:21:7:23 | exit get_P2 | MultiImplementationB.cs:4:21:4:23 | get_P2 |
| MultiImplementationA.cs:7:25:7:39 | {...} | MultiImplementationA.cs:7:21:7:23 | get_P2 |
| MultiImplementationA.cs:7:25:7:39 | {...} | MultiImplementationB.cs:4:21:4:23 | get_P2 |
| MultiImplementationA.cs:7:41:7:43 | enter set_P2 | MultiImplementationA.cs:7:41:7:43 | set_P2 |
| MultiImplementationA.cs:7:41:7:43 | enter set_P2 | MultiImplementationB.cs:4:39:4:41 | set_P2 |
| MultiImplementationA.cs:7:41:7:43 | exit set_P2 | MultiImplementationA.cs:7:41:7:43 | set_P2 |
| MultiImplementationA.cs:7:41:7:43 | exit set_P2 | MultiImplementationB.cs:4:39:4:41 | set_P2 |
| MultiImplementationA.cs:7:45:7:59 | {...} | MultiImplementationA.cs:7:41:7:43 | set_P2 |
| MultiImplementationA.cs:7:45:7:59 | {...} | MultiImplementationB.cs:4:39:4:41 | set_P2 |
| MultiImplementationA.cs:8:16:8:16 | enter M | MultiImplementationA.cs:8:16:8:16 | M |
| MultiImplementationA.cs:8:16:8:16 | enter M | MultiImplementationB.cs:5:16:5:16 | M |
| MultiImplementationA.cs:8:16:8:16 | exit M | MultiImplementationA.cs:8:16:8:16 | M |
| MultiImplementationA.cs:8:16:8:16 | exit M | MultiImplementationB.cs:5:16:5:16 | M |
| MultiImplementationA.cs:8:29:8:32 | null | MultiImplementationA.cs:8:16:8:16 | M |
| MultiImplementationA.cs:8:29:8:32 | null | MultiImplementationB.cs:5:16:5:16 | M |
| MultiImplementationA.cs:13:16:13:16 | this access | MultiImplementationA.cs:20:12:20:13 | C2 |
| MultiImplementationA.cs:13:16:13:16 | this access | MultiImplementationB.cs:18:12:18:13 | C2 |
| MultiImplementationA.cs:14:31:14:31 | access to parameter i | MultiImplementationA.cs:14:31:14:31 | get_Item |
| MultiImplementationA.cs:14:31:14:31 | access to parameter i | MultiImplementationB.cs:12:31:12:40 | get_Item |
| MultiImplementationA.cs:14:31:14:31 | enter get_Item | MultiImplementationA.cs:14:31:14:31 | get_Item |
| MultiImplementationA.cs:14:31:14:31 | enter get_Item | MultiImplementationB.cs:12:31:12:40 | get_Item |
| MultiImplementationA.cs:14:31:14:31 | exit get_Item | MultiImplementationA.cs:14:31:14:31 | get_Item |
| MultiImplementationA.cs:14:31:14:31 | exit get_Item | MultiImplementationB.cs:12:31:12:40 | get_Item |
| MultiImplementationA.cs:15:36:15:38 | enter get_Item | MultiImplementationA.cs:15:36:15:38 | get_Item |
| MultiImplementationA.cs:15:36:15:38 | enter get_Item | MultiImplementationB.cs:13:36:13:38 | get_Item |
| MultiImplementationA.cs:15:36:15:38 | exit get_Item | MultiImplementationA.cs:15:36:15:38 | get_Item |
| MultiImplementationA.cs:15:36:15:38 | exit get_Item | MultiImplementationB.cs:13:36:13:38 | get_Item |
| MultiImplementationA.cs:15:40:15:52 | {...} | MultiImplementationA.cs:15:36:15:38 | get_Item |
| MultiImplementationA.cs:15:40:15:52 | {...} | MultiImplementationB.cs:13:36:13:38 | get_Item |
| MultiImplementationA.cs:15:54:15:56 | enter set_Item | MultiImplementationA.cs:15:54:15:56 | set_Item |
| MultiImplementationA.cs:15:54:15:56 | enter set_Item | MultiImplementationB.cs:13:56:13:58 | set_Item |
| MultiImplementationA.cs:15:54:15:56 | exit set_Item | MultiImplementationA.cs:15:54:15:56 | set_Item |
| MultiImplementationA.cs:15:54:15:56 | exit set_Item | MultiImplementationB.cs:13:56:13:58 | set_Item |
| MultiImplementationA.cs:15:58:15:60 | {...} | MultiImplementationA.cs:15:54:15:56 | set_Item |
| MultiImplementationA.cs:15:58:15:60 | {...} | MultiImplementationB.cs:13:56:13:58 | set_Item |
| MultiImplementationA.cs:16:17:16:18 | enter M1 | MultiImplementationA.cs:16:17:16:18 | M1 |
| MultiImplementationA.cs:16:17:16:18 | enter M1 | MultiImplementationB.cs:14:17:14:18 | M1 |
| MultiImplementationA.cs:16:17:16:18 | exit M1 | MultiImplementationA.cs:16:17:16:18 | M1 |
| MultiImplementationA.cs:16:17:16:18 | exit M1 | MultiImplementationB.cs:14:17:14:18 | M1 |
| MultiImplementationA.cs:17:5:19:5 | {...} | MultiImplementationA.cs:16:17:16:18 | M1 |
| MultiImplementationA.cs:17:5:19:5 | {...} | MultiImplementationB.cs:14:17:14:18 | M1 |
| MultiImplementationA.cs:18:9:18:22 | enter M2 | MultiImplementationA.cs:18:9:18:22 | M2 |
| MultiImplementationA.cs:20:12:20:13 | enter C2 | MultiImplementationA.cs:20:12:20:13 | C2 |
| MultiImplementationA.cs:20:12:20:13 | enter C2 | MultiImplementationB.cs:18:12:18:13 | C2 |
| MultiImplementationA.cs:20:12:20:13 | exit C2 | MultiImplementationA.cs:20:12:20:13 | C2 |
| MultiImplementationA.cs:20:12:20:13 | exit C2 | MultiImplementationB.cs:18:12:18:13 | C2 |
| MultiImplementationA.cs:20:22:20:31 | {...} | MultiImplementationA.cs:20:12:20:13 | C2 |
| MultiImplementationA.cs:20:22:20:31 | {...} | MultiImplementationB.cs:18:12:18:13 | C2 |
| MultiImplementationA.cs:21:12:21:13 | enter C2 | MultiImplementationA.cs:21:12:21:13 | C2 |
| MultiImplementationA.cs:21:12:21:13 | enter C2 | MultiImplementationB.cs:19:12:19:13 | C2 |
| MultiImplementationA.cs:21:12:21:13 | exit C2 | MultiImplementationA.cs:21:12:21:13 | C2 |
| MultiImplementationA.cs:21:12:21:13 | exit C2 | MultiImplementationB.cs:19:12:19:13 | C2 |
| MultiImplementationA.cs:21:24:21:24 | 0 | MultiImplementationA.cs:21:12:21:13 | C2 |
| MultiImplementationA.cs:21:24:21:24 | 0 | MultiImplementationB.cs:19:12:19:13 | C2 |
| MultiImplementationA.cs:21:27:21:29 | {...} | MultiImplementationA.cs:21:12:21:13 | C2 |
| MultiImplementationA.cs:21:27:21:29 | {...} | MultiImplementationB.cs:19:12:19:13 | C2 |
| MultiImplementationA.cs:22:6:22:7 | enter ~C2 | MultiImplementationA.cs:22:6:22:7 | ~C2 |
| MultiImplementationA.cs:22:6:22:7 | enter ~C2 | MultiImplementationB.cs:20:6:20:7 | ~C2 |
| MultiImplementationA.cs:22:6:22:7 | exit ~C2 | MultiImplementationA.cs:22:6:22:7 | ~C2 |
| MultiImplementationA.cs:22:6:22:7 | exit ~C2 | MultiImplementationB.cs:20:6:20:7 | ~C2 |
| MultiImplementationA.cs:22:11:22:13 | {...} | MultiImplementationA.cs:22:6:22:7 | ~C2 |
| MultiImplementationA.cs:22:11:22:13 | {...} | MultiImplementationB.cs:20:6:20:7 | ~C2 |
| MultiImplementationA.cs:23:28:23:35 | enter implicit conversion | MultiImplementationA.cs:23:28:23:35 | implicit conversion |
| MultiImplementationA.cs:23:28:23:35 | enter implicit conversion | MultiImplementationB.cs:21:28:21:35 | implicit conversion |
| MultiImplementationA.cs:23:28:23:35 | exit implicit conversion | MultiImplementationA.cs:23:28:23:35 | implicit conversion |
| MultiImplementationA.cs:23:28:23:35 | exit implicit conversion | MultiImplementationB.cs:21:28:21:35 | implicit conversion |
| MultiImplementationA.cs:23:50:23:53 | null | MultiImplementationA.cs:23:28:23:35 | implicit conversion |
| MultiImplementationA.cs:23:50:23:53 | null | MultiImplementationB.cs:21:28:21:35 | implicit conversion |
| MultiImplementationA.cs:24:16:24:16 | this access | MultiImplementationA.cs:20:12:20:13 | C2 |
| MultiImplementationA.cs:24:16:24:16 | this access | MultiImplementationB.cs:18:12:18:13 | C2 |
| MultiImplementationA.cs:30:21:30:23 | enter get_P3 | MultiImplementationA.cs:30:21:30:23 | get_P3 |
| MultiImplementationA.cs:30:21:30:23 | enter get_P3 | MultiImplementationB.cs:27:21:27:23 | get_P3 |
| MultiImplementationA.cs:36:9:36:10 | enter M1 | MultiImplementationA.cs:36:9:36:10 | M1 |
| MultiImplementationA.cs:36:9:36:10 | enter M1 | MultiImplementationB.cs:32:9:32:10 | M1 |
| MultiImplementationA.cs:36:9:36:10 | exit M1 | MultiImplementationA.cs:36:9:36:10 | M1 |
| MultiImplementationA.cs:36:9:36:10 | exit M1 | MultiImplementationB.cs:32:9:32:10 | M1 |
| MultiImplementationA.cs:36:14:36:28 | {...} | MultiImplementationA.cs:36:9:36:10 | M1 |
| MultiImplementationA.cs:36:14:36:28 | {...} | MultiImplementationB.cs:32:9:32:10 | M1 |
| MultiImplementationA.cs:37:9:37:10 | enter M2 | MultiImplementationA.cs:37:9:37:10 | M2 |
| MultiImplementationB.cs:3:22:3:22 | 0 | MultiImplementationA.cs:6:22:6:31 | get_P1 |
| MultiImplementationB.cs:3:22:3:22 | 0 | MultiImplementationB.cs:3:22:3:22 | get_P1 |
| MultiImplementationB.cs:3:22:3:22 | enter get_P1 | MultiImplementationA.cs:6:22:6:31 | get_P1 |
| MultiImplementationB.cs:3:22:3:22 | enter get_P1 | MultiImplementationB.cs:3:22:3:22 | get_P1 |
| MultiImplementationB.cs:3:22:3:22 | exit get_P1 | MultiImplementationA.cs:6:22:6:31 | get_P1 |
| MultiImplementationB.cs:3:22:3:22 | exit get_P1 | MultiImplementationB.cs:3:22:3:22 | get_P1 |
| MultiImplementationB.cs:4:21:4:23 | enter get_P2 | MultiImplementationA.cs:7:21:7:23 | get_P2 |
| MultiImplementationB.cs:4:21:4:23 | enter get_P2 | MultiImplementationB.cs:4:21:4:23 | get_P2 |
| MultiImplementationB.cs:4:21:4:23 | exit get_P2 | MultiImplementationA.cs:7:21:7:23 | get_P2 |
| MultiImplementationB.cs:4:21:4:23 | exit get_P2 | MultiImplementationB.cs:4:21:4:23 | get_P2 |
| MultiImplementationB.cs:4:25:4:37 | {...} | MultiImplementationA.cs:7:21:7:23 | get_P2 |
| MultiImplementationB.cs:4:25:4:37 | {...} | MultiImplementationB.cs:4:21:4:23 | get_P2 |
| MultiImplementationB.cs:4:39:4:41 | enter set_P2 | MultiImplementationA.cs:7:41:7:43 | set_P2 |
| MultiImplementationB.cs:4:39:4:41 | enter set_P2 | MultiImplementationB.cs:4:39:4:41 | set_P2 |
| MultiImplementationB.cs:4:39:4:41 | exit set_P2 | MultiImplementationA.cs:7:41:7:43 | set_P2 |
| MultiImplementationB.cs:4:39:4:41 | exit set_P2 | MultiImplementationB.cs:4:39:4:41 | set_P2 |
| MultiImplementationB.cs:4:43:4:45 | {...} | MultiImplementationA.cs:7:41:7:43 | set_P2 |
| MultiImplementationB.cs:4:43:4:45 | {...} | MultiImplementationB.cs:4:39:4:41 | set_P2 |
| MultiImplementationB.cs:5:16:5:16 | enter M | MultiImplementationA.cs:8:16:8:16 | M |
| MultiImplementationB.cs:5:16:5:16 | enter M | MultiImplementationB.cs:5:16:5:16 | M |
| MultiImplementationB.cs:5:16:5:16 | exit M | MultiImplementationA.cs:8:16:8:16 | M |
| MultiImplementationB.cs:5:16:5:16 | exit M | MultiImplementationB.cs:5:16:5:16 | M |
| MultiImplementationB.cs:5:23:5:23 | 2 | MultiImplementationA.cs:8:16:8:16 | M |
| MultiImplementationB.cs:5:23:5:23 | 2 | MultiImplementationB.cs:5:16:5:16 | M |
| MultiImplementationB.cs:11:16:11:16 | this access | MultiImplementationA.cs:20:12:20:13 | C2 |
| MultiImplementationB.cs:11:16:11:16 | this access | MultiImplementationB.cs:18:12:18:13 | C2 |
| MultiImplementationB.cs:12:31:12:40 | enter get_Item | MultiImplementationA.cs:14:31:14:31 | get_Item |
| MultiImplementationB.cs:12:31:12:40 | enter get_Item | MultiImplementationB.cs:12:31:12:40 | get_Item |
| MultiImplementationB.cs:12:31:12:40 | exit get_Item | MultiImplementationA.cs:14:31:14:31 | get_Item |
| MultiImplementationB.cs:12:31:12:40 | exit get_Item | MultiImplementationB.cs:12:31:12:40 | get_Item |
| MultiImplementationB.cs:12:37:12:40 | null | MultiImplementationA.cs:14:31:14:31 | get_Item |
| MultiImplementationB.cs:12:37:12:40 | null | MultiImplementationB.cs:12:31:12:40 | get_Item |
| MultiImplementationB.cs:13:36:13:38 | enter get_Item | MultiImplementationA.cs:15:36:15:38 | get_Item |
| MultiImplementationB.cs:13:36:13:38 | enter get_Item | MultiImplementationB.cs:13:36:13:38 | get_Item |
| MultiImplementationB.cs:13:36:13:38 | exit get_Item | MultiImplementationA.cs:15:36:15:38 | get_Item |
| MultiImplementationB.cs:13:36:13:38 | exit get_Item | MultiImplementationB.cs:13:36:13:38 | get_Item |
| MultiImplementationB.cs:13:40:13:54 | {...} | MultiImplementationA.cs:15:36:15:38 | get_Item |
| MultiImplementationB.cs:13:40:13:54 | {...} | MultiImplementationB.cs:13:36:13:38 | get_Item |
| MultiImplementationB.cs:13:56:13:58 | enter set_Item | MultiImplementationA.cs:15:54:15:56 | set_Item |
| MultiImplementationB.cs:13:56:13:58 | enter set_Item | MultiImplementationB.cs:13:56:13:58 | set_Item |
| MultiImplementationB.cs:13:56:13:58 | exit set_Item | MultiImplementationA.cs:15:54:15:56 | set_Item |
| MultiImplementationB.cs:13:56:13:58 | exit set_Item | MultiImplementationB.cs:13:56:13:58 | set_Item |
| MultiImplementationB.cs:13:60:13:62 | {...} | MultiImplementationA.cs:15:54:15:56 | set_Item |
| MultiImplementationB.cs:13:60:13:62 | {...} | MultiImplementationB.cs:13:56:13:58 | set_Item |
| MultiImplementationB.cs:14:17:14:18 | enter M1 | MultiImplementationA.cs:16:17:16:18 | M1 |
| MultiImplementationB.cs:14:17:14:18 | enter M1 | MultiImplementationB.cs:14:17:14:18 | M1 |
| MultiImplementationB.cs:14:17:14:18 | exit M1 | MultiImplementationA.cs:16:17:16:18 | M1 |
| MultiImplementationB.cs:14:17:14:18 | exit M1 | MultiImplementationB.cs:14:17:14:18 | M1 |
| MultiImplementationB.cs:15:5:17:5 | {...} | MultiImplementationA.cs:16:17:16:18 | M1 |
| MultiImplementationB.cs:15:5:17:5 | {...} | MultiImplementationB.cs:14:17:14:18 | M1 |
| MultiImplementationB.cs:16:9:16:31 | enter M2 | MultiImplementationB.cs:16:9:16:31 | M2 |
| MultiImplementationB.cs:18:12:18:13 | enter C2 | MultiImplementationA.cs:20:12:20:13 | C2 |
| MultiImplementationB.cs:18:12:18:13 | enter C2 | MultiImplementationB.cs:18:12:18:13 | C2 |
| MultiImplementationB.cs:18:12:18:13 | exit C2 | MultiImplementationA.cs:20:12:20:13 | C2 |
| MultiImplementationB.cs:18:12:18:13 | exit C2 | MultiImplementationB.cs:18:12:18:13 | C2 |
| MultiImplementationB.cs:18:22:18:36 | {...} | MultiImplementationA.cs:20:12:20:13 | C2 |
| MultiImplementationB.cs:18:22:18:36 | {...} | MultiImplementationB.cs:18:12:18:13 | C2 |
| MultiImplementationB.cs:19:12:19:13 | enter C2 | MultiImplementationA.cs:21:12:21:13 | C2 |
| MultiImplementationB.cs:19:12:19:13 | enter C2 | MultiImplementationB.cs:19:12:19:13 | C2 |
| MultiImplementationB.cs:19:12:19:13 | exit C2 | MultiImplementationA.cs:21:12:21:13 | C2 |
| MultiImplementationB.cs:19:12:19:13 | exit C2 | MultiImplementationB.cs:19:12:19:13 | C2 |
| MultiImplementationB.cs:19:24:19:24 | 1 | MultiImplementationA.cs:21:12:21:13 | C2 |
| MultiImplementationB.cs:19:24:19:24 | 1 | MultiImplementationB.cs:19:12:19:13 | C2 |
| MultiImplementationB.cs:19:27:19:29 | {...} | MultiImplementationA.cs:21:12:21:13 | C2 |
| MultiImplementationB.cs:19:27:19:29 | {...} | MultiImplementationB.cs:19:12:19:13 | C2 |
| MultiImplementationB.cs:20:6:20:7 | enter ~C2 | MultiImplementationA.cs:22:6:22:7 | ~C2 |
| MultiImplementationB.cs:20:6:20:7 | enter ~C2 | MultiImplementationB.cs:20:6:20:7 | ~C2 |
| MultiImplementationB.cs:20:6:20:7 | exit ~C2 | MultiImplementationA.cs:22:6:22:7 | ~C2 |
| MultiImplementationB.cs:20:6:20:7 | exit ~C2 | MultiImplementationB.cs:20:6:20:7 | ~C2 |
| MultiImplementationB.cs:20:11:20:25 | {...} | MultiImplementationA.cs:22:6:22:7 | ~C2 |
| MultiImplementationB.cs:20:11:20:25 | {...} | MultiImplementationB.cs:20:6:20:7 | ~C2 |
| MultiImplementationB.cs:21:28:21:35 | enter implicit conversion | MultiImplementationA.cs:23:28:23:35 | implicit conversion |
| MultiImplementationB.cs:21:28:21:35 | enter implicit conversion | MultiImplementationB.cs:21:28:21:35 | implicit conversion |
| MultiImplementationB.cs:21:28:21:35 | exit implicit conversion | MultiImplementationA.cs:23:28:23:35 | implicit conversion |
| MultiImplementationB.cs:21:28:21:35 | exit implicit conversion | MultiImplementationB.cs:21:28:21:35 | implicit conversion |
| MultiImplementationB.cs:21:56:21:59 | null | MultiImplementationA.cs:23:28:23:35 | implicit conversion |
| MultiImplementationB.cs:21:56:21:59 | null | MultiImplementationB.cs:21:28:21:35 | implicit conversion |
| MultiImplementationB.cs:22:16:22:16 | this access | MultiImplementationA.cs:20:12:20:13 | C2 |
| MultiImplementationB.cs:22:16:22:16 | this access | MultiImplementationB.cs:18:12:18:13 | C2 |
| MultiImplementationB.cs:27:21:27:23 | enter get_P3 | MultiImplementationA.cs:30:21:30:23 | get_P3 |
| MultiImplementationB.cs:27:21:27:23 | enter get_P3 | MultiImplementationB.cs:27:21:27:23 | get_P3 |
| MultiImplementationB.cs:32:9:32:10 | enter M1 | MultiImplementationA.cs:36:9:36:10 | M1 |
| MultiImplementationB.cs:32:9:32:10 | enter M1 | MultiImplementationB.cs:32:9:32:10 | M1 |
| MultiImplementationB.cs:32:9:32:10 | exit M1 | MultiImplementationA.cs:36:9:36:10 | M1 |
| MultiImplementationB.cs:32:9:32:10 | exit M1 | MultiImplementationB.cs:32:9:32:10 | M1 |
| MultiImplementationB.cs:32:17:32:17 | 0 | MultiImplementationA.cs:36:9:36:10 | M1 |
| MultiImplementationB.cs:32:17:32:17 | 0 | MultiImplementationB.cs:32:9:32:10 | M1 |
| NullCoalescing.cs:3:9:3:10 | enter M1 | NullCoalescing.cs:3:9:3:10 | M1 |
| NullCoalescing.cs:3:9:3:10 | exit M1 | NullCoalescing.cs:3:9:3:10 | M1 |
| NullCoalescing.cs:3:28:3:28 | 0 | NullCoalescing.cs:3:9:3:10 | M1 |

View File

@@ -1544,6 +1544,89 @@
| LoopUnrolling.cs:73:13:73:34 | call to method WriteLine | LoopUnrolling.cs:73:31:73:33 | access to local variable arg |
| LoopUnrolling.cs:73:13:73:35 | ...; | LoopUnrolling.cs:73:13:73:35 | ...; |
| LoopUnrolling.cs:73:31:73:33 | access to local variable arg | LoopUnrolling.cs:73:31:73:33 | access to local variable arg |
| MultiImplementationA.cs:6:22:6:31 | throw ... | MultiImplementationA.cs:6:28:6:31 | null |
| MultiImplementationA.cs:6:28:6:31 | null | MultiImplementationA.cs:6:28:6:31 | null |
| MultiImplementationA.cs:7:25:7:39 | {...} | MultiImplementationA.cs:7:25:7:39 | {...} |
| MultiImplementationA.cs:7:27:7:37 | throw ...; | MultiImplementationA.cs:7:33:7:36 | null |
| MultiImplementationA.cs:7:33:7:36 | null | MultiImplementationA.cs:7:33:7:36 | null |
| MultiImplementationA.cs:7:45:7:59 | {...} | MultiImplementationA.cs:7:45:7:59 | {...} |
| MultiImplementationA.cs:7:47:7:57 | throw ...; | MultiImplementationA.cs:7:53:7:56 | null |
| MultiImplementationA.cs:7:53:7:56 | null | MultiImplementationA.cs:7:53:7:56 | null |
| MultiImplementationA.cs:8:23:8:32 | throw ... | MultiImplementationA.cs:8:29:8:32 | null |
| MultiImplementationA.cs:8:29:8:32 | null | MultiImplementationA.cs:8:29:8:32 | null |
| MultiImplementationA.cs:13:16:13:16 | access to field F | MultiImplementationA.cs:13:16:13:16 | this access |
| MultiImplementationA.cs:13:16:13:16 | this access | MultiImplementationA.cs:13:16:13:16 | this access |
| MultiImplementationA.cs:13:16:13:20 | ... = ... | MultiImplementationA.cs:13:16:13:16 | this access |
| MultiImplementationA.cs:13:20:13:20 | 0 | MultiImplementationA.cs:13:20:13:20 | 0 |
| MultiImplementationA.cs:14:31:14:31 | access to parameter i | MultiImplementationA.cs:14:31:14:31 | access to parameter i |
| MultiImplementationA.cs:15:40:15:52 | {...} | MultiImplementationA.cs:15:40:15:52 | {...} |
| MultiImplementationA.cs:15:42:15:50 | return ...; | MultiImplementationA.cs:15:49:15:49 | access to parameter s |
| MultiImplementationA.cs:15:49:15:49 | access to parameter s | MultiImplementationA.cs:15:49:15:49 | access to parameter s |
| MultiImplementationA.cs:15:58:15:60 | {...} | MultiImplementationA.cs:15:58:15:60 | {...} |
| MultiImplementationA.cs:16:28:16:28 | 0 | MultiImplementationA.cs:16:28:16:28 | 0 |
| MultiImplementationA.cs:17:5:19:5 | {...} | MultiImplementationA.cs:17:5:19:5 | {...} |
| MultiImplementationA.cs:18:9:18:22 | M2(...) | MultiImplementationA.cs:18:9:18:22 | M2(...) |
| MultiImplementationA.cs:18:21:18:21 | 0 | MultiImplementationA.cs:18:21:18:21 | 0 |
| MultiImplementationA.cs:20:22:20:31 | {...} | MultiImplementationA.cs:20:22:20:31 | {...} |
| MultiImplementationA.cs:20:24:20:24 | access to field F | MultiImplementationA.cs:20:24:20:24 | this access |
| MultiImplementationA.cs:20:24:20:24 | this access | MultiImplementationA.cs:20:24:20:24 | this access |
| MultiImplementationA.cs:20:24:20:28 | ... = ... | MultiImplementationA.cs:20:24:20:24 | this access |
| MultiImplementationA.cs:20:24:20:29 | ...; | MultiImplementationA.cs:20:24:20:29 | ...; |
| MultiImplementationA.cs:20:28:20:28 | access to parameter i | MultiImplementationA.cs:20:28:20:28 | access to parameter i |
| MultiImplementationA.cs:21:19:21:22 | call to constructor C2 | MultiImplementationA.cs:21:24:21:24 | 0 |
| MultiImplementationA.cs:21:24:21:24 | 0 | MultiImplementationA.cs:21:24:21:24 | 0 |
| MultiImplementationA.cs:21:27:21:29 | {...} | MultiImplementationA.cs:21:27:21:29 | {...} |
| MultiImplementationA.cs:22:11:22:13 | {...} | MultiImplementationA.cs:22:11:22:13 | {...} |
| MultiImplementationA.cs:23:50:23:53 | null | MultiImplementationA.cs:23:50:23:53 | null |
| MultiImplementationA.cs:24:16:24:16 | access to property P | MultiImplementationA.cs:24:16:24:16 | this access |
| MultiImplementationA.cs:24:16:24:16 | this access | MultiImplementationA.cs:24:16:24:16 | this access |
| MultiImplementationA.cs:24:32:24:34 | ... = ... | MultiImplementationA.cs:24:16:24:16 | this access |
| MultiImplementationA.cs:24:34:24:34 | 0 | MultiImplementationA.cs:24:34:24:34 | 0 |
| MultiImplementationA.cs:30:28:30:37 | throw ... | MultiImplementationA.cs:30:34:30:37 | null |
| MultiImplementationA.cs:30:34:30:37 | null | MultiImplementationA.cs:30:34:30:37 | null |
| MultiImplementationA.cs:36:14:36:28 | {...} | MultiImplementationA.cs:36:14:36:28 | {...} |
| MultiImplementationA.cs:36:16:36:26 | throw ...; | MultiImplementationA.cs:36:22:36:25 | null |
| MultiImplementationA.cs:36:22:36:25 | null | MultiImplementationA.cs:36:22:36:25 | null |
| MultiImplementationA.cs:37:14:37:28 | {...} | MultiImplementationA.cs:37:14:37:28 | {...} |
| MultiImplementationA.cs:37:16:37:26 | throw ...; | MultiImplementationA.cs:37:22:37:25 | null |
| MultiImplementationA.cs:37:22:37:25 | null | MultiImplementationA.cs:37:22:37:25 | null |
| MultiImplementationB.cs:3:22:3:22 | 0 | MultiImplementationB.cs:3:22:3:22 | 0 |
| MultiImplementationB.cs:4:25:4:37 | {...} | MultiImplementationB.cs:4:25:4:37 | {...} |
| MultiImplementationB.cs:4:27:4:35 | return ...; | MultiImplementationB.cs:4:34:4:34 | 1 |
| MultiImplementationB.cs:4:34:4:34 | 1 | MultiImplementationB.cs:4:34:4:34 | 1 |
| MultiImplementationB.cs:4:43:4:45 | {...} | MultiImplementationB.cs:4:43:4:45 | {...} |
| MultiImplementationB.cs:5:23:5:23 | 2 | MultiImplementationB.cs:5:23:5:23 | 2 |
| MultiImplementationB.cs:11:16:11:16 | access to field F | MultiImplementationB.cs:11:16:11:16 | this access |
| MultiImplementationB.cs:11:16:11:16 | this access | MultiImplementationB.cs:11:16:11:16 | this access |
| MultiImplementationB.cs:11:16:11:20 | ... = ... | MultiImplementationB.cs:11:16:11:16 | this access |
| MultiImplementationB.cs:11:20:11:20 | 1 | MultiImplementationB.cs:11:20:11:20 | 1 |
| MultiImplementationB.cs:12:31:12:40 | throw ... | MultiImplementationB.cs:12:37:12:40 | null |
| MultiImplementationB.cs:12:37:12:40 | null | MultiImplementationB.cs:12:37:12:40 | null |
| MultiImplementationB.cs:13:40:13:54 | {...} | MultiImplementationB.cs:13:40:13:54 | {...} |
| MultiImplementationB.cs:13:42:13:52 | throw ...; | MultiImplementationB.cs:13:48:13:51 | null |
| MultiImplementationB.cs:13:48:13:51 | null | MultiImplementationB.cs:13:48:13:51 | null |
| MultiImplementationB.cs:13:60:13:62 | {...} | MultiImplementationB.cs:13:60:13:62 | {...} |
| MultiImplementationB.cs:14:28:14:28 | 1 | MultiImplementationB.cs:14:28:14:28 | 1 |
| MultiImplementationB.cs:15:5:17:5 | {...} | MultiImplementationB.cs:15:5:17:5 | {...} |
| MultiImplementationB.cs:16:9:16:31 | M2(...) | MultiImplementationB.cs:16:9:16:31 | M2(...) |
| MultiImplementationB.cs:16:21:16:30 | throw ... | MultiImplementationB.cs:16:27:16:30 | null |
| MultiImplementationB.cs:16:27:16:30 | null | MultiImplementationB.cs:16:27:16:30 | null |
| MultiImplementationB.cs:18:22:18:36 | {...} | MultiImplementationB.cs:18:22:18:36 | {...} |
| MultiImplementationB.cs:18:24:18:34 | throw ...; | MultiImplementationB.cs:18:30:18:33 | null |
| MultiImplementationB.cs:18:30:18:33 | null | MultiImplementationB.cs:18:30:18:33 | null |
| MultiImplementationB.cs:19:19:19:22 | call to constructor C2 | MultiImplementationB.cs:19:24:19:24 | 1 |
| MultiImplementationB.cs:19:24:19:24 | 1 | MultiImplementationB.cs:19:24:19:24 | 1 |
| MultiImplementationB.cs:19:27:19:29 | {...} | MultiImplementationB.cs:19:27:19:29 | {...} |
| MultiImplementationB.cs:20:11:20:25 | {...} | MultiImplementationB.cs:20:11:20:25 | {...} |
| MultiImplementationB.cs:20:13:20:23 | throw ...; | MultiImplementationB.cs:20:19:20:22 | null |
| MultiImplementationB.cs:20:19:20:22 | null | MultiImplementationB.cs:20:19:20:22 | null |
| MultiImplementationB.cs:21:50:21:59 | throw ... | MultiImplementationB.cs:21:56:21:59 | null |
| MultiImplementationB.cs:21:56:21:59 | null | MultiImplementationB.cs:21:56:21:59 | null |
| MultiImplementationB.cs:22:16:22:16 | access to property P | MultiImplementationB.cs:22:16:22:16 | this access |
| MultiImplementationB.cs:22:16:22:16 | this access | MultiImplementationB.cs:22:16:22:16 | this access |
| MultiImplementationB.cs:22:32:22:34 | ... = ... | MultiImplementationB.cs:22:16:22:16 | this access |
| MultiImplementationB.cs:22:34:22:34 | 1 | MultiImplementationB.cs:22:34:22:34 | 1 |
| MultiImplementationB.cs:32:17:32:17 | 0 | MultiImplementationB.cs:32:17:32:17 | 0 |
| NullCoalescing.cs:3:23:3:23 | access to parameter i | NullCoalescing.cs:3:23:3:23 | access to parameter i |
| NullCoalescing.cs:3:23:3:28 | ... ?? ... | NullCoalescing.cs:3:23:3:28 | ... ?? ... |
| NullCoalescing.cs:3:28:3:28 | 0 | NullCoalescing.cs:3:28:3:28 | 0 |

View File

@@ -2056,6 +2056,89 @@
| LoopUnrolling.cs:73:13:73:34 | call to method WriteLine | LoopUnrolling.cs:73:13:73:34 | call to method WriteLine | normal |
| LoopUnrolling.cs:73:13:73:35 | ...; | LoopUnrolling.cs:73:13:73:34 | call to method WriteLine | normal |
| LoopUnrolling.cs:73:31:73:33 | access to local variable arg | LoopUnrolling.cs:73:31:73:33 | access to local variable arg | normal |
| MultiImplementationA.cs:6:22:6:31 | throw ... | MultiImplementationA.cs:6:22:6:31 | throw ... | throw(NullReferenceException) |
| MultiImplementationA.cs:6:28:6:31 | null | MultiImplementationA.cs:6:28:6:31 | null | normal |
| MultiImplementationA.cs:7:25:7:39 | {...} | MultiImplementationA.cs:7:27:7:37 | throw ...; | throw(NullReferenceException) |
| MultiImplementationA.cs:7:27:7:37 | throw ...; | MultiImplementationA.cs:7:27:7:37 | throw ...; | throw(NullReferenceException) |
| MultiImplementationA.cs:7:33:7:36 | null | MultiImplementationA.cs:7:33:7:36 | null | normal |
| MultiImplementationA.cs:7:45:7:59 | {...} | MultiImplementationA.cs:7:47:7:57 | throw ...; | throw(NullReferenceException) |
| MultiImplementationA.cs:7:47:7:57 | throw ...; | MultiImplementationA.cs:7:47:7:57 | throw ...; | throw(NullReferenceException) |
| MultiImplementationA.cs:7:53:7:56 | null | MultiImplementationA.cs:7:53:7:56 | null | normal |
| MultiImplementationA.cs:8:23:8:32 | throw ... | MultiImplementationA.cs:8:23:8:32 | throw ... | throw(NullReferenceException) |
| MultiImplementationA.cs:8:29:8:32 | null | MultiImplementationA.cs:8:29:8:32 | null | normal |
| MultiImplementationA.cs:13:16:13:16 | access to field F | MultiImplementationA.cs:13:16:13:16 | this access | normal |
| MultiImplementationA.cs:13:16:13:16 | this access | MultiImplementationA.cs:13:16:13:16 | this access | normal |
| MultiImplementationA.cs:13:16:13:20 | ... = ... | MultiImplementationA.cs:13:16:13:20 | ... = ... | normal |
| MultiImplementationA.cs:13:20:13:20 | 0 | MultiImplementationA.cs:13:20:13:20 | 0 | normal |
| MultiImplementationA.cs:14:31:14:31 | access to parameter i | MultiImplementationA.cs:14:31:14:31 | access to parameter i | normal |
| MultiImplementationA.cs:15:40:15:52 | {...} | MultiImplementationA.cs:15:42:15:50 | return ...; | return |
| MultiImplementationA.cs:15:42:15:50 | return ...; | MultiImplementationA.cs:15:42:15:50 | return ...; | return |
| MultiImplementationA.cs:15:49:15:49 | access to parameter s | MultiImplementationA.cs:15:49:15:49 | access to parameter s | normal |
| MultiImplementationA.cs:15:58:15:60 | {...} | MultiImplementationA.cs:15:58:15:60 | {...} | normal |
| MultiImplementationA.cs:16:28:16:28 | 0 | MultiImplementationA.cs:16:28:16:28 | 0 | normal |
| MultiImplementationA.cs:17:5:19:5 | {...} | MultiImplementationA.cs:18:9:18:22 | M2(...) | normal |
| MultiImplementationA.cs:18:9:18:22 | M2(...) | MultiImplementationA.cs:18:9:18:22 | M2(...) | normal |
| MultiImplementationA.cs:18:21:18:21 | 0 | MultiImplementationA.cs:18:21:18:21 | 0 | normal |
| MultiImplementationA.cs:20:22:20:31 | {...} | MultiImplementationA.cs:20:24:20:28 | ... = ... | normal |
| MultiImplementationA.cs:20:24:20:24 | access to field F | MultiImplementationA.cs:20:24:20:24 | this access | normal |
| MultiImplementationA.cs:20:24:20:24 | this access | MultiImplementationA.cs:20:24:20:24 | this access | normal |
| MultiImplementationA.cs:20:24:20:28 | ... = ... | MultiImplementationA.cs:20:24:20:28 | ... = ... | normal |
| MultiImplementationA.cs:20:24:20:29 | ...; | MultiImplementationA.cs:20:24:20:28 | ... = ... | normal |
| MultiImplementationA.cs:20:28:20:28 | access to parameter i | MultiImplementationA.cs:20:28:20:28 | access to parameter i | normal |
| MultiImplementationA.cs:21:19:21:22 | call to constructor C2 | MultiImplementationA.cs:21:19:21:22 | call to constructor C2 | normal |
| MultiImplementationA.cs:21:24:21:24 | 0 | MultiImplementationA.cs:21:24:21:24 | 0 | normal |
| MultiImplementationA.cs:21:27:21:29 | {...} | MultiImplementationA.cs:21:27:21:29 | {...} | normal |
| MultiImplementationA.cs:22:11:22:13 | {...} | MultiImplementationA.cs:22:11:22:13 | {...} | normal |
| MultiImplementationA.cs:23:50:23:53 | null | MultiImplementationA.cs:23:50:23:53 | null | normal |
| MultiImplementationA.cs:24:16:24:16 | access to property P | MultiImplementationA.cs:24:16:24:16 | this access | normal |
| MultiImplementationA.cs:24:16:24:16 | this access | MultiImplementationA.cs:24:16:24:16 | this access | normal |
| MultiImplementationA.cs:24:32:24:34 | ... = ... | MultiImplementationA.cs:24:32:24:34 | ... = ... | normal |
| MultiImplementationA.cs:24:34:24:34 | 0 | MultiImplementationA.cs:24:34:24:34 | 0 | normal |
| MultiImplementationA.cs:30:28:30:37 | throw ... | MultiImplementationA.cs:30:28:30:37 | throw ... | throw(NullReferenceException) |
| MultiImplementationA.cs:30:34:30:37 | null | MultiImplementationA.cs:30:34:30:37 | null | normal |
| MultiImplementationA.cs:36:14:36:28 | {...} | MultiImplementationA.cs:36:16:36:26 | throw ...; | throw(NullReferenceException) |
| MultiImplementationA.cs:36:16:36:26 | throw ...; | MultiImplementationA.cs:36:16:36:26 | throw ...; | throw(NullReferenceException) |
| MultiImplementationA.cs:36:22:36:25 | null | MultiImplementationA.cs:36:22:36:25 | null | normal |
| MultiImplementationA.cs:37:14:37:28 | {...} | MultiImplementationA.cs:37:16:37:26 | throw ...; | throw(NullReferenceException) |
| MultiImplementationA.cs:37:16:37:26 | throw ...; | MultiImplementationA.cs:37:16:37:26 | throw ...; | throw(NullReferenceException) |
| MultiImplementationA.cs:37:22:37:25 | null | MultiImplementationA.cs:37:22:37:25 | null | normal |
| MultiImplementationB.cs:3:22:3:22 | 0 | MultiImplementationB.cs:3:22:3:22 | 0 | normal |
| MultiImplementationB.cs:4:25:4:37 | {...} | MultiImplementationB.cs:4:27:4:35 | return ...; | return |
| MultiImplementationB.cs:4:27:4:35 | return ...; | MultiImplementationB.cs:4:27:4:35 | return ...; | return |
| MultiImplementationB.cs:4:34:4:34 | 1 | MultiImplementationB.cs:4:34:4:34 | 1 | normal |
| MultiImplementationB.cs:4:43:4:45 | {...} | MultiImplementationB.cs:4:43:4:45 | {...} | normal |
| MultiImplementationB.cs:5:23:5:23 | 2 | MultiImplementationB.cs:5:23:5:23 | 2 | normal |
| MultiImplementationB.cs:11:16:11:16 | access to field F | MultiImplementationB.cs:11:16:11:16 | this access | normal |
| MultiImplementationB.cs:11:16:11:16 | this access | MultiImplementationB.cs:11:16:11:16 | this access | normal |
| MultiImplementationB.cs:11:16:11:20 | ... = ... | MultiImplementationB.cs:11:16:11:20 | ... = ... | normal |
| MultiImplementationB.cs:11:20:11:20 | 1 | MultiImplementationB.cs:11:20:11:20 | 1 | normal |
| MultiImplementationB.cs:12:31:12:40 | throw ... | MultiImplementationB.cs:12:31:12:40 | throw ... | throw(NullReferenceException) |
| MultiImplementationB.cs:12:37:12:40 | null | MultiImplementationB.cs:12:37:12:40 | null | normal |
| MultiImplementationB.cs:13:40:13:54 | {...} | MultiImplementationB.cs:13:42:13:52 | throw ...; | throw(NullReferenceException) |
| MultiImplementationB.cs:13:42:13:52 | throw ...; | MultiImplementationB.cs:13:42:13:52 | throw ...; | throw(NullReferenceException) |
| MultiImplementationB.cs:13:48:13:51 | null | MultiImplementationB.cs:13:48:13:51 | null | normal |
| MultiImplementationB.cs:13:60:13:62 | {...} | MultiImplementationB.cs:13:60:13:62 | {...} | normal |
| MultiImplementationB.cs:14:28:14:28 | 1 | MultiImplementationB.cs:14:28:14:28 | 1 | normal |
| MultiImplementationB.cs:15:5:17:5 | {...} | MultiImplementationB.cs:16:9:16:31 | M2(...) | normal |
| MultiImplementationB.cs:16:9:16:31 | M2(...) | MultiImplementationB.cs:16:9:16:31 | M2(...) | normal |
| MultiImplementationB.cs:16:21:16:30 | throw ... | MultiImplementationB.cs:16:21:16:30 | throw ... | throw(NullReferenceException) |
| MultiImplementationB.cs:16:27:16:30 | null | MultiImplementationB.cs:16:27:16:30 | null | normal |
| MultiImplementationB.cs:18:22:18:36 | {...} | MultiImplementationB.cs:18:24:18:34 | throw ...; | throw(NullReferenceException) |
| MultiImplementationB.cs:18:24:18:34 | throw ...; | MultiImplementationB.cs:18:24:18:34 | throw ...; | throw(NullReferenceException) |
| MultiImplementationB.cs:18:30:18:33 | null | MultiImplementationB.cs:18:30:18:33 | null | normal |
| MultiImplementationB.cs:19:19:19:22 | call to constructor C2 | MultiImplementationB.cs:19:19:19:22 | call to constructor C2 | normal |
| MultiImplementationB.cs:19:24:19:24 | 1 | MultiImplementationB.cs:19:24:19:24 | 1 | normal |
| MultiImplementationB.cs:19:27:19:29 | {...} | MultiImplementationB.cs:19:27:19:29 | {...} | normal |
| MultiImplementationB.cs:20:11:20:25 | {...} | MultiImplementationB.cs:20:13:20:23 | throw ...; | throw(NullReferenceException) |
| MultiImplementationB.cs:20:13:20:23 | throw ...; | MultiImplementationB.cs:20:13:20:23 | throw ...; | throw(NullReferenceException) |
| MultiImplementationB.cs:20:19:20:22 | null | MultiImplementationB.cs:20:19:20:22 | null | normal |
| MultiImplementationB.cs:21:50:21:59 | throw ... | MultiImplementationB.cs:21:50:21:59 | throw ... | throw(NullReferenceException) |
| MultiImplementationB.cs:21:56:21:59 | null | MultiImplementationB.cs:21:56:21:59 | null | normal |
| MultiImplementationB.cs:22:16:22:16 | access to property P | MultiImplementationB.cs:22:16:22:16 | this access | normal |
| MultiImplementationB.cs:22:16:22:16 | this access | MultiImplementationB.cs:22:16:22:16 | this access | normal |
| MultiImplementationB.cs:22:32:22:34 | ... = ... | MultiImplementationB.cs:22:32:22:34 | ... = ... | normal |
| MultiImplementationB.cs:22:34:22:34 | 1 | MultiImplementationB.cs:22:34:22:34 | 1 | normal |
| MultiImplementationB.cs:32:17:32:17 | 0 | MultiImplementationB.cs:32:17:32:17 | 0 | normal |
| NullCoalescing.cs:3:23:3:23 | access to parameter i | NullCoalescing.cs:3:23:3:23 | access to parameter i | non-null |
| NullCoalescing.cs:3:23:3:23 | access to parameter i | NullCoalescing.cs:3:23:3:23 | access to parameter i | null |
| NullCoalescing.cs:3:23:3:28 | ... ?? ... | NullCoalescing.cs:3:23:3:23 | access to parameter i | non-null |

View File

@@ -0,0 +1,38 @@
// semmle-extractor-options: --separate-compilation
// Stub implementation
class C1
{
public int P1 => throw null;
public int P2 { get { throw null; } set { throw null; } }
public int M() => throw null;
}
class C2
{
public int F = 0;
public int this[int i] => i;
public string this[string s] { get { return s; } set { } }
public void M1(int i = 0)
{
int M2() => 0;
}
public C2(int i) { F = i; }
public C2() : this(0) { }
~C2() { }
public static implicit operator C2(int i) => null;
public int P { get; set; } = 0;
}
// Stub implementation
class C3
{
public int P3 { get => throw null; }
}
// Stub implementation
partial class C4
{
int M1() { throw null; }
int M2() { throw null; }
}

View File

@@ -0,0 +1,33 @@
class C1
{
public int P1 => 0;
public int P2 { get { return 1; } set { } }
public int M() => 2;
}
// Stub implementation
class C2
{
public int F = 1;
public int this[int i] => throw null;
public string this[string s] { get { throw null; } set { } }
public void M1(int i = 1)
{
int M2() => throw null;
}
public C2(int i) { throw null; }
public C2() : this(1) { }
~C2() { throw null; }
public static implicit operator C2(int i) => throw null;
public int P { get; set; } = 1;
}
class C3
{
public int P3 { get; }
}
partial class C4
{
int M1() => 0;
}

View File

@@ -2265,6 +2265,182 @@
| LoopUnrolling.cs:73:13:73:34 | call to method WriteLine | LoopUnrolling.cs:72:9:73:35 | foreach (... ... in ...) ... | semmle.label | successor |
| LoopUnrolling.cs:73:13:73:35 | ...; | LoopUnrolling.cs:73:31:73:33 | access to local variable arg | semmle.label | successor |
| LoopUnrolling.cs:73:31:73:33 | access to local variable arg | LoopUnrolling.cs:73:13:73:34 | call to method WriteLine | semmle.label | successor |
| MultiImplementationA.cs:6:22:6:31 | enter get_P1 | MultiImplementationA.cs:6:28:6:31 | null | semmle.label | successor |
| MultiImplementationA.cs:6:22:6:31 | enter get_P1 | MultiImplementationB.cs:3:22:3:22 | 0 | semmle.label | successor |
| MultiImplementationA.cs:6:22:6:31 | throw ... | MultiImplementationA.cs:6:22:6:31 | exit get_P1 | semmle.label | exception(NullReferenceException) |
| MultiImplementationA.cs:6:22:6:31 | throw ... | MultiImplementationB.cs:3:22:3:22 | exit get_P1 | semmle.label | exception(NullReferenceException) |
| MultiImplementationA.cs:6:28:6:31 | null | MultiImplementationA.cs:6:22:6:31 | throw ... | semmle.label | successor |
| MultiImplementationA.cs:7:21:7:23 | enter get_P2 | MultiImplementationA.cs:7:25:7:39 | {...} | semmle.label | successor |
| MultiImplementationA.cs:7:21:7:23 | enter get_P2 | MultiImplementationB.cs:4:25:4:37 | {...} | semmle.label | successor |
| MultiImplementationA.cs:7:25:7:39 | {...} | MultiImplementationA.cs:7:33:7:36 | null | semmle.label | successor |
| MultiImplementationA.cs:7:27:7:37 | throw ...; | MultiImplementationA.cs:7:21:7:23 | exit get_P2 | semmle.label | exception(NullReferenceException) |
| MultiImplementationA.cs:7:27:7:37 | throw ...; | MultiImplementationB.cs:4:21:4:23 | exit get_P2 | semmle.label | exception(NullReferenceException) |
| MultiImplementationA.cs:7:33:7:36 | null | MultiImplementationA.cs:7:27:7:37 | throw ...; | semmle.label | successor |
| MultiImplementationA.cs:7:41:7:43 | enter set_P2 | MultiImplementationA.cs:7:45:7:59 | {...} | semmle.label | successor |
| MultiImplementationA.cs:7:41:7:43 | enter set_P2 | MultiImplementationB.cs:4:43:4:45 | {...} | semmle.label | successor |
| MultiImplementationA.cs:7:45:7:59 | {...} | MultiImplementationA.cs:7:53:7:56 | null | semmle.label | successor |
| MultiImplementationA.cs:7:47:7:57 | throw ...; | MultiImplementationA.cs:7:41:7:43 | exit set_P2 | semmle.label | exception(NullReferenceException) |
| MultiImplementationA.cs:7:47:7:57 | throw ...; | MultiImplementationB.cs:4:39:4:41 | exit set_P2 | semmle.label | exception(NullReferenceException) |
| MultiImplementationA.cs:7:53:7:56 | null | MultiImplementationA.cs:7:47:7:57 | throw ...; | semmle.label | successor |
| MultiImplementationA.cs:8:16:8:16 | enter M | MultiImplementationA.cs:8:29:8:32 | null | semmle.label | successor |
| MultiImplementationA.cs:8:16:8:16 | enter M | MultiImplementationB.cs:5:23:5:23 | 2 | semmle.label | successor |
| MultiImplementationA.cs:8:23:8:32 | throw ... | MultiImplementationA.cs:8:16:8:16 | exit M | semmle.label | exception(NullReferenceException) |
| MultiImplementationA.cs:8:23:8:32 | throw ... | MultiImplementationB.cs:5:16:5:16 | exit M | semmle.label | exception(NullReferenceException) |
| MultiImplementationA.cs:8:29:8:32 | null | MultiImplementationA.cs:8:23:8:32 | throw ... | semmle.label | successor |
| MultiImplementationA.cs:13:16:13:16 | this access | MultiImplementationA.cs:13:20:13:20 | 0 | semmle.label | successor |
| MultiImplementationA.cs:13:16:13:20 | ... = ... | MultiImplementationA.cs:13:16:13:16 | this access | semmle.label | successor |
| MultiImplementationA.cs:13:16:13:20 | ... = ... | MultiImplementationA.cs:24:16:24:16 | this access | semmle.label | successor |
| MultiImplementationA.cs:13:16:13:20 | ... = ... | MultiImplementationB.cs:11:16:11:16 | this access | semmle.label | successor |
| MultiImplementationA.cs:13:16:13:20 | ... = ... | MultiImplementationB.cs:22:16:22:16 | this access | semmle.label | successor |
| MultiImplementationA.cs:13:20:13:20 | 0 | MultiImplementationA.cs:13:16:13:20 | ... = ... | semmle.label | successor |
| MultiImplementationA.cs:14:31:14:31 | access to parameter i | MultiImplementationA.cs:14:31:14:31 | exit get_Item | semmle.label | successor |
| MultiImplementationA.cs:14:31:14:31 | access to parameter i | MultiImplementationB.cs:12:31:12:40 | exit get_Item | semmle.label | successor |
| MultiImplementationA.cs:14:31:14:31 | enter get_Item | MultiImplementationA.cs:14:31:14:31 | access to parameter i | semmle.label | successor |
| MultiImplementationA.cs:14:31:14:31 | enter get_Item | MultiImplementationB.cs:12:37:12:40 | null | semmle.label | successor |
| MultiImplementationA.cs:15:36:15:38 | enter get_Item | MultiImplementationA.cs:15:40:15:52 | {...} | semmle.label | successor |
| MultiImplementationA.cs:15:36:15:38 | enter get_Item | MultiImplementationB.cs:13:40:13:54 | {...} | semmle.label | successor |
| MultiImplementationA.cs:15:40:15:52 | {...} | MultiImplementationA.cs:15:49:15:49 | access to parameter s | semmle.label | successor |
| MultiImplementationA.cs:15:42:15:50 | return ...; | MultiImplementationA.cs:15:36:15:38 | exit get_Item | semmle.label | return |
| MultiImplementationA.cs:15:42:15:50 | return ...; | MultiImplementationB.cs:13:36:13:38 | exit get_Item | semmle.label | return |
| MultiImplementationA.cs:15:49:15:49 | access to parameter s | MultiImplementationA.cs:15:42:15:50 | return ...; | semmle.label | successor |
| MultiImplementationA.cs:15:54:15:56 | enter set_Item | MultiImplementationA.cs:15:58:15:60 | {...} | semmle.label | successor |
| MultiImplementationA.cs:15:54:15:56 | enter set_Item | MultiImplementationB.cs:13:60:13:62 | {...} | semmle.label | successor |
| MultiImplementationA.cs:15:58:15:60 | {...} | MultiImplementationA.cs:15:54:15:56 | exit set_Item | semmle.label | successor |
| MultiImplementationA.cs:15:58:15:60 | {...} | MultiImplementationB.cs:13:56:13:58 | exit set_Item | semmle.label | successor |
| MultiImplementationA.cs:16:17:16:18 | enter M1 | MultiImplementationA.cs:17:5:19:5 | {...} | semmle.label | successor |
| MultiImplementationA.cs:16:17:16:18 | enter M1 | MultiImplementationB.cs:15:5:17:5 | {...} | semmle.label | successor |
| MultiImplementationA.cs:17:5:19:5 | {...} | MultiImplementationA.cs:18:9:18:22 | M2(...) | semmle.label | successor |
| MultiImplementationA.cs:18:9:18:22 | M2(...) | MultiImplementationA.cs:16:17:16:18 | exit M1 | semmle.label | successor |
| MultiImplementationA.cs:18:9:18:22 | M2(...) | MultiImplementationB.cs:14:17:14:18 | exit M1 | semmle.label | successor |
| MultiImplementationA.cs:18:9:18:22 | enter M2 | MultiImplementationA.cs:18:21:18:21 | 0 | semmle.label | successor |
| MultiImplementationA.cs:18:21:18:21 | 0 | MultiImplementationA.cs:18:9:18:22 | exit M2 | semmle.label | successor |
| MultiImplementationA.cs:20:12:20:13 | enter C2 | MultiImplementationA.cs:13:16:13:16 | this access | semmle.label | successor |
| MultiImplementationA.cs:20:12:20:13 | enter C2 | MultiImplementationB.cs:11:16:11:16 | this access | semmle.label | successor |
| MultiImplementationA.cs:20:22:20:31 | {...} | MultiImplementationA.cs:20:24:20:29 | ...; | semmle.label | successor |
| MultiImplementationA.cs:20:24:20:24 | this access | MultiImplementationA.cs:20:28:20:28 | access to parameter i | semmle.label | successor |
| MultiImplementationA.cs:20:24:20:28 | ... = ... | MultiImplementationA.cs:20:12:20:13 | exit C2 | semmle.label | successor |
| MultiImplementationA.cs:20:24:20:28 | ... = ... | MultiImplementationB.cs:18:12:18:13 | exit C2 | semmle.label | successor |
| MultiImplementationA.cs:20:24:20:29 | ...; | MultiImplementationA.cs:20:24:20:24 | this access | semmle.label | successor |
| MultiImplementationA.cs:20:28:20:28 | access to parameter i | MultiImplementationA.cs:20:24:20:28 | ... = ... | semmle.label | successor |
| MultiImplementationA.cs:21:12:21:13 | enter C2 | MultiImplementationA.cs:21:24:21:24 | 0 | semmle.label | successor |
| MultiImplementationA.cs:21:12:21:13 | enter C2 | MultiImplementationB.cs:19:24:19:24 | 1 | semmle.label | successor |
| MultiImplementationA.cs:21:19:21:22 | call to constructor C2 | MultiImplementationA.cs:21:27:21:29 | {...} | semmle.label | successor |
| MultiImplementationA.cs:21:19:21:22 | call to constructor C2 | MultiImplementationB.cs:19:27:19:29 | {...} | semmle.label | successor |
| MultiImplementationA.cs:21:24:21:24 | 0 | MultiImplementationA.cs:21:19:21:22 | call to constructor C2 | semmle.label | successor |
| MultiImplementationA.cs:21:27:21:29 | {...} | MultiImplementationA.cs:21:12:21:13 | exit C2 | semmle.label | successor |
| MultiImplementationA.cs:21:27:21:29 | {...} | MultiImplementationB.cs:19:12:19:13 | exit C2 | semmle.label | successor |
| MultiImplementationA.cs:22:6:22:7 | enter ~C2 | MultiImplementationA.cs:22:11:22:13 | {...} | semmle.label | successor |
| MultiImplementationA.cs:22:6:22:7 | enter ~C2 | MultiImplementationB.cs:20:11:20:25 | {...} | semmle.label | successor |
| MultiImplementationA.cs:22:11:22:13 | {...} | MultiImplementationA.cs:22:6:22:7 | exit ~C2 | semmle.label | successor |
| MultiImplementationA.cs:22:11:22:13 | {...} | MultiImplementationB.cs:20:6:20:7 | exit ~C2 | semmle.label | successor |
| MultiImplementationA.cs:23:28:23:35 | enter implicit conversion | MultiImplementationA.cs:23:50:23:53 | null | semmle.label | successor |
| MultiImplementationA.cs:23:28:23:35 | enter implicit conversion | MultiImplementationB.cs:21:56:21:59 | null | semmle.label | successor |
| MultiImplementationA.cs:23:50:23:53 | null | MultiImplementationA.cs:23:28:23:35 | exit implicit conversion | semmle.label | successor |
| MultiImplementationA.cs:23:50:23:53 | null | MultiImplementationB.cs:21:28:21:35 | exit implicit conversion | semmle.label | successor |
| MultiImplementationA.cs:24:16:24:16 | access to property P | MultiImplementationA.cs:24:32:24:34 | ... = ... | semmle.label | successor |
| MultiImplementationA.cs:24:16:24:16 | this access | MultiImplementationA.cs:24:34:24:34 | 0 | semmle.label | successor |
| MultiImplementationA.cs:24:32:24:34 | ... = ... | MultiImplementationA.cs:20:22:20:31 | {...} | semmle.label | successor |
| MultiImplementationA.cs:24:32:24:34 | ... = ... | MultiImplementationA.cs:24:16:24:16 | this access | semmle.label | successor |
| MultiImplementationA.cs:24:32:24:34 | ... = ... | MultiImplementationB.cs:18:22:18:36 | {...} | semmle.label | successor |
| MultiImplementationA.cs:24:32:24:34 | ... = ... | MultiImplementationB.cs:22:16:22:16 | this access | semmle.label | successor |
| MultiImplementationA.cs:24:34:24:34 | 0 | MultiImplementationA.cs:24:16:24:16 | access to property P | semmle.label | successor |
| MultiImplementationA.cs:30:21:30:23 | enter get_P3 | MultiImplementationA.cs:30:34:30:37 | null | semmle.label | successor |
| MultiImplementationA.cs:30:28:30:37 | throw ... | MultiImplementationA.cs:30:21:30:23 | exit get_P3 | semmle.label | exception(NullReferenceException) |
| MultiImplementationA.cs:30:28:30:37 | throw ... | MultiImplementationB.cs:27:21:27:23 | exit get_P3 | semmle.label | exception(NullReferenceException) |
| MultiImplementationA.cs:30:34:30:37 | null | MultiImplementationA.cs:30:28:30:37 | throw ... | semmle.label | successor |
| MultiImplementationA.cs:36:9:36:10 | enter M1 | MultiImplementationA.cs:36:14:36:28 | {...} | semmle.label | successor |
| MultiImplementationA.cs:36:9:36:10 | enter M1 | MultiImplementationB.cs:32:17:32:17 | 0 | semmle.label | successor |
| MultiImplementationA.cs:36:14:36:28 | {...} | MultiImplementationA.cs:36:22:36:25 | null | semmle.label | successor |
| MultiImplementationA.cs:36:16:36:26 | throw ...; | MultiImplementationA.cs:36:9:36:10 | exit M1 | semmle.label | exception(NullReferenceException) |
| MultiImplementationA.cs:36:16:36:26 | throw ...; | MultiImplementationB.cs:32:9:32:10 | exit M1 | semmle.label | exception(NullReferenceException) |
| MultiImplementationA.cs:36:22:36:25 | null | MultiImplementationA.cs:36:16:36:26 | throw ...; | semmle.label | successor |
| MultiImplementationA.cs:37:9:37:10 | enter M2 | MultiImplementationA.cs:37:14:37:28 | {...} | semmle.label | successor |
| MultiImplementationA.cs:37:14:37:28 | {...} | MultiImplementationA.cs:37:22:37:25 | null | semmle.label | successor |
| MultiImplementationA.cs:37:16:37:26 | throw ...; | MultiImplementationA.cs:37:9:37:10 | exit M2 | semmle.label | exception(NullReferenceException) |
| MultiImplementationA.cs:37:22:37:25 | null | MultiImplementationA.cs:37:16:37:26 | throw ...; | semmle.label | successor |
| MultiImplementationB.cs:3:22:3:22 | 0 | MultiImplementationA.cs:6:22:6:31 | exit get_P1 | semmle.label | successor |
| MultiImplementationB.cs:3:22:3:22 | 0 | MultiImplementationB.cs:3:22:3:22 | exit get_P1 | semmle.label | successor |
| MultiImplementationB.cs:3:22:3:22 | enter get_P1 | MultiImplementationA.cs:6:28:6:31 | null | semmle.label | successor |
| MultiImplementationB.cs:3:22:3:22 | enter get_P1 | MultiImplementationB.cs:3:22:3:22 | 0 | semmle.label | successor |
| MultiImplementationB.cs:4:21:4:23 | enter get_P2 | MultiImplementationA.cs:7:25:7:39 | {...} | semmle.label | successor |
| MultiImplementationB.cs:4:21:4:23 | enter get_P2 | MultiImplementationB.cs:4:25:4:37 | {...} | semmle.label | successor |
| MultiImplementationB.cs:4:25:4:37 | {...} | MultiImplementationB.cs:4:34:4:34 | 1 | semmle.label | successor |
| MultiImplementationB.cs:4:27:4:35 | return ...; | MultiImplementationA.cs:7:21:7:23 | exit get_P2 | semmle.label | return |
| MultiImplementationB.cs:4:27:4:35 | return ...; | MultiImplementationB.cs:4:21:4:23 | exit get_P2 | semmle.label | return |
| MultiImplementationB.cs:4:34:4:34 | 1 | MultiImplementationB.cs:4:27:4:35 | return ...; | semmle.label | successor |
| MultiImplementationB.cs:4:39:4:41 | enter set_P2 | MultiImplementationA.cs:7:45:7:59 | {...} | semmle.label | successor |
| MultiImplementationB.cs:4:39:4:41 | enter set_P2 | MultiImplementationB.cs:4:43:4:45 | {...} | semmle.label | successor |
| MultiImplementationB.cs:4:43:4:45 | {...} | MultiImplementationA.cs:7:41:7:43 | exit set_P2 | semmle.label | successor |
| MultiImplementationB.cs:4:43:4:45 | {...} | MultiImplementationB.cs:4:39:4:41 | exit set_P2 | semmle.label | successor |
| MultiImplementationB.cs:5:16:5:16 | enter M | MultiImplementationA.cs:8:29:8:32 | null | semmle.label | successor |
| MultiImplementationB.cs:5:16:5:16 | enter M | MultiImplementationB.cs:5:23:5:23 | 2 | semmle.label | successor |
| MultiImplementationB.cs:5:23:5:23 | 2 | MultiImplementationA.cs:8:16:8:16 | exit M | semmle.label | successor |
| MultiImplementationB.cs:5:23:5:23 | 2 | MultiImplementationB.cs:5:16:5:16 | exit M | semmle.label | successor |
| MultiImplementationB.cs:11:16:11:16 | this access | MultiImplementationB.cs:11:20:11:20 | 1 | semmle.label | successor |
| MultiImplementationB.cs:11:16:11:20 | ... = ... | MultiImplementationA.cs:13:16:13:16 | this access | semmle.label | successor |
| MultiImplementationB.cs:11:16:11:20 | ... = ... | MultiImplementationA.cs:24:16:24:16 | this access | semmle.label | successor |
| MultiImplementationB.cs:11:16:11:20 | ... = ... | MultiImplementationB.cs:11:16:11:16 | this access | semmle.label | successor |
| MultiImplementationB.cs:11:16:11:20 | ... = ... | MultiImplementationB.cs:22:16:22:16 | this access | semmle.label | successor |
| MultiImplementationB.cs:11:20:11:20 | 1 | MultiImplementationB.cs:11:16:11:20 | ... = ... | semmle.label | successor |
| MultiImplementationB.cs:12:31:12:40 | enter get_Item | MultiImplementationA.cs:14:31:14:31 | access to parameter i | semmle.label | successor |
| MultiImplementationB.cs:12:31:12:40 | enter get_Item | MultiImplementationB.cs:12:37:12:40 | null | semmle.label | successor |
| MultiImplementationB.cs:12:31:12:40 | throw ... | MultiImplementationA.cs:14:31:14:31 | exit get_Item | semmle.label | exception(NullReferenceException) |
| MultiImplementationB.cs:12:31:12:40 | throw ... | MultiImplementationB.cs:12:31:12:40 | exit get_Item | semmle.label | exception(NullReferenceException) |
| MultiImplementationB.cs:12:37:12:40 | null | MultiImplementationB.cs:12:31:12:40 | throw ... | semmle.label | successor |
| MultiImplementationB.cs:13:36:13:38 | enter get_Item | MultiImplementationA.cs:15:40:15:52 | {...} | semmle.label | successor |
| MultiImplementationB.cs:13:36:13:38 | enter get_Item | MultiImplementationB.cs:13:40:13:54 | {...} | semmle.label | successor |
| MultiImplementationB.cs:13:40:13:54 | {...} | MultiImplementationB.cs:13:48:13:51 | null | semmle.label | successor |
| MultiImplementationB.cs:13:42:13:52 | throw ...; | MultiImplementationA.cs:15:36:15:38 | exit get_Item | semmle.label | exception(NullReferenceException) |
| MultiImplementationB.cs:13:42:13:52 | throw ...; | MultiImplementationB.cs:13:36:13:38 | exit get_Item | semmle.label | exception(NullReferenceException) |
| MultiImplementationB.cs:13:48:13:51 | null | MultiImplementationB.cs:13:42:13:52 | throw ...; | semmle.label | successor |
| MultiImplementationB.cs:13:56:13:58 | enter set_Item | MultiImplementationA.cs:15:58:15:60 | {...} | semmle.label | successor |
| MultiImplementationB.cs:13:56:13:58 | enter set_Item | MultiImplementationB.cs:13:60:13:62 | {...} | semmle.label | successor |
| MultiImplementationB.cs:13:60:13:62 | {...} | MultiImplementationA.cs:15:54:15:56 | exit set_Item | semmle.label | successor |
| MultiImplementationB.cs:13:60:13:62 | {...} | MultiImplementationB.cs:13:56:13:58 | exit set_Item | semmle.label | successor |
| MultiImplementationB.cs:14:17:14:18 | enter M1 | MultiImplementationA.cs:17:5:19:5 | {...} | semmle.label | successor |
| MultiImplementationB.cs:14:17:14:18 | enter M1 | MultiImplementationB.cs:15:5:17:5 | {...} | semmle.label | successor |
| MultiImplementationB.cs:15:5:17:5 | {...} | MultiImplementationB.cs:16:9:16:31 | M2(...) | semmle.label | successor |
| MultiImplementationB.cs:16:9:16:31 | M2(...) | MultiImplementationA.cs:16:17:16:18 | exit M1 | semmle.label | successor |
| MultiImplementationB.cs:16:9:16:31 | M2(...) | MultiImplementationB.cs:14:17:14:18 | exit M1 | semmle.label | successor |
| MultiImplementationB.cs:16:9:16:31 | enter M2 | MultiImplementationB.cs:16:27:16:30 | null | semmle.label | successor |
| MultiImplementationB.cs:16:21:16:30 | throw ... | MultiImplementationB.cs:16:9:16:31 | exit M2 | semmle.label | exception(NullReferenceException) |
| MultiImplementationB.cs:16:27:16:30 | null | MultiImplementationB.cs:16:21:16:30 | throw ... | semmle.label | successor |
| MultiImplementationB.cs:18:12:18:13 | enter C2 | MultiImplementationA.cs:13:16:13:16 | this access | semmle.label | successor |
| MultiImplementationB.cs:18:12:18:13 | enter C2 | MultiImplementationB.cs:11:16:11:16 | this access | semmle.label | successor |
| MultiImplementationB.cs:18:22:18:36 | {...} | MultiImplementationB.cs:18:30:18:33 | null | semmle.label | successor |
| MultiImplementationB.cs:18:24:18:34 | throw ...; | MultiImplementationA.cs:20:12:20:13 | exit C2 | semmle.label | exception(NullReferenceException) |
| MultiImplementationB.cs:18:24:18:34 | throw ...; | MultiImplementationB.cs:18:12:18:13 | exit C2 | semmle.label | exception(NullReferenceException) |
| MultiImplementationB.cs:18:30:18:33 | null | MultiImplementationB.cs:18:24:18:34 | throw ...; | semmle.label | successor |
| MultiImplementationB.cs:19:12:19:13 | enter C2 | MultiImplementationA.cs:21:24:21:24 | 0 | semmle.label | successor |
| MultiImplementationB.cs:19:12:19:13 | enter C2 | MultiImplementationB.cs:19:24:19:24 | 1 | semmle.label | successor |
| MultiImplementationB.cs:19:19:19:22 | call to constructor C2 | MultiImplementationA.cs:21:27:21:29 | {...} | semmle.label | successor |
| MultiImplementationB.cs:19:19:19:22 | call to constructor C2 | MultiImplementationB.cs:19:27:19:29 | {...} | semmle.label | successor |
| MultiImplementationB.cs:19:24:19:24 | 1 | MultiImplementationB.cs:19:19:19:22 | call to constructor C2 | semmle.label | successor |
| MultiImplementationB.cs:19:27:19:29 | {...} | MultiImplementationA.cs:21:12:21:13 | exit C2 | semmle.label | successor |
| MultiImplementationB.cs:19:27:19:29 | {...} | MultiImplementationB.cs:19:12:19:13 | exit C2 | semmle.label | successor |
| MultiImplementationB.cs:20:6:20:7 | enter ~C2 | MultiImplementationA.cs:22:11:22:13 | {...} | semmle.label | successor |
| MultiImplementationB.cs:20:6:20:7 | enter ~C2 | MultiImplementationB.cs:20:11:20:25 | {...} | semmle.label | successor |
| MultiImplementationB.cs:20:11:20:25 | {...} | MultiImplementationB.cs:20:19:20:22 | null | semmle.label | successor |
| MultiImplementationB.cs:20:13:20:23 | throw ...; | MultiImplementationA.cs:22:6:22:7 | exit ~C2 | semmle.label | exception(NullReferenceException) |
| MultiImplementationB.cs:20:13:20:23 | throw ...; | MultiImplementationB.cs:20:6:20:7 | exit ~C2 | semmle.label | exception(NullReferenceException) |
| MultiImplementationB.cs:20:19:20:22 | null | MultiImplementationB.cs:20:13:20:23 | throw ...; | semmle.label | successor |
| MultiImplementationB.cs:21:28:21:35 | enter implicit conversion | MultiImplementationA.cs:23:50:23:53 | null | semmle.label | successor |
| MultiImplementationB.cs:21:28:21:35 | enter implicit conversion | MultiImplementationB.cs:21:56:21:59 | null | semmle.label | successor |
| MultiImplementationB.cs:21:50:21:59 | throw ... | MultiImplementationA.cs:23:28:23:35 | exit implicit conversion | semmle.label | exception(NullReferenceException) |
| MultiImplementationB.cs:21:50:21:59 | throw ... | MultiImplementationB.cs:21:28:21:35 | exit implicit conversion | semmle.label | exception(NullReferenceException) |
| MultiImplementationB.cs:21:56:21:59 | null | MultiImplementationB.cs:21:50:21:59 | throw ... | semmle.label | successor |
| MultiImplementationB.cs:22:16:22:16 | access to property P | MultiImplementationB.cs:22:32:22:34 | ... = ... | semmle.label | successor |
| MultiImplementationB.cs:22:16:22:16 | this access | MultiImplementationB.cs:22:34:22:34 | 1 | semmle.label | successor |
| MultiImplementationB.cs:22:32:22:34 | ... = ... | MultiImplementationA.cs:20:22:20:31 | {...} | semmle.label | successor |
| MultiImplementationB.cs:22:32:22:34 | ... = ... | MultiImplementationA.cs:24:16:24:16 | this access | semmle.label | successor |
| MultiImplementationB.cs:22:32:22:34 | ... = ... | MultiImplementationB.cs:18:22:18:36 | {...} | semmle.label | successor |
| MultiImplementationB.cs:22:32:22:34 | ... = ... | MultiImplementationB.cs:22:16:22:16 | this access | semmle.label | successor |
| MultiImplementationB.cs:22:34:22:34 | 1 | MultiImplementationB.cs:22:16:22:16 | access to property P | semmle.label | successor |
| MultiImplementationB.cs:27:21:27:23 | enter get_P3 | MultiImplementationA.cs:30:34:30:37 | null | semmle.label | successor |
| MultiImplementationB.cs:32:9:32:10 | enter M1 | MultiImplementationA.cs:36:14:36:28 | {...} | semmle.label | successor |
| MultiImplementationB.cs:32:9:32:10 | enter M1 | MultiImplementationB.cs:32:17:32:17 | 0 | semmle.label | successor |
| MultiImplementationB.cs:32:17:32:17 | 0 | MultiImplementationA.cs:36:9:36:10 | exit M1 | semmle.label | successor |
| MultiImplementationB.cs:32:17:32:17 | 0 | MultiImplementationB.cs:32:9:32:10 | exit M1 | semmle.label | successor |
| NullCoalescing.cs:3:9:3:10 | enter M1 | NullCoalescing.cs:3:23:3:28 | ... ?? ... | semmle.label | successor |
| NullCoalescing.cs:3:23:3:23 | access to parameter i | NullCoalescing.cs:3:9:3:10 | exit M1 | semmle.label | non-null |
| NullCoalescing.cs:3:23:3:23 | access to parameter i | NullCoalescing.cs:3:28:3:28 | 0 | semmle.label | null |

View File

@@ -736,6 +736,63 @@ entryPoint
| LoopUnrolling.cs:45:10:45:11 | M6 | LoopUnrolling.cs:46:5:53:5 | {...} |
| LoopUnrolling.cs:55:10:55:11 | M7 | LoopUnrolling.cs:56:5:65:5 | {...} |
| LoopUnrolling.cs:67:10:67:11 | M8 | LoopUnrolling.cs:68:5:74:5 | {...} |
| MultiImplementationA.cs:6:22:6:31 | get_P1 | MultiImplementationA.cs:6:28:6:31 | null |
| MultiImplementationA.cs:6:22:6:31 | get_P1 | MultiImplementationB.cs:3:22:3:22 | 0 |
| MultiImplementationA.cs:7:21:7:23 | get_P2 | MultiImplementationA.cs:7:25:7:39 | {...} |
| MultiImplementationA.cs:7:21:7:23 | get_P2 | MultiImplementationB.cs:4:25:4:37 | {...} |
| MultiImplementationA.cs:7:41:7:43 | set_P2 | MultiImplementationA.cs:7:45:7:59 | {...} |
| MultiImplementationA.cs:7:41:7:43 | set_P2 | MultiImplementationB.cs:4:43:4:45 | {...} |
| MultiImplementationA.cs:8:16:8:16 | M | MultiImplementationA.cs:8:29:8:32 | null |
| MultiImplementationA.cs:8:16:8:16 | M | MultiImplementationB.cs:5:23:5:23 | 2 |
| MultiImplementationA.cs:14:31:14:31 | get_Item | MultiImplementationA.cs:14:31:14:31 | access to parameter i |
| MultiImplementationA.cs:14:31:14:31 | get_Item | MultiImplementationB.cs:12:37:12:40 | null |
| MultiImplementationA.cs:15:36:15:38 | get_Item | MultiImplementationA.cs:15:40:15:52 | {...} |
| MultiImplementationA.cs:15:36:15:38 | get_Item | MultiImplementationB.cs:13:40:13:54 | {...} |
| MultiImplementationA.cs:15:54:15:56 | set_Item | MultiImplementationA.cs:15:58:15:60 | {...} |
| MultiImplementationA.cs:15:54:15:56 | set_Item | MultiImplementationB.cs:13:60:13:62 | {...} |
| MultiImplementationA.cs:16:17:16:18 | M1 | MultiImplementationA.cs:17:5:19:5 | {...} |
| MultiImplementationA.cs:16:17:16:18 | M1 | MultiImplementationB.cs:15:5:17:5 | {...} |
| MultiImplementationA.cs:18:9:18:22 | M2 | MultiImplementationA.cs:18:21:18:21 | 0 |
| MultiImplementationA.cs:20:12:20:13 | C2 | MultiImplementationA.cs:13:16:13:16 | this access |
| MultiImplementationA.cs:20:12:20:13 | C2 | MultiImplementationB.cs:11:16:11:16 | this access |
| MultiImplementationA.cs:21:12:21:13 | C2 | MultiImplementationA.cs:21:24:21:24 | 0 |
| MultiImplementationA.cs:21:12:21:13 | C2 | MultiImplementationB.cs:19:24:19:24 | 1 |
| MultiImplementationA.cs:22:6:22:7 | ~C2 | MultiImplementationA.cs:22:11:22:13 | {...} |
| MultiImplementationA.cs:22:6:22:7 | ~C2 | MultiImplementationB.cs:20:11:20:25 | {...} |
| MultiImplementationA.cs:23:28:23:35 | implicit conversion | MultiImplementationA.cs:23:50:23:53 | null |
| MultiImplementationA.cs:23:28:23:35 | implicit conversion | MultiImplementationB.cs:21:56:21:59 | null |
| MultiImplementationA.cs:30:21:30:23 | get_P3 | MultiImplementationA.cs:30:34:30:37 | null |
| MultiImplementationA.cs:36:9:36:10 | M1 | MultiImplementationA.cs:36:14:36:28 | {...} |
| MultiImplementationA.cs:36:9:36:10 | M1 | MultiImplementationB.cs:32:17:32:17 | 0 |
| MultiImplementationA.cs:37:9:37:10 | M2 | MultiImplementationA.cs:37:14:37:28 | {...} |
| MultiImplementationB.cs:3:22:3:22 | get_P1 | MultiImplementationA.cs:6:28:6:31 | null |
| MultiImplementationB.cs:3:22:3:22 | get_P1 | MultiImplementationB.cs:3:22:3:22 | 0 |
| MultiImplementationB.cs:4:21:4:23 | get_P2 | MultiImplementationA.cs:7:25:7:39 | {...} |
| MultiImplementationB.cs:4:21:4:23 | get_P2 | MultiImplementationB.cs:4:25:4:37 | {...} |
| MultiImplementationB.cs:4:39:4:41 | set_P2 | MultiImplementationA.cs:7:45:7:59 | {...} |
| MultiImplementationB.cs:4:39:4:41 | set_P2 | MultiImplementationB.cs:4:43:4:45 | {...} |
| MultiImplementationB.cs:5:16:5:16 | M | MultiImplementationA.cs:8:29:8:32 | null |
| MultiImplementationB.cs:5:16:5:16 | M | MultiImplementationB.cs:5:23:5:23 | 2 |
| MultiImplementationB.cs:12:31:12:40 | get_Item | MultiImplementationA.cs:14:31:14:31 | access to parameter i |
| MultiImplementationB.cs:12:31:12:40 | get_Item | MultiImplementationB.cs:12:37:12:40 | null |
| MultiImplementationB.cs:13:36:13:38 | get_Item | MultiImplementationA.cs:15:40:15:52 | {...} |
| MultiImplementationB.cs:13:36:13:38 | get_Item | MultiImplementationB.cs:13:40:13:54 | {...} |
| MultiImplementationB.cs:13:56:13:58 | set_Item | MultiImplementationA.cs:15:58:15:60 | {...} |
| MultiImplementationB.cs:13:56:13:58 | set_Item | MultiImplementationB.cs:13:60:13:62 | {...} |
| MultiImplementationB.cs:14:17:14:18 | M1 | MultiImplementationA.cs:17:5:19:5 | {...} |
| MultiImplementationB.cs:14:17:14:18 | M1 | MultiImplementationB.cs:15:5:17:5 | {...} |
| MultiImplementationB.cs:16:9:16:31 | M2 | MultiImplementationB.cs:16:27:16:30 | null |
| MultiImplementationB.cs:18:12:18:13 | C2 | MultiImplementationA.cs:13:16:13:16 | this access |
| MultiImplementationB.cs:18:12:18:13 | C2 | MultiImplementationB.cs:11:16:11:16 | this access |
| MultiImplementationB.cs:19:12:19:13 | C2 | MultiImplementationA.cs:21:24:21:24 | 0 |
| MultiImplementationB.cs:19:12:19:13 | C2 | MultiImplementationB.cs:19:24:19:24 | 1 |
| MultiImplementationB.cs:20:6:20:7 | ~C2 | MultiImplementationA.cs:22:11:22:13 | {...} |
| MultiImplementationB.cs:20:6:20:7 | ~C2 | MultiImplementationB.cs:20:11:20:25 | {...} |
| MultiImplementationB.cs:21:28:21:35 | implicit conversion | MultiImplementationA.cs:23:50:23:53 | null |
| MultiImplementationB.cs:21:28:21:35 | implicit conversion | MultiImplementationB.cs:21:56:21:59 | null |
| MultiImplementationB.cs:27:21:27:23 | get_P3 | MultiImplementationA.cs:30:34:30:37 | null |
| MultiImplementationB.cs:32:9:32:10 | M1 | MultiImplementationA.cs:36:14:36:28 | {...} |
| MultiImplementationB.cs:32:9:32:10 | M1 | MultiImplementationB.cs:32:17:32:17 | 0 |
| NullCoalescing.cs:3:9:3:10 | M1 | NullCoalescing.cs:3:23:3:28 | ... ?? ... |
| NullCoalescing.cs:5:9:5:10 | M2 | NullCoalescing.cs:5:24:5:43 | ... ? ... : ... |
| NullCoalescing.cs:7:12:7:13 | M3 | NullCoalescing.cs:7:40:7:53 | ... ?? ... |

View File

@@ -243,7 +243,7 @@ expressionTypes
| NullableRefTypes.cs:19:33:19:36 | this access | MyClass! |
| NullableRefTypes.cs:26:44:26:53 | throw ... | MyClass![]! |
| NullableRefTypes.cs:26:50:26:53 | null | null |
| NullableRefTypes.cs:27:44:27:53 | throw ... | MyClass![]! |
| NullableRefTypes.cs:27:44:27:53 | throw ... | MyClass?[]! |
| NullableRefTypes.cs:27:50:27:53 | null | null |
| NullableRefTypes.cs:30:21:30:24 | null | null |
| NullableRefTypes.cs:31:20:31:23 | this access | MyClass! |

View File

@@ -950,143 +950,72 @@ ranges.cs:
# 9| 2: [IntLiteral] 3
# 9| 3: [IntLiteral] 4
# 9| 1: [LocalVariableAccess] access to local variable array
# 10| 1: [LocalVariableDeclStmt] ... ...;
# 10| 0: [LocalVariableDeclAndInitExpr] Int32[,] array2 = ...
# 10| 0: [ArrayCreation] array creation of type Int32[,]
# 10| 0: [IntLiteral] 2
# 10| 1: [IntLiteral] 3
# 10| 1: [LocalVariableAccess] access to local variable array2
# 11| 1: [LocalVariableDeclStmt] ... ...;
# 11| 0: [LocalVariableDeclAndInitExpr] Int32[] slice1 = ...
# 11| 0: [ArrayAccess] access to array element
# 11| -1: [LocalVariableAccess] access to local variable array
# 11| 0: [RangeExpr] ... .. ...
# 11| 0: [OperatorCall] call to operator implicit conversion
# 11| 0: [IntLiteral] 1
# 11| 1: [OperatorCall] call to operator implicit conversion
# 11| 0: [IntLiteral] 3
# 11| 1: [LocalVariableAccess] access to local variable slice1
# 12| 2: [LocalVariableDeclStmt] ... ...;
# 12| 0: [LocalVariableDeclAndInitExpr] Int32 slice1 = ...
# 12| 0: [LocalVariableDeclAndInitExpr] Int32[] slice2 = ...
# 12| 0: [ArrayAccess] access to array element
# 12| -1: [LocalVariableAccess] access to local variable array
# 12| 0: [OperatorCall] call to operator implicit conversion
# 12| 0: [RangeExpr] ... .. ...
# 12| 0: [OperatorCall] call to operator implicit conversion
# 12| 0: [IntLiteral] 1
# 12| 1: [OperatorCall] call to operator implicit conversion
# 12| 0: [IntLiteral] 3
# 12| 1: [LocalVariableAccess] access to local variable slice1
# 12| 0: [RangeExpr] ... .. ...
# 12| 0: [OperatorCall] call to operator implicit conversion
# 12| 0: [IntLiteral] 0
# 12| 1: [IndexExpr] ^...
# 12| 0: [IntLiteral] 1
# 12| 1: [LocalVariableAccess] access to local variable slice2
# 13| 3: [LocalVariableDeclStmt] ... ...;
# 13| 0: [LocalVariableDeclAndInitExpr] Int32 slice2 = ...
# 13| 0: [ArrayAccess] access to array element
# 13| -1: [LocalVariableAccess] access to local variable array
# 13| 0: [OperatorCall] call to operator implicit conversion
# 13| 0: [RangeExpr] ... .. ...
# 13| 0: [OperatorCall] call to operator implicit conversion
# 13| 0: [IntLiteral] 0
# 13| 1: [IndexExpr] ^...
# 13| 0: [IntLiteral] 1
# 13| 1: [LocalVariableAccess] access to local variable slice2
# 13| 0: [LocalVariableDeclAndInitExpr] Int32 x = ...
# 13| 0: [IntLiteral] 2
# 13| 1: [LocalVariableAccess] access to local variable x
# 13| 1: [LocalVariableDeclAndInitExpr] Int32 y = ...
# 13| 0: [IntLiteral] 3
# 13| 1: [LocalVariableAccess] access to local variable y
# 14| 4: [LocalVariableDeclStmt] ... ...;
# 14| 0: [LocalVariableDeclAndInitExpr] Int32 x = ...
# 14| 0: [IntLiteral] 2
# 14| 1: [LocalVariableAccess] access to local variable x
# 14| 1: [LocalVariableDeclAndInitExpr] Int32 y = ...
# 14| 0: [IntLiteral] 3
# 14| 1: [LocalVariableAccess] access to local variable y
# 14| 0: [LocalVariableDeclAndInitExpr] Int32[] slice3 = ...
# 14| 0: [ArrayAccess] access to array element
# 14| -1: [LocalVariableAccess] access to local variable array
# 14| 0: [RangeExpr] ... .. ...
# 14| 0: [OperatorCall] call to operator implicit conversion
# 14| 0: [LocalVariableAccess] access to local variable x
# 14| 1: [OperatorCall] call to operator implicit conversion
# 14| 0: [LocalVariableAccess] access to local variable y
# 14| 1: [LocalVariableAccess] access to local variable slice3
# 15| 5: [LocalVariableDeclStmt] ... ...;
# 15| 0: [LocalVariableDeclAndInitExpr] Int32 slice3 = ...
# 15| 0: [LocalVariableDeclAndInitExpr] Int32[] slice4 = ...
# 15| 0: [ArrayAccess] access to array element
# 15| -1: [LocalVariableAccess] access to local variable array
# 15| 0: [OperatorCall] call to operator implicit conversion
# 15| 0: [RangeExpr] ... .. ...
# 15| 0: [OperatorCall] call to operator implicit conversion
# 15| 0: [LocalVariableAccess] access to local variable x
# 15| 1: [OperatorCall] call to operator implicit conversion
# 15| 0: [LocalVariableAccess] access to local variable y
# 15| 1: [LocalVariableAccess] access to local variable slice3
# 15| 0: [RangeExpr] ... .. ...
# 15| 1: [OperatorCall] call to operator implicit conversion
# 15| 0: [LocalVariableAccess] access to local variable y
# 15| 1: [LocalVariableAccess] access to local variable slice4
# 16| 6: [LocalVariableDeclStmt] ... ...;
# 16| 0: [LocalVariableDeclAndInitExpr] Int32 slice4 = ...
# 16| 0: [LocalVariableDeclAndInitExpr] Int32[] slice5 = ...
# 16| 0: [ArrayAccess] access to array element
# 16| -1: [LocalVariableAccess] access to local variable array
# 16| 0: [OperatorCall] call to operator implicit conversion
# 16| 0: [RangeExpr] ... .. ...
# 16| 1: [OperatorCall] call to operator implicit conversion
# 16| 0: [LocalVariableAccess] access to local variable y
# 16| 1: [LocalVariableAccess] access to local variable slice4
# 16| 0: [RangeExpr] ... .. ...
# 16| 0: [OperatorCall] call to operator implicit conversion
# 16| 0: [LocalVariableAccess] access to local variable x
# 16| 1: [LocalVariableAccess] access to local variable slice5
# 17| 7: [LocalVariableDeclStmt] ... ...;
# 17| 0: [LocalVariableDeclAndInitExpr] Int32 slice5 = ...
# 17| 0: [LocalVariableDeclAndInitExpr] Int32[] slice6 = ...
# 17| 0: [ArrayAccess] access to array element
# 17| -1: [LocalVariableAccess] access to local variable array
# 17| 0: [OperatorCall] call to operator implicit conversion
# 17| 0: [RangeExpr] ... .. ...
# 17| 0: [OperatorCall] call to operator implicit conversion
# 17| 0: [LocalVariableAccess] access to local variable x
# 17| 1: [LocalVariableAccess] access to local variable slice5
# 17| 0: [RangeExpr] ... .. ...
# 17| 1: [LocalVariableAccess] access to local variable slice6
# 18| 8: [LocalVariableDeclStmt] ... ...;
# 18| 0: [LocalVariableDeclAndInitExpr] Int32 slice6 = ...
# 18| 0: [LocalVariableDeclAndInitExpr] Int32[] slice7 = ...
# 18| 0: [ArrayAccess] access to array element
# 18| -1: [LocalVariableAccess] access to local variable array
# 18| 0: [OperatorCall] call to operator implicit conversion
# 18| 0: [RangeExpr] ... .. ...
# 18| 1: [LocalVariableAccess] access to local variable slice6
# 19| 9: [LocalVariableDeclStmt] ... ...;
# 19| 0: [LocalVariableDeclAndInitExpr] Int32 slice7 = ...
# 19| 0: [ArrayAccess] access to array element
# 19| -1: [LocalVariableAccess] access to local variable array
# 19| 0: [OperatorCall] call to operator implicit conversion
# 19| 0: [RangeExpr] ... .. ...
# 19| 0: [IndexExpr] ^...
# 19| 0: [IntLiteral] 10
# 19| 1: [IndexExpr] ^...
# 19| 0: [IntLiteral] 5
# 19| 1: [LocalVariableAccess] access to local variable slice7
# 20| 10: [LocalVariableDeclStmt] ... ...;
# 20| 0: [LocalVariableDeclAndInitExpr] Int32 slice8 = ...
# 20| 0: [ArrayAccess] access to array element
# 20| -1: [LocalVariableAccess] access to local variable array2
# 20| 0: [OperatorCall] call to operator implicit conversion
# 20| 0: [RangeExpr] ... .. ...
# 20| 0: [OperatorCall] call to operator implicit conversion
# 20| 0: [IntLiteral] 1
# 20| 1: [OperatorCall] call to operator implicit conversion
# 20| 0: [IntLiteral] 2
# 20| 1: [OperatorCall] call to operator implicit conversion
# 20| 0: [RangeExpr] ... .. ...
# 20| 1: [LocalVariableAccess] access to local variable slice8
# 25| [NamespaceDeclaration] namespace ... { ... }
# 27| 1: [Struct] Index
# 29| 5: [InstanceConstructor] Index
#-----| 2: (Parameters)
# 29| 0: [Parameter] value
# 29| 1: [Parameter] fromEnd
# 29| 1: [BoolLiteral] false
# 29| 4: [BlockStmt] {...}
# 30| 6: [ImplicitConversionOperator] implicit conversion
#-----| 2: (Parameters)
# 30| 0: [Parameter] value
# 30| 4: [DefaultValueExpr] default(...)
# 30| 0: [TypeAccess] access to type Index
# 33| 2: [Struct] Range
# 35| 5: [InstanceConstructor] Range
#-----| 2: (Parameters)
# 35| 0: [Parameter] start
# 35| 1: [Parameter] end
# 35| 4: [ThrowExpr] throw ...
# 35| 0: [NullLiteral] null
# 36| 6: [Method] StartAt
#-----| 2: (Parameters)
# 36| 0: [Parameter] start
# 36| 4: [ThrowExpr] throw ...
# 36| 0: [NullLiteral] null
# 37| 7: [Method] EndAt
#-----| 2: (Parameters)
# 37| 0: [Parameter] end
# 37| 4: [ThrowExpr] throw ...
# 37| 0: [NullLiteral] null
# 38| 8: [Property] All
# 38| 3: [Getter] get_All
# 38| 4: [ThrowExpr] throw ...
# 38| 0: [NullLiteral] null
# 39| 9: [Method] Create
#-----| 2: (Parameters)
# 39| 0: [Parameter] start
# 39| 1: [Parameter] end
# 39| 4: [ThrowExpr] throw ...
# 39| 0: [NullLiteral] null
# 40| 10: [ImplicitConversionOperator] implicit conversion
#-----| 2: (Parameters)
# 40| 0: [Parameter] r
# 40| 4: [ThrowExpr] throw ...
# 40| 0: [NullLiteral] null
# 18| 0: [RangeExpr] ... .. ...
# 18| 0: [IndexExpr] ^...
# 18| 0: [IntLiteral] 10
# 18| 1: [IndexExpr] ^...
# 18| 0: [IntLiteral] 5
# 18| 1: [LocalVariableAccess] access to local variable slice7

View File

@@ -7,36 +7,14 @@ class Ranges
void F()
{
var array = new int[] { 1, 2, 3, 4 };
var array2 = new int[2, 3];
var slice1 = array[1..3];
var slice2 = array[0..^1];
int x=2, y=3;
int x = 2, y = 3;
var slice3 = array[x..y];
var slice4 = array[..y];
var slice5 = array[x..];
var slice6 = array[..];
var slice7 = array[^10..^5];
var slice8 = array2[1..2, ..];
}
}
// These are temporary until qltest uses .NET Core 3.0.
namespace System
{
public readonly struct Index
{
public Index(int value, bool fromEnd = false) { }
public static implicit operator Index(int value) => default(Index);
}
public readonly struct Range
{
public Range(Index start, Index end) => throw null;
public static Range StartAt(System.Index start) => throw null;
public static Range EndAt(System.Index end) => throw null;
public static Range All => throw null;
public static Range Create(Index start, Index end) => throw null;
public static implicit operator int(Range r) => throw null;
}
}

View File

@@ -1,28 +1,24 @@
indexes
| ranges.cs:13:31:13:32 | ^... | ranges.cs:13:32:13:32 | 1 |
| ranges.cs:19:28:19:30 | ^... | ranges.cs:19:29:19:30 | 10 |
| ranges.cs:19:33:19:34 | ^... | ranges.cs:19:34:19:34 | 5 |
| ranges.cs:12:31:12:32 | ^... | ranges.cs:12:32:12:32 | 1 |
| ranges.cs:18:28:18:30 | ^... | ranges.cs:18:29:18:30 | 10 |
| ranges.cs:18:33:18:34 | ^... | ranges.cs:18:34:18:34 | 5 |
ranges
| ranges.cs:12:28:12:31 | ... .. ... |
| ranges.cs:13:28:13:32 | ... .. ... |
| ranges.cs:15:28:15:31 | ... .. ... |
| ranges.cs:11:28:11:31 | ... .. ... |
| ranges.cs:12:28:12:32 | ... .. ... |
| ranges.cs:14:28:14:31 | ... .. ... |
| ranges.cs:15:28:15:30 | ... .. ... |
| ranges.cs:16:28:16:30 | ... .. ... |
| ranges.cs:17:28:17:30 | ... .. ... |
| ranges.cs:18:28:18:29 | ... .. ... |
| ranges.cs:19:28:19:34 | ... .. ... |
| ranges.cs:20:29:20:32 | ... .. ... |
| ranges.cs:20:35:20:36 | ... .. ... |
| ranges.cs:17:28:17:29 | ... .. ... |
| ranges.cs:18:28:18:34 | ... .. ... |
rangeStart
| ranges.cs:12:28:12:31 | ... .. ... | ranges.cs:12:28:12:28 | 1 |
| ranges.cs:13:28:13:32 | ... .. ... | ranges.cs:13:28:13:28 | 0 |
| ranges.cs:15:28:15:31 | ... .. ... | ranges.cs:15:28:15:28 | access to local variable x |
| ranges.cs:17:28:17:30 | ... .. ... | ranges.cs:17:28:17:28 | access to local variable x |
| ranges.cs:19:28:19:34 | ... .. ... | ranges.cs:19:28:19:30 | ^... |
| ranges.cs:20:29:20:32 | ... .. ... | ranges.cs:20:29:20:29 | 1 |
| ranges.cs:11:28:11:31 | ... .. ... | ranges.cs:11:28:11:28 | 1 |
| ranges.cs:12:28:12:32 | ... .. ... | ranges.cs:12:28:12:28 | 0 |
| ranges.cs:14:28:14:31 | ... .. ... | ranges.cs:14:28:14:28 | access to local variable x |
| ranges.cs:16:28:16:30 | ... .. ... | ranges.cs:16:28:16:28 | access to local variable x |
| ranges.cs:18:28:18:34 | ... .. ... | ranges.cs:18:28:18:30 | ^... |
rangeEnd
| ranges.cs:12:28:12:31 | ... .. ... | ranges.cs:12:31:12:31 | 3 |
| ranges.cs:13:28:13:32 | ... .. ... | ranges.cs:13:31:13:32 | ^... |
| ranges.cs:15:28:15:31 | ... .. ... | ranges.cs:15:31:15:31 | access to local variable y |
| ranges.cs:16:28:16:30 | ... .. ... | ranges.cs:16:30:16:30 | access to local variable y |
| ranges.cs:19:28:19:34 | ... .. ... | ranges.cs:19:33:19:34 | ^... |
| ranges.cs:20:29:20:32 | ... .. ... | ranges.cs:20:32:20:32 | 2 |
| ranges.cs:11:28:11:31 | ... .. ... | ranges.cs:11:31:11:31 | 3 |
| ranges.cs:12:28:12:32 | ... .. ... | ranges.cs:12:31:12:32 | ^... |
| ranges.cs:14:28:14:31 | ... .. ... | ranges.cs:14:31:14:31 | access to local variable y |
| ranges.cs:15:28:15:30 | ... .. ... | ranges.cs:15:30:15:30 | access to local variable y |
| ranges.cs:18:28:18:34 | ... .. ... | ranges.cs:18:33:18:34 | ^... |

View File

@@ -175,10 +175,10 @@ definitions.cs:
# 97| 5: [Class] A
# 99| 5: [DelegateType] EventHandler
# 101| 6: [Event] Click
# 101| 3: [RemoveEventAccessor] remove_Click
# 101| 3: [AddEventAccessor] add_Click
#-----| 2: (Parameters)
# 101| 0: [Parameter] value
# 101| 3: [AddEventAccessor] add_Click
# 101| 3: [RemoveEventAccessor] remove_Click
#-----| 2: (Parameters)
# 101| 0: [Parameter] value
# 103| 7: [Method] M
@@ -254,10 +254,10 @@ definitions.cs:
# 140| 0: [TypeAccess] access to type E*
# 143| 11: [Interface] I4
# 145| 4: [Event] EH
# 145| 3: [RemoveEventAccessor] remove_EH
# 145| 3: [AddEventAccessor] add_EH
#-----| 2: (Parameters)
# 145| 0: [Parameter] value
# 145| 3: [AddEventAccessor] add_EH
# 145| 3: [RemoveEventAccessor] remove_EH
#-----| 2: (Parameters)
# 145| 0: [Parameter] value
# 146| 5: [Method] M

View File

@@ -6,10 +6,10 @@ events.cs:
# 7| 1: [Parameter] e
# 10| 2: [Class] Button
# 13| 5: [Event] Click
# 13| 3: [RemoveEventAccessor] remove_Click
# 13| 3: [AddEventAccessor] add_Click
#-----| 2: (Parameters)
# 13| 0: [Parameter] value
# 13| 3: [AddEventAccessor] add_Click
# 13| 3: [RemoveEventAccessor] remove_Click
#-----| 2: (Parameters)
# 13| 0: [Parameter] value
# 15| 6: [Method] OnClick

View File

@@ -938,10 +938,10 @@ expressions.cs:
# 224| 1: [Parameter] e
# 226| 7: [Class] Button
# 229| 5: [Event] Click
# 229| 3: [RemoveEventAccessor] remove_Click
# 229| 3: [AddEventAccessor] add_Click
#-----| 2: (Parameters)
# 229| 0: [Parameter] value
# 229| 3: [AddEventAccessor] add_Click
# 229| 3: [RemoveEventAccessor] remove_Click
#-----| 2: (Parameters)
# 229| 0: [Parameter] value
# 231| 6: [Method] OnClick

View File

@@ -1,16 +1,60 @@
| A.cs:6:22:6:31 | get_P1 | A.cs:6:22:6:31 | throw ... |
| A.cs:6:22:6:31 | get_P1 | B.cs:5:22:5:22 | 0 |
| A.cs:7:21:7:23 | get_P2 | A.cs:7:25:7:39 | {...} |
| A.cs:7:21:7:23 | get_P2 | B.cs:6:25:6:37 | {...} |
| A.cs:7:41:7:43 | set_P2 | A.cs:7:45:7:59 | {...} |
| A.cs:7:41:7:43 | set_P2 | B.cs:6:43:6:45 | {...} |
| A.cs:8:16:8:16 | M | A.cs:8:23:8:32 | throw ... |
| A.cs:8:16:8:16 | M | B.cs:7:23:7:23 | 2 |
| A.cs:14:31:14:31 | get_Item | A.cs:14:31:14:31 | access to parameter i |
| A.cs:14:31:14:31 | get_Item | B.cs:14:31:14:40 | throw ... |
| A.cs:15:36:15:38 | get_Item | A.cs:15:40:15:52 | {...} |
| A.cs:15:36:15:38 | get_Item | B.cs:15:40:15:54 | {...} |
| A.cs:15:54:15:56 | set_Item | A.cs:15:58:15:60 | {...} |
| A.cs:15:54:15:56 | set_Item | B.cs:15:60:15:62 | {...} |
| A.cs:16:17:16:18 | M1 | A.cs:17:5:19:5 | {...} |
| A.cs:16:17:16:18 | M1 | B.cs:17:5:19:5 | {...} |
| A.cs:18:9:18:22 | M2 | A.cs:18:21:18:21 | 0 |
| A.cs:20:12:20:13 | C2 | A.cs:20:22:20:31 | {...} |
| A.cs:20:12:20:13 | C2 | B.cs:20:22:20:36 | {...} |
| A.cs:21:12:21:13 | C2 | A.cs:21:27:21:29 | {...} |
| A.cs:21:12:21:13 | C2 | B.cs:21:27:21:29 | {...} |
| A.cs:22:6:22:7 | ~C2 | A.cs:22:11:22:13 | {...} |
| A.cs:22:6:22:7 | ~C2 | B.cs:22:11:22:25 | {...} |
| A.cs:23:28:23:35 | implicit conversion | A.cs:23:50:23:53 | null |
| A.cs:23:28:23:35 | implicit conversion | B.cs:23:50:23:59 | throw ... |
| A.cs:30:21:30:23 | get_P3 | A.cs:30:28:30:37 | throw ... |
| A.cs:36:9:36:10 | M1 | A.cs:36:14:36:28 | {...} |
| A.cs:36:9:36:10 | M1 | B.cs:34:17:34:17 | 0 |
| A.cs:37:9:37:10 | M2 | A.cs:37:14:37:28 | {...} |
| A.cs:37:9:37:10 | M2 | C.cs:3:17:3:17 | 0 |
| B.cs:5:22:5:22 | get_P1 | A.cs:6:22:6:31 | throw ... |
| B.cs:5:22:5:22 | get_P1 | B.cs:5:22:5:22 | 0 |
| B.cs:6:21:6:23 | get_P2 | A.cs:7:25:7:39 | {...} |
| B.cs:6:21:6:23 | get_P2 | B.cs:6:25:6:37 | {...} |
| B.cs:6:39:6:41 | set_P2 | A.cs:7:45:7:59 | {...} |
| B.cs:6:39:6:41 | set_P2 | B.cs:6:43:6:45 | {...} |
| B.cs:7:16:7:16 | M | A.cs:8:23:8:32 | throw ... |
| B.cs:7:16:7:16 | M | B.cs:7:23:7:23 | 2 |
| B.cs:14:31:14:40 | get_Item | A.cs:14:31:14:31 | access to parameter i |
| B.cs:14:31:14:40 | get_Item | B.cs:14:31:14:40 | throw ... |
| B.cs:15:36:15:38 | get_Item | A.cs:15:40:15:52 | {...} |
| B.cs:15:36:15:38 | get_Item | B.cs:15:40:15:54 | {...} |
| B.cs:15:56:15:58 | set_Item | A.cs:15:58:15:60 | {...} |
| B.cs:15:56:15:58 | set_Item | B.cs:15:60:15:62 | {...} |
| B.cs:16:17:16:18 | M1 | A.cs:17:5:19:5 | {...} |
| B.cs:16:17:16:18 | M1 | B.cs:17:5:19:5 | {...} |
| B.cs:18:9:18:31 | M2 | B.cs:18:21:18:30 | throw ... |
| B.cs:20:12:20:13 | C2 | A.cs:20:22:20:31 | {...} |
| B.cs:20:12:20:13 | C2 | B.cs:20:22:20:36 | {...} |
| B.cs:21:12:21:13 | C2 | A.cs:21:27:21:29 | {...} |
| B.cs:21:12:21:13 | C2 | B.cs:21:27:21:29 | {...} |
| B.cs:22:6:22:7 | ~C2 | A.cs:22:11:22:13 | {...} |
| B.cs:22:6:22:7 | ~C2 | B.cs:22:11:22:25 | {...} |
| B.cs:23:28:23:35 | implicit conversion | A.cs:23:50:23:53 | null |
| B.cs:23:28:23:35 | implicit conversion | B.cs:23:50:23:59 | throw ... |
| B.cs:29:21:29:23 | get_P3 | A.cs:30:28:30:37 | throw ... |
| B.cs:34:9:34:10 | M1 | A.cs:36:14:36:28 | {...} |
| B.cs:34:9:34:10 | M1 | B.cs:34:17:34:17 | 0 |
| C.cs:3:9:3:10 | M2 | A.cs:37:14:37:28 | {...} |
| C.cs:3:9:3:10 | M2 | C.cs:3:17:3:17 | 0 |

View File

@@ -1,3 +1,11 @@
| A.cs:4:7:4:8 | C1 |
| A.cs:6:16:6:17 | P1 |
| A.cs:6:22:6:31 | get_P1 |
| A.cs:7:16:7:17 | P2 |
| A.cs:7:21:7:23 | get_P2 |
| A.cs:7:41:7:43 | set_P2 |
| A.cs:7:41:7:43 | value |
| A.cs:8:16:8:16 | M |
| A.cs:11:7:11:8 | C2 |
| A.cs:13:16:13:16 | F |
| A.cs:14:16:14:19 | Item |
@@ -24,6 +32,12 @@
| A.cs:24:20:24:22 | get_P |
| A.cs:24:25:24:27 | set_P |
| A.cs:24:25:24:27 | value |
| A.cs:28:7:28:8 | C3 |
| A.cs:30:16:30:17 | P3 |
| A.cs:30:21:30:23 | get_P3 |
| A.cs:34:15:34:16 | C4 |
| A.cs:36:9:36:10 | M1 |
| A.cs:37:9:37:10 | M2 |
| B.cs:3:7:3:8 | C1 |
| B.cs:5:16:5:17 | P1 |
| B.cs:5:22:5:22 | get_P1 |
@@ -32,7 +46,32 @@
| B.cs:6:39:6:41 | set_P2 |
| B.cs:6:39:6:41 | value |
| B.cs:7:16:7:16 | M |
| B.cs:11:7:11:8 | C2 |
| B.cs:13:16:13:16 | F |
| B.cs:14:16:14:19 | Item |
| B.cs:14:25:14:25 | i |
| B.cs:14:25:14:25 | i |
| B.cs:14:31:14:40 | get_Item |
| B.cs:15:19:15:22 | Item |
| B.cs:15:31:15:31 | s |
| B.cs:15:31:15:31 | s |
| B.cs:15:31:15:31 | s |
| B.cs:15:36:15:38 | get_Item |
| B.cs:15:56:15:58 | set_Item |
| B.cs:15:56:15:58 | value |
| B.cs:16:17:16:18 | M1 |
| B.cs:16:24:16:24 | i |
| B.cs:18:9:18:31 | M2 |
| B.cs:20:12:20:13 | C2 |
| B.cs:20:19:20:19 | i |
| B.cs:21:12:21:13 | C2 |
| B.cs:22:6:22:7 | ~C2 |
| B.cs:23:28:23:35 | implicit conversion |
| B.cs:23:44:23:44 | i |
| B.cs:24:16:24:16 | P |
| B.cs:24:20:24:22 | get_P |
| B.cs:24:25:24:27 | set_P |
| B.cs:24:25:24:27 | value |
| B.cs:27:7:27:8 | C3 |
| B.cs:29:16:29:17 | P3 |
| B.cs:29:21:29:23 | get_P3 |

View File

@@ -1,31 +0,0 @@
| A.cs:14:31:14:31 | get_Item | A.cs:14:31:14:31 | access to parameter i |
| A.cs:14:31:14:31 | get_Item | B.cs:14:31:14:40 | throw ... |
| A.cs:15:36:15:38 | get_Item | A.cs:15:40:15:52 | {...} |
| A.cs:15:36:15:38 | get_Item | B.cs:15:40:15:54 | {...} |
| A.cs:15:54:15:56 | set_Item | A.cs:15:58:15:60 | {...} |
| A.cs:15:54:15:56 | set_Item | B.cs:15:60:15:62 | {...} |
| A.cs:16:17:16:18 | M1 | A.cs:17:5:19:5 | {...} |
| A.cs:16:17:16:18 | M1 | B.cs:17:5:19:5 | {...} |
| A.cs:18:9:18:22 | M2 | A.cs:18:21:18:21 | 0 |
| A.cs:20:12:20:13 | C2 | A.cs:20:22:20:31 | {...} |
| A.cs:20:12:20:13 | C2 | B.cs:20:22:20:36 | {...} |
| A.cs:21:12:21:13 | C2 | A.cs:21:27:21:29 | {...} |
| A.cs:21:12:21:13 | C2 | B.cs:21:27:21:29 | {...} |
| A.cs:22:6:22:7 | ~C2 | A.cs:22:11:22:13 | {...} |
| A.cs:22:6:22:7 | ~C2 | B.cs:22:11:22:25 | {...} |
| A.cs:23:28:23:35 | implicit conversion | A.cs:23:50:23:53 | null |
| A.cs:23:28:23:35 | implicit conversion | B.cs:23:50:23:59 | throw ... |
| B.cs:5:22:5:22 | get_P1 | A.cs:6:22:6:31 | throw ... |
| B.cs:5:22:5:22 | get_P1 | B.cs:5:22:5:22 | 0 |
| B.cs:6:21:6:23 | get_P2 | A.cs:7:25:7:39 | {...} |
| B.cs:6:21:6:23 | get_P2 | B.cs:6:25:6:37 | {...} |
| B.cs:6:39:6:41 | set_P2 | A.cs:7:45:7:59 | {...} |
| B.cs:6:39:6:41 | set_P2 | B.cs:6:43:6:45 | {...} |
| B.cs:7:16:7:16 | M | A.cs:8:23:8:32 | throw ... |
| B.cs:7:16:7:16 | M | B.cs:7:23:7:23 | 2 |
| B.cs:18:9:18:31 | M2 | B.cs:18:21:18:30 | throw ... |
| B.cs:29:21:29:23 | get_P3 | A.cs:30:28:30:37 | throw ... |
| B.cs:34:9:34:10 | M1 | A.cs:36:14:36:28 | {...} |
| B.cs:34:9:34:10 | M1 | B.cs:34:17:34:17 | 0 |
| C.cs:3:9:3:10 | M2 | A.cs:37:14:37:28 | {...} |
| C.cs:3:9:3:10 | M2 | C.cs:3:17:3:17 | 0 |

View File

@@ -1,4 +0,0 @@
import csharp
from Callable c
select c, c.getABody()

View File

@@ -1 +1,4 @@
| A.cs:14:16:14:19 | Item | A.cs:14:31:14:31 | access to parameter i |
| A.cs:14:16:14:19 | Item | B.cs:14:31:14:40 | throw ... |
| B.cs:14:16:14:19 | Item | A.cs:14:31:14:31 | access to parameter i |
| B.cs:14:16:14:19 | Item | B.cs:14:31:14:40 | throw ... |

View File

@@ -1,60 +0,0 @@
| C2 | A.cs:20:12:20:13 | A.cs:20:12:20:13 |
| C2 | A.cs:21:12:21:13 | A.cs:21:12:21:13 |
| C2 | B.cs:20:12:20:13 | B.cs:20:12:20:13 |
| C2 | B.cs:21:12:21:13 | B.cs:21:12:21:13 |
| F | A.cs:13:16:13:16 | A.cs:13:16:13:16 |
| F | B.cs:13:16:13:16 | B.cs:13:16:13:16 |
| F | test.dll:0:0:0:0 | test, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null |
| Item | A.cs:14:16:14:19 | A.cs:14:16:14:19 |
| Item | B.cs:14:16:14:19 | B.cs:14:16:14:19 |
| Item | test.dll:0:0:0:0 | test, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null |
| M | A.cs:8:16:8:16 | A.cs:8:16:8:16 |
| M | B.cs:7:16:7:16 | B.cs:7:16:7:16 |
| M | test.dll:0:0:0:0 | test, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null |
| M1 | A.cs:16:17:16:18 | A.cs:16:17:16:18 |
| M1 | A.cs:36:9:36:10 | A.cs:36:9:36:10 |
| M1 | B.cs:16:17:16:18 | B.cs:16:17:16:18 |
| M1 | B.cs:34:9:34:10 | B.cs:34:9:34:10 |
| M1 | test.dll:0:0:0:0 | test, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null |
| M2 | A.cs:37:9:37:10 | A.cs:37:9:37:10 |
| M2 | C.cs:3:9:3:10 | C.cs:3:9:3:10 |
| M2 | test.dll:0:0:0:0 | test, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null |
| P | A.cs:24:16:24:16 | A.cs:24:16:24:16 |
| P | B.cs:24:16:24:16 | B.cs:24:16:24:16 |
| P | test.dll:0:0:0:0 | test, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null |
| P1 | A.cs:6:16:6:17 | A.cs:6:16:6:17 |
| P1 | B.cs:5:16:5:17 | B.cs:5:16:5:17 |
| P1 | test.dll:0:0:0:0 | test, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null |
| get_Item | A.cs:14:31:14:31 | A.cs:14:31:14:31 |
| get_Item | A.cs:15:36:15:38 | A.cs:15:36:15:38 |
| get_Item | B.cs:14:31:14:40 | B.cs:14:31:14:40 |
| get_Item | B.cs:15:36:15:38 | B.cs:15:36:15:38 |
| get_Item | test.dll:0:0:0:0 | test, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null |
| get_P | A.cs:24:20:24:22 | A.cs:24:20:24:22 |
| get_P | B.cs:24:20:24:22 | B.cs:24:20:24:22 |
| get_P | test.dll:0:0:0:0 | test, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null |
| get_P1 | A.cs:6:22:6:31 | A.cs:6:22:6:31 |
| get_P1 | B.cs:5:22:5:22 | B.cs:5:22:5:22 |
| get_P1 | test.dll:0:0:0:0 | test, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null |
| get_P2 | A.cs:7:21:7:23 | A.cs:7:21:7:23 |
| get_P2 | B.cs:6:21:6:23 | B.cs:6:21:6:23 |
| get_P2 | test.dll:0:0:0:0 | test, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null |
| get_P3 | A.cs:30:21:30:23 | A.cs:30:21:30:23 |
| get_P3 | B.cs:29:21:29:23 | B.cs:29:21:29:23 |
| get_P3 | test.dll:0:0:0:0 | test, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null |
| i | A.cs:16:24:16:24 | A.cs:16:24:16:24 |
| i | B.cs:16:24:16:24 | B.cs:16:24:16:24 |
| implicit conversion | A.cs:23:28:23:35 | A.cs:23:28:23:35 |
| implicit conversion | B.cs:23:28:23:35 | B.cs:23:28:23:35 |
| implicit conversion | test.dll:0:0:0:0 | test, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null |
| set_Item | A.cs:15:54:15:56 | A.cs:15:54:15:56 |
| set_Item | B.cs:15:56:15:58 | B.cs:15:56:15:58 |
| set_Item | test.dll:0:0:0:0 | test, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null |
| set_P | A.cs:24:25:24:27 | A.cs:24:25:24:27 |
| set_P | B.cs:24:25:24:27 | B.cs:24:25:24:27 |
| set_P | test.dll:0:0:0:0 | test, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null |
| set_P2 | A.cs:7:41:7:43 | A.cs:7:41:7:43 |
| set_P2 | B.cs:6:39:6:41 | B.cs:6:39:6:41 |
| set_P2 | test.dll:0:0:0:0 | test, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null |
| ~C2 | A.cs:22:6:22:7 | A.cs:22:6:22:7 |
| ~C2 | B.cs:22:6:22:7 | B.cs:22:6:22:7 |

View File

@@ -1,5 +0,0 @@
import csharp
import semmle.code.csharp.ExprOrStmtParent
from MultiImplementationsParent p
select p.toString(), p.getALocation()

View File

@@ -1 +1,4 @@
| A.cs:16:24:16:24 | i | A.cs:16:28:16:28 | 0 |
| A.cs:16:24:16:24 | i | B.cs:16:28:16:28 | 1 |
| B.cs:16:24:16:24 | i | A.cs:16:28:16:28 | 0 |
| B.cs:16:24:16:24 | i | B.cs:16:28:16:28 | 1 |

View File

@@ -1,2 +1,8 @@
| A.cs:6:16:6:17 | P1 | A.cs:6:22:6:31 | throw ... | body |
| A.cs:6:16:6:17 | P1 | B.cs:5:22:5:22 | 0 | body |
| A.cs:24:16:24:16 | P | A.cs:24:34:24:34 | 0 | initializer |
| A.cs:24:16:24:16 | P | B.cs:24:34:24:34 | 1 | initializer |
| B.cs:5:16:5:17 | P1 | A.cs:6:22:6:31 | throw ... | body |
| B.cs:5:16:5:17 | P1 | B.cs:5:22:5:22 | 0 | body |
| B.cs:24:16:24:16 | P | A.cs:24:34:24:34 | 0 | initializer |
| B.cs:24:16:24:16 | P | B.cs:24:34:24:34 | 1 | initializer |

View File

@@ -0,0 +1,2 @@
| A.cs:5:12:5:13 | M1 | This method has multiple bodies. |
| B.cs:5:12:5:13 | M1 | This method has multiple bodies. |

View File

@@ -1 +1,2 @@
| A.cs:3:7:3:7 | C |
| B.cs:3:7:3:7 | C |

View File

@@ -1,2 +1,4 @@
| A.cs:5:12:5:13 | M1 |
| A.cs:6:10:6:11 | M2 |
| B.cs:5:12:5:13 | M1 |
| B.cs:6:10:6:11 | M3 |

View File

@@ -87,7 +87,7 @@ class WhileIs
void Test()
{
object x = null;
while(x is string s)
while (x is string s)
{
var y = s;
}
@@ -116,7 +116,7 @@ class LiteralConversions
void F()
{
new Point { x=1, y=2 };
new Point { x = 1, y = 2 };
}
}
@@ -130,20 +130,20 @@ class DynamicType
class LocalVariableTags
{
Func<int, int> F = x => { int y=x; return y; };
Func<int, int> F = x => { int y = x; return y; };
private static Func<object, string, object> _getter => (o, n) =>
{
object x = o;
return x;
object x = o;
return x;
};
}
partial class C1<T> where T: DynamicType
partial class C1<T> where T : DynamicType
{
}
partial class C1<T> where T: DynamicType
partial class C1<T> where T : DynamicType
{
}
@@ -173,8 +173,8 @@ class UsingDiscard
{
void F()
{
foreach(var _ in new IDisposable[] { })
using(_)
foreach (var _ in new IDisposable[] { })
using (_)
{
}
}
@@ -189,4 +189,12 @@ class TupleMatching
}
}
class C2<T> { }
class C3<T> : C2<C4<T>> { }
class C4<T> : C2<C3<T>> { }
class C5 : C4<C5> { }
// semmle-extractor-options: /r:System.Dynamic.Runtime.dll

View File

@@ -41,7 +41,7 @@
| Program.cs:75:5:75:7 | Int32 |
| Program.cs:87:5:87:8 | Void |
| Program.cs:89:9:89:14 | Object |
| Program.cs:90:20:90:25 | String |
| Program.cs:90:21:90:26 | String |
| Program.cs:92:13:92:15 | String |
| Program.cs:101:16:101:21 | Object |
| Program.cs:104:5:104:8 | Void |
@@ -63,11 +63,11 @@
| Program.cs:135:25:135:30 | Object |
| Program.cs:135:33:135:38 | String |
| Program.cs:135:41:135:46 | Object |
| Program.cs:137:10:137:15 | Object |
| Program.cs:137:9:137:14 | Object |
| Program.cs:142:27:142:27 | T |
| Program.cs:142:30:142:40 | DynamicType |
| Program.cs:142:31:142:41 | DynamicType |
| Program.cs:146:27:146:27 | T |
| Program.cs:146:30:146:40 | DynamicType |
| Program.cs:146:31:146:41 | DynamicType |
| Program.cs:156:15:156:35 | TEmbeddedTypesManager |
| Program.cs:156:39:156:58 | EmbeddedTypesManager<,> |
| Program.cs:156:60:156:80 | TEmbeddedTypesManager |
@@ -81,7 +81,7 @@
| Program.cs:164:5:164:12 | Int32*[][] |
| Program.cs:169:5:169:10 | String |
| Program.cs:174:5:174:8 | Void |
| Program.cs:176:17:176:19 | IDisposable |
| Program.cs:176:18:176:20 | IDisposable |
| Program.cs:185:5:185:17 | (Int32,Object) |
| Program.cs:185:6:185:8 | Int32 |
| Program.cs:185:11:185:16 | Object |
@@ -91,3 +91,11 @@
| Program.cs:187:9:187:25 | Nullable<(Object,Object)> |
| Program.cs:187:10:187:15 | Object |
| Program.cs:187:18:187:23 | Object |
| Program.cs:194:15:194:16 | C2<C4<T>> |
| Program.cs:194:18:194:19 | C4<T> |
| Program.cs:194:21:194:21 | T |
| Program.cs:196:15:196:16 | C2<C3<T>> |
| Program.cs:196:18:196:19 | C3<T> |
| Program.cs:196:21:196:21 | T |
| Program.cs:198:12:198:13 | C4<C5> |
| Program.cs:198:15:198:16 | C5 |