internal static void VerifyLocal( CompilationTestData testData, string typeName, LocalAndMethod localAndMethod, string expectedMethodName, string expectedLocalName, string expectedLocalDisplayName = null, DkmClrCompilationResultFlags expectedFlags = DkmClrCompilationResultFlags.None, string expectedILOpt = null, bool expectedGeneric = false, [CallerFilePath] string expectedValueSourcePath = null, [CallerLineNumber] int expectedValueSourceLine = 0) { ExpressionCompilerTestHelpers.VerifyLocal <MethodSymbol>( testData, typeName, localAndMethod, expectedMethodName, expectedLocalName, expectedLocalDisplayName ?? expectedLocalName, expectedFlags, VerifyTypeParameters, expectedILOpt, expectedGeneric, expectedValueSourcePath, expectedValueSourceLine); }
public LocalAndMethod(string localName, string localDisplayName, string methodName, DkmClrCompilationResultFlags flags) { this.LocalName = localName; this.LocalDisplayName = localDisplayName; this.MethodName = methodName; this.Flags = flags; }
internal static void VerifyLocal <TMethodSymbol>( this CompilationTestData testData, string typeName, LocalAndMethod localAndMethod, string expectedMethodName, string expectedLocalName, string expectedLocalDisplayName, DkmClrCompilationResultFlags expectedFlags, Action <TMethodSymbol> verifyTypeParameters, string expectedILOpt, bool expectedGeneric, string expectedValueSourcePath, int expectedValueSourceLine) where TMethodSymbol : IMethodSymbol { Assert.Equal(expectedLocalName, localAndMethod.LocalName); Assert.Equal(expectedLocalDisplayName, localAndMethod.LocalDisplayName); Assert.True(expectedMethodName.StartsWith(localAndMethod.MethodName, StringComparison.Ordinal), expectedMethodName + " does not start with " + localAndMethod.MethodName); // Expected name may include type arguments and parameters. Assert.Equal(expectedFlags, localAndMethod.Flags); var methodData = testData.GetMethodData(typeName + "." + expectedMethodName); verifyTypeParameters((TMethodSymbol)methodData.Method); if (expectedILOpt != null) { string actualIL = methodData.GetMethodIL(); AssertEx.AssertEqualToleratingWhitespaceDifferences( expectedILOpt, actualIL, escapeQuotes: true, expectedValueSourcePath: expectedValueSourcePath, expectedValueSourceLine: expectedValueSourceLine); } Assert.Equal(((Cci.IMethodDefinition)methodData.Method).CallingConvention, expectedGeneric ? Cci.CallingConvention.Generic : Cci.CallingConvention.Default); }
public LocalAndMethod(string localName, string localDisplayName, string methodName, DkmClrCompilationResultFlags flags) { this.LocalName = localName; this.LocalDisplayName = localDisplayName; this.MethodName = methodName; this.Flags = flags; }
/// <remarks> /// For statements and assignments, we are only interested in <see cref="DkmClrCompilationResultFlags"/>. /// </remarks> public ResultProperties(DkmClrCompilationResultFlags flags) : this( flags, default(DkmEvaluationResultCategory), default(DkmEvaluationResultAccessType), default(DkmEvaluationResultStorageType), default(DkmEvaluationResultTypeModifierFlags)) { }
/// <remarks> /// For statements and assignments, we are only interested in <see cref="DkmClrCompilationResultFlags"/>. /// </remarks> public ResultProperties(DkmClrCompilationResultFlags flags) : this( flags, default(DkmEvaluationResultCategory), default(DkmEvaluationResultAccessType), default(DkmEvaluationResultStorageType), default(DkmEvaluationResultTypeModifierFlags)) { }
private void MaybeGenerateEntryForSymbol(Symbol symbol) { if (_context.ArgumentsOnly && symbol.StorageClass != StorageClass.Argument) { // We are only showing arguments return; } IrisType symbolType = symbol.Type; if (symbolType.IsMethod || symbolType == IrisType.Invalid || symbolType == IrisType.Void) { // This symbol doesn't belong in the Locals window. // Don't generate an entry for it. return; } if (symbol.Name.StartsWith("$.")) { // Don't show compiler internal symbols return; } string methodName = _context.NextMethodName(); IrisType derefType = DerefType(symbolType); // Emit code for the method to get the symbol value. MethodGenerator.BeginMethod(methodName, derefType, _context.ParameterVariables, _context.LocalVariables, entryPoint: false, methodFileName: null); EmitLoadSymbol(symbol, SymbolLoadMode.Dereference); MethodGenerator.EndMethod(); // Generate the local entry to pass back to the debug engine DkmClrCompilationResultFlags resultFlags = DkmClrCompilationResultFlags.None; if (derefType == IrisType.Boolean) { // The debugger uses "BoolResult" for breakpoint conditions so setting the flag // here has no effect currently, but we set it for the sake of consistency. resultFlags |= DkmClrCompilationResultFlags.BoolResult; } else if (derefType.IsArray) { // Iris doesn't support modification of an array itself resultFlags |= DkmClrCompilationResultFlags.ReadOnlyResult; } string fullName = symbol.Name; _context.GeneratedLocals.Add(DkmClrLocalVariableInfo.Create( fullName, fullName, methodName, resultFlags, DkmEvaluationResultCategory.Data, null)); }
/// <remarks> /// For statements and assignments, we are only interested in <see cref="DkmClrCompilationResultFlags"/>. /// </remarks> public ResultProperties(DkmClrCompilationResultFlags flags) : this( flags, category : default, accessType : default, storageType : default, modifierFlags : default ) { }
public CSharpLocalAndMethod( string name, string displayName, MethodSymbol method, DkmClrCompilationResultFlags flags ) : base(name, displayName, method.Name, flags) { Debug.Assert(method is EEMethodSymbol); // Expected but not required. _method = method; }
public ResultProperties( DkmClrCompilationResultFlags flags, DkmEvaluationResultCategory category, DkmEvaluationResultAccessType accessType, DkmEvaluationResultStorageType storageType, DkmEvaluationResultTypeModifierFlags modifierFlags) { Flags = flags; Category = category; AccessType = accessType; StorageType = storageType; ModifierFlags = modifierFlags; }
public ResultProperties( DkmClrCompilationResultFlags flags, DkmEvaluationResultCategory category, DkmEvaluationResultAccessType accessType, DkmEvaluationResultStorageType storageType, DkmEvaluationResultTypeModifierFlags modifierFlags) { this.Flags = flags; this.Category = category; this.AccessType = accessType; this.StorageType = storageType; this.ModifierFlags = modifierFlags; }
internal static ResultProperties GetResultProperties <TSymbol>( this TSymbol?symbol, DkmClrCompilationResultFlags flags, bool isConstant ) where TSymbol : class, ISymbolInternal { var category = (symbol != null) ? GetResultCategory(symbol.Kind) : DkmEvaluationResultCategory.Data; var accessType = (symbol != null) ? GetResultAccessType(symbol.DeclaredAccessibility) : DkmEvaluationResultAccessType.None; var storageType = (symbol != null) && symbol.IsStatic ? DkmEvaluationResultStorageType.Static : DkmEvaluationResultStorageType.None; var modifierFlags = DkmEvaluationResultTypeModifierFlags.None; if (isConstant) { modifierFlags = DkmEvaluationResultTypeModifierFlags.Constant; } else if (symbol is null) { // No change. } else if (symbol.IsVirtual || symbol.IsAbstract || symbol.IsOverride) { modifierFlags = DkmEvaluationResultTypeModifierFlags.Virtual; } else if (symbol.Kind == SymbolKind.Field && ((IFieldSymbolInternal)symbol).IsVolatile) { modifierFlags = DkmEvaluationResultTypeModifierFlags.Volatile; } // CONSIDER: for completeness, we could check for [MethodImpl(MethodImplOptions.Synchronized)] // and set DkmEvaluationResultTypeModifierFlags.Synchronized, but it doesn't seem to have any // impact on the UI. It is exposed through the DTE, but cscompee didn't set the flag either. return(new ResultProperties(flags, category, accessType, storageType, modifierFlags)); }
public CSharpLocalAndMethod(string name, string displayName, MethodSymbol method, DkmClrCompilationResultFlags flags) : base(name, displayName, method.Name, flags) { Debug.Assert(method is EEMethodSymbol); // Expected but not required. _method = method; }
private static LocalAndMethod MakeLocalAndMethod(LocalSymbol local, MethodSymbol method, DkmClrCompilationResultFlags flags) { // Note: The native EE doesn't do this, but if we don't escape keyword identifiers, // the ResultProvider needs to be able to disambiguate cases like "this" and "@this", // which it can't do correctly without semantic information. var escapedName = SyntaxHelpers.EscapeKeywordIdentifiers(local.Name); var displayName = (local as PlaceholderLocalSymbol)?.DisplayName ?? escapedName; return new CSharpLocalAndMethod(escapedName, displayName, method, flags); }
private void AppendLocalAndMethod( ArrayBuilder<LocalAndMethod> localBuilder, ArrayBuilder<MethodSymbol> methodBuilder, LocalSymbol local, EENamedTypeSymbol container, int localIndex, DkmClrCompilationResultFlags resultFlags) { var methodName = GetNextMethodName(methodBuilder); var method = this.GetLocalMethod(container, methodName, local.Name, localIndex); localBuilder.Add(MakeLocalAndMethod(local, method, resultFlags)); methodBuilder.Add(method); }
private static void CheckResultFlags(EvaluationContext context, string expr, DkmClrCompilationResultFlags expectedFlags, string expectedError = null) { ResultProperties resultProperties; string error; var testData = new CompilationTestData(); var result = context.CompileExpression(expr, out resultProperties, out error, testData); Assert.Equal(expectedError, error); Assert.NotEqual(expectedError == null, result == null); Assert.Equal(expectedFlags, resultProperties.Flags); }
internal static void VerifyLocal( CompilationTestData testData, string typeName, LocalAndMethod localAndMethod, string expectedMethodName, string expectedLocalName, string expectedLocalDisplayName = null, DkmClrCompilationResultFlags expectedFlags = DkmClrCompilationResultFlags.None, string expectedILOpt = null, bool expectedGeneric = false, [CallerFilePath]string expectedValueSourcePath = null, [CallerLineNumber]int expectedValueSourceLine = 0) { ExpressionCompilerTestHelpers.VerifyLocal<MethodSymbol>( testData, typeName, localAndMethod, expectedMethodName, expectedLocalName, expectedLocalDisplayName ?? expectedLocalName, expectedFlags, VerifyTypeParameters, expectedILOpt, expectedGeneric, expectedValueSourcePath, expectedValueSourceLine); }
private static void CompileDeclaration(EvaluationContext context, string declaration, out DkmClrCompilationResultFlags flags, out CompilationTestData testData) { testData = new CompilationTestData(); ResultProperties resultProperties; string error; ImmutableArray<AssemblyIdentity> missingAssemblyIdentities; var result = context.CompileExpression( declaration, DkmEvaluationFlags.None, NoAliases, DebuggerDiagnosticFormatter.Instance, out resultProperties, out error, out missingAssemblyIdentities, EnsureEnglishUICulture.PreferredOrNull, testData); Assert.Null(error); Assert.Empty(missingAssemblyIdentities); flags = resultProperties.Flags; }
private static void CompileDeclaration(EvaluationContext context, string declaration, out DkmClrCompilationResultFlags flags, out CompilationTestData testData) { testData = new CompilationTestData(); ResultProperties resultProperties; string error; ImmutableArray <AssemblyIdentity> missingAssemblyIdentities; var result = context.CompileExpression( declaration, DkmEvaluationFlags.None, NoAliases, DiagnosticFormatter.Instance, out resultProperties, out error, out missingAssemblyIdentities, EnsureEnglishUICulture.PreferredOrNull, testData); Assert.Null(error); Assert.Empty(missingAssemblyIdentities); flags = resultProperties.Flags; }
private static void AppendLocalAndMethod( ArrayBuilder<LocalAndMethod> localBuilder, ArrayBuilder<MethodSymbol> methodBuilder, string name, Func<EENamedTypeSymbol, string, string, int, MethodSymbol> getMethod, EENamedTypeSymbol container, int localOrParameterIndex, DkmClrCompilationResultFlags resultFlags) { // Note: The native EE doesn't do this, but if we don't escape keyword identifiers, // the ResultProvider needs to be able to disambiguate cases like "this" and "@this", // which it can't do correctly without semantic information. name = SyntaxHelpers.EscapeKeywordIdentifiers(name); var methodName = GetNextMethodName(methodBuilder); var method = getMethod(container, methodName, name, localOrParameterIndex); localBuilder.Add(new CSharpLocalAndMethod(name, method, resultFlags)); methodBuilder.Add(method); }