internal static LocalSymbol Create( TypeNameDecoder<PEModuleSymbol, TypeSymbol> typeNameDecoder, MethodSymbol containingMethod, AssemblySymbol sourceAssembly, Alias alias) { var typeName = alias.Type; Debug.Assert(typeName.Length > 0); var type = typeNameDecoder.GetTypeSymbolForSerializedType(typeName); Debug.Assert((object)type != null); var dynamicFlagsInfo = alias.CustomTypeInfo.ToDynamicFlagsCustomTypeInfo(); if (dynamicFlagsInfo.Any()) { var flagsBuilder = ArrayBuilder<bool>.GetInstance(); dynamicFlagsInfo.CopyTo(flagsBuilder); var dynamicType = DynamicTypeDecoder.TransformTypeWithoutCustomModifierFlags( type, sourceAssembly, RefKind.None, flagsBuilder.ToImmutableAndFree(), checkLength: false); Debug.Assert(dynamicType != null); Debug.Assert(dynamicType != type); type = dynamicType; } var name = alias.FullName; var displayName = alias.Name; switch (alias.Kind) { case DkmClrAliasKind.Exception: return new ExceptionLocalSymbol(containingMethod, name, displayName, type, ExpressionCompilerConstants.GetExceptionMethodName); case DkmClrAliasKind.StowedException: return new ExceptionLocalSymbol(containingMethod, name, displayName, type, ExpressionCompilerConstants.GetStowedExceptionMethodName); case DkmClrAliasKind.ReturnValue: { int index; PseudoVariableUtilities.TryParseReturnValueIndex(name, out index); Debug.Assert(index >= 0); return new ReturnValueLocalSymbol(containingMethod, name, displayName, type, index); } case DkmClrAliasKind.ObjectId: return new ObjectIdLocalSymbol(containingMethod, type, name, displayName, isWritable: false); case DkmClrAliasKind.Variable: return new ObjectIdLocalSymbol(containingMethod, type, name, displayName, isWritable: true); default: throw ExceptionUtilities.UnexpectedValue(alias.Kind); } }
internal static LocalSymbol Create( TypeNameDecoder<PEModuleSymbol, TypeSymbol> typeNameDecoder, MethodSymbol containingMethod, AssemblySymbol sourceAssembly, Alias alias) { var typeName = alias.Type; Debug.Assert(typeName.Length > 0); var type = typeNameDecoder.GetTypeSymbolForSerializedType(typeName); Debug.Assert((object)type != null); ReadOnlyCollection<byte> dynamicFlags; ReadOnlyCollection<string> tupleElementNames; CustomTypeInfo.Decode(alias.CustomTypeInfoId, alias.CustomTypeInfo, out dynamicFlags, out tupleElementNames); if (dynamicFlags != null) { type = DecodeDynamicTypes(type, sourceAssembly, dynamicFlags); } if (tupleElementNames != null) { type = TupleTypeDecoder.DecodeTupleTypesIfApplicable(type, sourceAssembly, tupleElementNames.AsImmutable()); } var name = alias.FullName; var displayName = alias.Name; switch (alias.Kind) { case DkmClrAliasKind.Exception: return new ExceptionLocalSymbol(containingMethod, name, displayName, type, ExpressionCompilerConstants.GetExceptionMethodName); case DkmClrAliasKind.StowedException: return new ExceptionLocalSymbol(containingMethod, name, displayName, type, ExpressionCompilerConstants.GetStowedExceptionMethodName); case DkmClrAliasKind.ReturnValue: { int index; PseudoVariableUtilities.TryParseReturnValueIndex(name, out index); Debug.Assert(index >= 0); return new ReturnValueLocalSymbol(containingMethod, name, displayName, type, index); } case DkmClrAliasKind.ObjectId: return new ObjectIdLocalSymbol(containingMethod, type, name, displayName, isWritable: false); case DkmClrAliasKind.Variable: return new ObjectIdLocalSymbol(containingMethod, type, name, displayName, isWritable: true); default: throw ExceptionUtilities.UnexpectedValue(alias.Kind); } }
public void Alias() { var source = @"class C { static (int, int) F; static void M() { } }"; var comp = CreateCompilationWithMscorlib(source, new[] { ValueTupleRef }, options: TestOptions.DebugDll); WithRuntimeInstance(comp, runtime => { var context = CreateMethodContext( runtime, "C.M"); // (int A, (int, int D) B)[] t; var aliasElementNames = new ReadOnlyCollection<string>(new[] { "A", "B", null, "D" }); var alias = new Alias( DkmClrAliasKind.Variable, "t", "t", "System.ValueTuple`2[[System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.ValueTuple`2[[System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]], System.ValueTuple, Version=4.0.1.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51]][], System.ValueTuple, Version=4.0.1.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51", CustomTypeInfo.PayloadTypeId, CustomTypeInfo.Encode(null, aliasElementNames)); var locals = ArrayBuilder<LocalAndMethod>.GetInstance(); string typeName; var diagnostics = DiagnosticBag.GetInstance(); var testData = new CompilationTestData(); context.CompileGetLocals( locals, argumentsOnly: false, aliases: ImmutableArray.Create(alias), diagnostics: diagnostics, typeName: out typeName, testData: testData); diagnostics.Verify(); diagnostics.Free(); Assert.Equal(locals.Count, 1); ReadOnlyCollection<byte> customTypeInfo; var customTypeInfoId = locals[0].GetCustomTypeInfo(out customTypeInfo); ReadOnlyCollection<byte> dynamicFlags; ReadOnlyCollection<string> tupleElementNames; CustomTypeInfo.Decode(customTypeInfoId, customTypeInfo, out dynamicFlags, out tupleElementNames); Assert.Equal(aliasElementNames, tupleElementNames); var method = testData.Methods.Single().Value.Method; Assert.NotNull(GetTupleElementNamesAttributeIfAny(method)); var returnType = (TypeSymbol)method.ReturnType; Assert.False(returnType.IsTupleType); Assert.True(((ArrayTypeSymbol)returnType).ElementType.IsTupleType); VerifyLocal(testData, typeName, locals[0], "<>m0", "t", expectedILOpt: @"{ // Code size 16 (0x10) .maxstack 1 IL_0000: ldstr ""t"" IL_0005: call ""object Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.GetObjectByAlias(string)"" IL_000a: castclass ""(int A, (int, int D) B)[]"" IL_000f: ret }"); locals.Free(); }); }