提交 5ea86ba0 编写于 作者: A Andrew Casey

Address PR feedback

Move aliases out of ```EvaluationContext``` so that they don't interfere with our caching strategy.

Clean up the overall diff.
上级 d5ae74b7
......@@ -5,7 +5,10 @@
using System.Collections.Immutable;
using System.Globalization;
using Microsoft.CodeAnalysis.CSharp.Symbols;
using Microsoft.CodeAnalysis.CSharp.Symbols.Metadata.PE;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.ExpressionEvaluator;
using Microsoft.VisualStudio.Debugger.Clr;
using Roslyn.Utilities;
namespace Microsoft.CodeAnalysis.CSharp.ExpressionEvaluator
......@@ -13,19 +16,42 @@ namespace Microsoft.CodeAnalysis.CSharp.ExpressionEvaluator
internal sealed class PlaceholderLocalBinder : LocalScopeBinder
{
private readonly CSharpSyntaxNode _syntax;
private readonly ImmutableArray<LocalSymbol> _aliasLocals;
private readonly ImmutableArray<LocalSymbol> _aliases;
private readonly MethodSymbol _containingMethod;
private readonly ImmutableDictionary<string, LocalSymbol> _lowercaseReturnValueAliases;
internal PlaceholderLocalBinder(
CSharpSyntaxNode syntax,
ImmutableArray<LocalSymbol> aliasLocals,
ImmutableArray<Alias> aliases,
MethodSymbol containingMethod,
EETypeNameDecoder typeNameDecoder,
Binder next) :
base(next)
{
_syntax = syntax;
_aliasLocals = aliasLocals;
_containingMethod = containingMethod;
var compilation = next.Compilation;
var sourceAssembly = compilation.SourceAssembly;
var aliasesBuilder = ArrayBuilder<LocalSymbol>.GetInstance(aliases.Length);
var lowercaseBuilder = ImmutableDictionary.CreateBuilder<string, LocalSymbol>();
foreach (Alias alias in aliases)
{
var local = PlaceholderLocalSymbol.Create(
typeNameDecoder,
containingMethod,
sourceAssembly,
alias);
aliasesBuilder.Add(local);
if (alias.Kind == DkmClrAliasKind.ReturnValue)
{
lowercaseBuilder.Add(local.Name.ToLower(), local);
}
}
_lowercaseReturnValueAliases = lowercaseBuilder.ToImmutableDictionary();
_aliases = aliasesBuilder.ToImmutableAndFree();
}
internal sealed override void LookupSymbolsInSingleBinder(
......@@ -57,7 +83,15 @@ internal sealed class PlaceholderLocalBinder : LocalScopeBinder
}
else
{
base.LookupSymbolsInSingleBinder(result, name, arity, basesBeingResolved, options, originalBinder, diagnose, ref useSiteDiagnostics);
LocalSymbol lowercaseReturnValueAlias;
if (_lowercaseReturnValueAliases.TryGetValue(name, out lowercaseReturnValueAlias))
{
result.MergeEqual(this.CheckViability(lowercaseReturnValueAlias, arity, options, null, diagnose, ref useSiteDiagnostics, basesBeingResolved));
}
else
{
base.LookupSymbolsInSingleBinder(result, name, arity, basesBeingResolved, options, originalBinder, diagnose, ref useSiteDiagnostics);
}
}
}
......@@ -69,7 +103,7 @@ protected sealed override void AddLookupSymbolsInfoInSingleBinder(LookupSymbolsI
protected override ImmutableArray<LocalSymbol> BuildLocals()
{
var builder = ArrayBuilder<LocalSymbol>.GetInstance();
builder.AddRange(_aliasLocals);
builder.AddRange(_aliases);
var declaration = _syntax as LocalDeclarationStatementSyntax;
if (declaration != null)
{
......
......@@ -4,7 +4,6 @@
using System.Collections.Immutable;
using System.Diagnostics;
using Microsoft.CodeAnalysis.ExpressionEvaluator;
using Microsoft.VisualStudio.Debugger;
using Microsoft.VisualStudio.Debugger.Clr;
using Microsoft.VisualStudio.Debugger.Evaluation;
......@@ -62,7 +61,6 @@ internal override DkmCompilerId CompilerId
internal override EvaluationContextBase CreateMethodContext(
DkmClrAppDomain appDomain,
ImmutableArray<MetadataBlock> metadataBlocks,
ImmutableArray<Alias> aliases,
Lazy<ImmutableArray<AssemblyReaders>> unusedLazyAssemblyReaders,
object symReader,
Guid moduleVersionId,
......@@ -79,7 +77,6 @@ internal override DkmCompilerId CompilerId
var compilation = metadataBlocks.ToCompilationReferencedModulesOnly(moduleVersionId);
return EvaluationContext.CreateMethodContext(
compilation,
aliases,
symReader,
moduleVersionId,
methodToken,
......@@ -92,7 +89,6 @@ internal override DkmCompilerId CompilerId
var context = EvaluationContext.CreateMethodContext(
previous,
metadataBlocks,
aliases,
symReader,
moduleVersionId,
methodToken,
......@@ -102,7 +98,7 @@ internal override DkmCompilerId CompilerId
if (context != previous.EvaluationContext)
{
appDomain.SetMetadataContext(new CSharpMetadataContext(metadataBlocks, aliases, context));
appDomain.SetMetadataContext(new CSharpMetadataContext(metadataBlocks, context));
}
return context;
......
......@@ -131,17 +131,16 @@ internal override CSharpCompilation GetCompilation(DkmClrModuleInstance moduleIn
var appDomain = moduleInstance.AppDomain;
var previous = appDomain.GetMetadataContext<CSharpMetadataContext>();
var metadataBlocks = moduleInstance.RuntimeInstance.GetMetadataBlocks(appDomain);
var aliases = ImmutableArray<Alias>.Empty;
CSharpCompilation compilation;
if (previous.Matches(metadataBlocks, aliases))
if (previous.Matches(metadataBlocks))
{
compilation = previous.Compilation;
}
else
{
compilation = metadataBlocks.ToCompilation();
appDomain.SetMetadataContext(new CSharpMetadataContext(metadataBlocks, aliases, compilation));
appDomain.SetMetadataContext(new CSharpMetadataContext(metadataBlocks, compilation));
}
return compilation;
......
......@@ -18,18 +18,10 @@ public CSharpLocalAndMethod(string name, string displayName, MethodSymbol method
_method = method;
}
public CSharpLocalAndMethod(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.
: this(
SyntaxHelpers.EscapeKeywordIdentifiers(local.Name),
(local as PlaceholderLocalSymbol)?.DisplayName ?? SyntaxHelpers.EscapeKeywordIdentifiers(local.Name),
method,
flags)
{
}
/// <remarks>
/// The custom type info payload depends on the return type, which is not available when
/// <see cref="CSharpLocalAndMethod"/> is created.
/// </remarks>
public override CustomTypeInfo GetCustomTypeInfo() =>
new CustomTypeInfo(DynamicFlagsCustomTypeInfo.PayloadTypeId, _method.GetCustomTypeInfoPayload());
}
......
......@@ -9,38 +9,27 @@ namespace Microsoft.CodeAnalysis.CSharp.ExpressionEvaluator
internal struct CSharpMetadataContext
{
internal readonly ImmutableArray<MetadataBlock> MetadataBlocks;
internal readonly ImmutableArray<Alias> Aliases;
internal readonly CSharpCompilation Compilation;
internal readonly EvaluationContext EvaluationContext;
internal CSharpMetadataContext(
ImmutableArray<MetadataBlock> metadataBlocks,
ImmutableArray<Alias> aliases,
CSharpCompilation compilation)
internal CSharpMetadataContext(ImmutableArray<MetadataBlock> metadataBlocks, CSharpCompilation compilation)
{
this.MetadataBlocks = metadataBlocks;
this.Aliases = aliases;
this.Compilation = compilation;
this.EvaluationContext = null;
}
internal CSharpMetadataContext(
ImmutableArray<MetadataBlock> metadataBlocks,
ImmutableArray<Alias> aliases,
EvaluationContext evaluationContext)
internal CSharpMetadataContext(ImmutableArray<MetadataBlock> metadataBlocks, EvaluationContext evaluationContext)
{
this.MetadataBlocks = metadataBlocks;
this.Aliases = aliases;
this.Compilation = evaluationContext.Compilation;
this.EvaluationContext = evaluationContext;
}
internal bool Matches(ImmutableArray<MetadataBlock> metadataBlocks, ImmutableArray<Alias> aliases)
internal bool Matches(ImmutableArray<MetadataBlock> metadataBlocks)
{
return !this.MetadataBlocks.IsDefault &&
this.MetadataBlocks.SequenceEqual(metadataBlocks) &&
!this.Aliases.IsDefault &&
this.Aliases.SequenceEqual(aliases);
this.MetadataBlocks.SequenceEqual(metadataBlocks);
}
}
}
......@@ -6,6 +6,7 @@
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Emit;
using Microsoft.CodeAnalysis.ExpressionEvaluator;
using Microsoft.VisualStudio.Debugger.Clr;
using Microsoft.VisualStudio.Debugger.Evaluation.ClrCompilation;
using Roslyn.Utilities;
using System;
......@@ -35,7 +36,6 @@ internal sealed class CompilationContext
private readonly MetadataDecoder _metadataDecoder;
private readonly MethodSymbol _currentFrame;
private readonly ImmutableArray<LocalSymbol> _locals;
private readonly ImmutableArray<LocalSymbol> _aliasLocals;
private readonly ImmutableDictionary<string, DisplayClassVariable> _displayClassVariables;
private readonly ImmutableHashSet<string> _hoistedParameterNames;
private readonly ImmutableArray<LocalSymbol> _localsForBinding;
......@@ -50,7 +50,6 @@ internal sealed class CompilationContext
MetadataDecoder metadataDecoder,
MethodSymbol currentFrame,
ImmutableArray<LocalSymbol> locals,
ImmutableArray<LocalSymbol> aliasLocals,
InScopeHoistedLocals inScopeHoistedLocals,
MethodDebugInfo methodDebugInfo,
CSharpSyntaxNode syntax)
......@@ -63,7 +62,6 @@ internal sealed class CompilationContext
_currentFrame = currentFrame;
_syntax = syntax;
_methodNotType = !locals.IsDefault;
_aliasLocals = aliasLocals;
// NOTE: Since this is done within CompilationContext, it will not be cached.
// CONSIDER: The values should be the same everywhere in the module, so they
......@@ -114,6 +112,7 @@ internal sealed class CompilationContext
internal CommonPEModuleBuilder CompileExpression(
string typeName,
string methodName,
ImmutableArray<Alias> aliases,
Microsoft.CodeAnalysis.CodeGen.CompilationTestData testData,
DiagnosticBag diagnostics,
out ResultProperties resultProperties)
......@@ -133,7 +132,7 @@ internal sealed class CompilationContext
var hasDisplayClassThis = _displayClassVariables.ContainsKey(GeneratedNames.ThisProxyFieldName());
var binder = ExtendBinderChain(
_syntax,
_aliasLocals,
aliases,
method,
this.NamespaceBinder,
hasDisplayClassThis,
......@@ -179,6 +178,7 @@ internal sealed class CompilationContext
internal CommonPEModuleBuilder CompileAssignment(
string typeName,
string methodName,
ImmutableArray<Alias> aliases,
Microsoft.CodeAnalysis.CodeGen.CompilationTestData testData,
DiagnosticBag diagnostics,
out ResultProperties resultProperties)
......@@ -197,7 +197,7 @@ internal sealed class CompilationContext
var hasDisplayClassThis = _displayClassVariables.ContainsKey(GeneratedNames.ThisProxyFieldName());
var binder = ExtendBinderChain(
_syntax,
_aliasLocals,
aliases,
method,
this.NamespaceBinder,
hasDisplayClassThis,
......@@ -250,6 +250,7 @@ private static string GetNextMethodName(ArrayBuilder<MethodSymbol> builder)
string typeName,
ArrayBuilder<LocalAndMethod> localBuilder,
bool argumentsOnly,
ImmutableArray<Alias> aliases,
Microsoft.CodeAnalysis.CodeGen.CompilationTestData testData,
DiagnosticBag diagnostics)
{
......@@ -288,25 +289,29 @@ private static string GetNextMethodName(ArrayBuilder<MethodSymbol> builder)
if (!argumentsOnly)
{
// Pseudo-variables: $exception, $ReturnValue, etc.
var aliasNames = PooledHashSet<string>.GetInstance(); // To de-dup $ReturnValue/$returnvalue, etc.
foreach (var aliasLocal in _aliasLocals)
if (aliases.Length > 0)
{
if (!aliasNames.Add(aliasLocal.Name.ToLowerInvariant())) // Names are all ascii, so culture doesn't matter.
{
continue;
}
var methodName = GetNextMethodName(methodBuilder);
var syntax = SyntaxFactory.IdentifierName(SyntaxFactory.MissingToken(SyntaxKind.IdentifierToken));
var aliasMethod = this.CreateMethod(container, methodName, syntax, (method, diags) =>
{
var expression = new BoundLocal(syntax, aliasLocal, constantValueOpt: null, type: aliasLocal.Type);
return new BoundReturnStatement(syntax, expression) { WasCompilerGenerated = true };
});
var flags = aliasLocal.IsWritable ? DkmClrCompilationResultFlags.None : DkmClrCompilationResultFlags.ReadOnlyResult;
localBuilder.Add(new CSharpLocalAndMethod(aliasLocal, aliasMethod, flags));
methodBuilder.Add(aliasMethod);
}
aliasNames.Free();
var sourceAssembly = Compilation.SourceAssembly;
var typeNameDecoder = new EETypeNameDecoder(Compilation, (PEModuleSymbol)_currentFrame.ContainingModule);
foreach (var alias in aliases)
{
var local = PlaceholderLocalSymbol.Create(
typeNameDecoder,
_currentFrame,
sourceAssembly,
alias);
var methodName = GetNextMethodName(methodBuilder);
var syntax = SyntaxFactory.IdentifierName(SyntaxFactory.MissingToken(SyntaxKind.IdentifierToken));
var aliasMethod = this.CreateMethod(container, methodName, syntax, (method, diags) =>
{
var expression = new BoundLocal(syntax, local, constantValueOpt: null, type: local.Type);
return new BoundReturnStatement(syntax, expression) { WasCompilerGenerated = true };
});
var flags = local.IsWritable ? DkmClrCompilationResultFlags.None : DkmClrCompilationResultFlags.ReadOnlyResult;
localBuilder.Add(MakeLocalAndMethod(local, aliasMethod, flags));
methodBuilder.Add(aliasMethod);
}
}
// "this" for non-static methods that are not display class methods or
// display class methods where the display class contains "<>4__this".
......@@ -409,12 +414,12 @@ private static string GetNextMethodName(ArrayBuilder<MethodSymbol> builder)
ArrayBuilder<MethodSymbol> methodBuilder,
LocalSymbol local,
EENamedTypeSymbol container,
int localOrParameterIndex,
int localIndex,
DkmClrCompilationResultFlags resultFlags)
{
var methodName = GetNextMethodName(methodBuilder);
var method = this.GetLocalMethod(container, methodName, local.Name, localOrParameterIndex);
localBuilder.Add(new CSharpLocalAndMethod(local, method, resultFlags));
var method = this.GetLocalMethod(container, methodName, local.Name, localIndex);
localBuilder.Add(MakeLocalAndMethod(local, method, resultFlags));
methodBuilder.Add(method);
}
......@@ -423,18 +428,28 @@ private static string GetNextMethodName(ArrayBuilder<MethodSymbol> builder)
ArrayBuilder<MethodSymbol> methodBuilder,
ParameterSymbol parameter,
EENamedTypeSymbol container,
int localOrParameterIndex)
int parameterIndex)
{
// 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 name = SyntaxHelpers.EscapeKeywordIdentifiers(parameter.Name);
var methodName = GetNextMethodName(methodBuilder);
var method = this.GetParameterMethod(container, methodName, name, localOrParameterIndex);
var method = this.GetParameterMethod(container, methodName, name, parameterIndex);
localBuilder.Add(new CSharpLocalAndMethod(name, name, method, DkmClrCompilationResultFlags.None));
methodBuilder.Add(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 static EEAssemblyBuilder CreateModuleBuilder(
CSharpCompilation compilation,
ImmutableArray<MethodSymbol> methods,
......@@ -730,7 +745,7 @@ private static CSharpCompilation GetCompilationWithExternAliases(CSharpCompilati
private static Binder ExtendBinderChain(
CSharpSyntaxNode syntax,
ImmutableArray<LocalSymbol> aliasLocals,
ImmutableArray<Alias> aliases,
EEMethodSymbol method,
Binder binder,
bool hasDisplayClassThis,
......@@ -766,7 +781,13 @@ private static CSharpCompilation GetCompilationWithExternAliases(CSharpCompilati
if (methodNotType)
{
// Method locals and parameters shadow pseudo-variables.
binder = new PlaceholderLocalBinder(syntax, aliasLocals, method, binder);
var typeNameDecoder = new EETypeNameDecoder(binder.Compilation, (PEModuleSymbol)substitutedSourceMethod.ContainingModule);
binder = new PlaceholderLocalBinder(
syntax,
aliases,
method,
typeNameDecoder,
binder);
}
binder = new EEMethodBinder(method, substitutedSourceMethod, binder);
......
......@@ -15,9 +15,7 @@
using Microsoft.CodeAnalysis.Emit;
using Microsoft.CodeAnalysis.ExpressionEvaluator;
using Microsoft.DiaSymReader;
using Microsoft.VisualStudio.Debugger.Clr;
using Microsoft.VisualStudio.Debugger.Evaluation;
using Roslyn.Utilities;
namespace Microsoft.CodeAnalysis.CSharp.ExpressionEvaluator
{
......@@ -33,7 +31,6 @@ internal sealed class EvaluationContext : EvaluationContextBase
private readonly MetadataDecoder _metadataDecoder;
private readonly MethodSymbol _currentFrame;
private readonly ImmutableArray<LocalSymbol> _locals;
private readonly ImmutableArray<LocalSymbol> _aliasLocals;
private readonly InScopeHoistedLocals _inScopeHoistedLocals;
private readonly MethodDebugInfo _methodDebugInfo;
......@@ -43,7 +40,6 @@ internal sealed class EvaluationContext : EvaluationContextBase
MetadataDecoder metadataDecoder,
MethodSymbol currentFrame,
ImmutableArray<LocalSymbol> locals,
ImmutableArray<LocalSymbol> aliasLocals,
InScopeHoistedLocals inScopeHoistedLocals,
MethodDebugInfo methodDebugInfo)
{
......@@ -54,7 +50,6 @@ internal sealed class EvaluationContext : EvaluationContextBase
_metadataDecoder = metadataDecoder;
_currentFrame = currentFrame;
_locals = locals;
_aliasLocals = aliasLocals;
_inScopeHoistedLocals = inScopeHoistedLocals;
_methodDebugInfo = methodDebugInfo;
}
......@@ -77,7 +72,7 @@ internal sealed class EvaluationContext : EvaluationContextBase
int typeToken)
{
// Re-use the previous compilation if possible.
var compilation = previous.Matches(metadataBlocks, ImmutableArray<Alias>.Empty) ?
var compilation = previous.Matches(metadataBlocks) ?
previous.Compilation :
metadataBlocks.ToCompilation();
......@@ -102,7 +97,6 @@ internal sealed class EvaluationContext : EvaluationContextBase
metadataDecoder,
currentFrame,
default(ImmutableArray<LocalSymbol>),
default(ImmutableArray<LocalSymbol>),
InScopeHoistedLocals.Empty,
default(MethodDebugInfo));
}
......@@ -112,7 +106,6 @@ internal sealed class EvaluationContext : EvaluationContextBase
/// </summary>
/// <param name="previous">Previous context, if any, for possible re-use.</param>
/// <param name="metadataBlocks">Module metadata</param>
/// <param name="aliases">Aliases (e.g. $exception, locals declared in the Immediate window).</param>
/// <param name="symReader"><see cref="ISymUnmanagedReader"/> for PDB associated with <paramref name="moduleVersionId"/></param>
/// <param name="moduleVersionId">Module containing method</param>
/// <param name="methodToken">Method metadata token</param>
......@@ -123,7 +116,6 @@ internal sealed class EvaluationContext : EvaluationContextBase
internal static EvaluationContext CreateMethodContext(
CSharpMetadataContext previous,
ImmutableArray<MetadataBlock> metadataBlocks,
ImmutableArray<Alias> aliases,
object symReader,
Guid moduleVersionId,
int methodToken,
......@@ -133,7 +125,7 @@ internal sealed class EvaluationContext : EvaluationContextBase
{
// Re-use the previous compilation if possible.
CSharpCompilation compilation;
if (previous.Matches(metadataBlocks, aliases))
if (previous.Matches(metadataBlocks))
{
// Re-use entire context if method scope has not changed.
var previousContext = previous.EvaluationContext;
......@@ -152,7 +144,6 @@ internal sealed class EvaluationContext : EvaluationContextBase
return CreateMethodContext(
compilation,
aliases,
symReader,
moduleVersionId,
methodToken,
......@@ -163,7 +154,6 @@ internal sealed class EvaluationContext : EvaluationContextBase
internal static EvaluationContext CreateMethodContext(
CSharpCompilation compilation,
ImmutableArray<Alias> aliases,
object symReader,
Guid moduleVersionId,
int methodToken,
......@@ -213,17 +203,12 @@ internal sealed class EvaluationContext : EvaluationContextBase
var locals = localsBuilder.ToImmutableAndFree();
var aliasLocalsBuilder = ArrayBuilder<LocalSymbol>.GetInstance();
GetAliasLocals(aliasLocalsBuilder, aliases, currentFrame, compilation);
var aliasLocals = aliasLocalsBuilder.ToImmutableAndFree();
return new EvaluationContext(
methodContextReuseConstraints,
compilation,
metadataDecoder,
currentFrame,
locals,
aliasLocals,
inScopeHoistedLocals,
methodDebugInfo);
}
......@@ -235,7 +220,6 @@ internal CompilationContext CreateCompilationContext(CSharpSyntaxNode syntax)
_metadataDecoder,
_currentFrame,
_locals,
_aliasLocals,
_inScopeHoistedLocals,
_methodDebugInfo,
syntax);
......@@ -244,6 +228,7 @@ internal CompilationContext CreateCompilationContext(CSharpSyntaxNode syntax)
internal override CompileResult CompileExpression(
string expr,
DkmEvaluationFlags compilationFlags,
ImmutableArray<Alias> aliases,
DiagnosticBag diagnostics,
out ResultProperties resultProperties,
Microsoft.CodeAnalysis.CodeGen.CompilationTestData testData)
......@@ -258,7 +243,7 @@ internal CompilationContext CreateCompilationContext(CSharpSyntaxNode syntax)
var context = this.CreateCompilationContext(syntax);
ResultProperties properties;
var moduleBuilder = context.CompileExpression(TypeName, MethodName, testData, diagnostics, out properties);
var moduleBuilder = context.CompileExpression(TypeName, MethodName, aliases, testData, diagnostics, out properties);
if (moduleBuilder == null)
{
resultProperties = default(ResultProperties);
......@@ -336,6 +321,7 @@ private static MethodSymbol GetSynthesizedMethod(CommonPEModuleBuilder moduleBui
internal override CompileResult CompileAssignment(
string target,
string expr,
ImmutableArray<Alias> aliases,
DiagnosticBag diagnostics,
out ResultProperties resultProperties,
Microsoft.CodeAnalysis.CodeGen.CompilationTestData testData)
......@@ -349,7 +335,7 @@ private static MethodSymbol GetSynthesizedMethod(CommonPEModuleBuilder moduleBui
var context = this.CreateCompilationContext(assignment);
ResultProperties properties;
var moduleBuilder = context.CompileAssignment(TypeName, MethodName, testData, diagnostics, out properties);
var moduleBuilder = context.CompileAssignment(TypeName, MethodName, aliases, testData, diagnostics, out properties);
if (moduleBuilder == null)
{
resultProperties = default(ResultProperties);
......@@ -387,12 +373,13 @@ private static MethodSymbol GetSynthesizedMethod(CommonPEModuleBuilder moduleBui
internal override ReadOnlyCollection<byte> CompileGetLocals(
ArrayBuilder<LocalAndMethod> locals,
bool argumentsOnly,
ImmutableArray<Alias> aliases,
DiagnosticBag diagnostics,
out string typeName,
Microsoft.CodeAnalysis.CodeGen.CompilationTestData testData)
{
var context = this.CreateCompilationContext(null);
var moduleBuilder = context.CompileGetLocals(TypeName, locals, argumentsOnly, testData, diagnostics);
var moduleBuilder = context.CompileGetLocals(TypeName, locals, argumentsOnly, aliases, testData, diagnostics);
ReadOnlyCollection<byte> assembly = null;
if ((moduleBuilder != null) && (locals.Count > 0))
......@@ -530,86 +517,6 @@ private static MethodSymbol GetSynthesizedMethod(CommonPEModuleBuilder moduleBui
}
}
private static void GetAliasLocals(
ArrayBuilder<LocalSymbol> builder,
ImmutableArray<Alias> aliases,
MethodSymbol method,
CSharpCompilation compilation)
{
var sourceAssembly = compilation.SourceAssembly;
var typeNameDecoder = new EETypeNameDecoder(compilation, (PEModuleSymbol)method.ContainingModule);
foreach (var alias in aliases)
{
LocalSymbol additionalLocal;
builder.Add(CreateAliasLocal(typeNameDecoder, method, sourceAssembly, alias, out additionalLocal));
if ((object)additionalLocal != null)
{
Debug.Assert(alias.Kind == DkmClrAliasKind.ReturnValue);
builder.Add(additionalLocal);
}
}
}
private static LocalSymbol CreateAliasLocal(
TypeNameDecoder<PEModuleSymbol, TypeSymbol> typeNameDecoder,
MethodSymbol containingMethod,
AssemblySymbol sourceAssembly,
Alias alias,
out LocalSymbol additionalLocal)
{
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:
additionalLocal = null;
return new ExceptionLocalSymbol(containingMethod, name, displayName, type, ExpressionCompilerConstants.GetExceptionMethodName);
case DkmClrAliasKind.StowedException:
additionalLocal = null;
return new ExceptionLocalSymbol(containingMethod, name, displayName, type, ExpressionCompilerConstants.GetStowedExceptionMethodName);
case DkmClrAliasKind.ReturnValue:
{
int index;
PseudoVariableUtilities.TryParseReturnValueIndex(name, out index);
Debug.Assert(index >= 0);
var lowerId = name.ToLowerInvariant(); // The id should be ascii, so locale shouldn't matter.
additionalLocal = lowerId == name ? null : new ReturnValueLocalSymbol(containingMethod, lowerId, displayName, type, index);
return new ReturnValueLocalSymbol(containingMethod, name, displayName, type, index);
}
case DkmClrAliasKind.ObjectId:
Debug.Assert(name.Length > 0 && name[0] != '$');
additionalLocal = null;
return new ObjectIdLocalSymbol(containingMethod, type, "$" + name, displayName, isWritable: false);
case DkmClrAliasKind.Variable:
additionalLocal = null;
return new ObjectIdLocalSymbol(containingMethod, type, name, displayName, isWritable: true);
default:
throw ExceptionUtilities.UnexpectedValue(alias.Kind);
}
}
internal override bool HasDuplicateTypesOrAssemblies(Diagnostic diagnostic)
{
switch ((ErrorCode)diagnostic.Code)
......
......@@ -11,8 +11,8 @@ internal sealed class ObjectIdLocalSymbol : PlaceholderLocalSymbol
{
private readonly bool _isWritable;
internal ObjectIdLocalSymbol(MethodSymbol method, TypeSymbol type, string id, string displayName, bool isWritable) :
base(method, id, displayName, type)
internal ObjectIdLocalSymbol(MethodSymbol method, TypeSymbol type, string name, string displayName, bool isWritable) :
base(method, name, displayName, type)
{
_isWritable = isWritable;
}
......
......@@ -4,7 +4,9 @@
using System.Collections.Immutable;
using System.Diagnostics;
using Microsoft.CodeAnalysis.CSharp.Symbols;
using Microsoft.CodeAnalysis.CSharp.Symbols.Metadata.PE;
using Microsoft.CodeAnalysis.ExpressionEvaluator;
using Microsoft.VisualStudio.Debugger.Clr;
using Roslyn.Utilities;
namespace Microsoft.CodeAnalysis.CSharp.ExpressionEvaluator
......@@ -26,6 +28,59 @@ internal PlaceholderLocalSymbol(MethodSymbol method, string name, string display
this.DisplayName = displayName;
}
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:
Debug.Assert(name.Length > 0 && name[0] != '$');
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 override LocalDeclarationKind DeclarationKind
{
get { return LocalDeclarationKind.RegularVariable; }
......
......@@ -181,10 +181,9 @@ internal class B<U>
var compilation0 = CreateCompilationWithMscorlib(source, options: TestOptions.DebugDll, assemblyName: ExpressionCompilerUtilities.GenerateUniqueName());
var runtime = CreateRuntimeInstance(compilation0, includeSymbols: false);
var context = CreateTypeContext(runtime, "A.B");
ResultProperties resultProperties;
string error;
var testData = new CompilationTestData();
var result = context.CompileExpression("F(default(T), default(U))", out resultProperties, out error, testData);
var result = context.CompileExpression("F(default(T), default(U))", out error, testData);
string actualIL = testData.GetMethodData("<>x<T, U>.<>m0").GetMethodIL();
AssertEx.AssertEqualToleratingWhitespaceDifferences(
actualIL,
......@@ -233,11 +232,10 @@ void M()
var compilation0 = CreateCompilationWithMscorlib(source, options: TestOptions.DebugDll, assemblyName: ExpressionCompilerUtilities.GenerateUniqueName());
var runtime = CreateRuntimeInstance(compilation0, includeSymbols: false);
var context = CreateTypeContext(runtime, "N.C");
ResultProperties resultProperties;
string error;
var testData = new CompilationTestData();
// Expression compilation should succeed without imports.
var result = context.CompileExpression("typeof(N.C) ?? typeof(C)", out resultProperties, out error, testData);
var result = context.CompileExpression("typeof(N.C) ?? typeof(C)", out error, testData);
Assert.Null(error);
AssertEx.AssertEqualToleratingWhitespaceDifferences(
testData.GetMethodData("<>x.<>m0").GetMethodIL(),
......@@ -256,10 +254,10 @@ .maxstack 2
// Expression compilation should fail using imports since there are no symbols.
context = CreateTypeContext(runtime, "N.C");
testData = new CompilationTestData();
result = context.CompileExpression("typeof(A.C) ?? typeof(B) ?? typeof(C)", out resultProperties, out error, testData);
result = context.CompileExpression("typeof(A.C) ?? typeof(B) ?? typeof(C)", out error, testData);
Assert.Equal(error, "error CS0246: The type or namespace name 'A' could not be found (are you missing a using directive or an assembly reference?)");
testData = new CompilationTestData();
result = context.CompileExpression("typeof(B) ?? typeof(C)", out resultProperties, out error, testData);
result = context.CompileExpression("typeof(B) ?? typeof(C)", out error, testData);
Assert.Equal(error, "error CS0246: The type or namespace name 'B' could not be found (are you missing a using directive or an assembly reference?)");
}
......@@ -275,10 +273,9 @@ class C
var compilation0 = CreateCompilationWithMscorlib(source, options: TestOptions.DebugDll, assemblyName: ExpressionCompilerUtilities.GenerateUniqueName());
var runtime = CreateRuntimeInstance(compilation0, includeSymbols: false);
var context = CreateTypeContext(runtime, "C");
ResultProperties resultProperties;
string error;
var testData = new CompilationTestData();
var result = context.CompileExpression("$ReturnValue", out resultProperties, out error, testData);
var result = context.CompileExpression("$ReturnValue", out error, testData);
Assert.Equal(error, "error CS0103: The name '$ReturnValue' does not exist in the current context");
}
......@@ -365,10 +362,9 @@ protected override string GetDebuggerDisplay()
var compilation0 = CreateCompilationWithMscorlib(source, options: TestOptions.DebugDll, assemblyName: ExpressionCompilerUtilities.GenerateUniqueName());
var runtime = CreateRuntimeInstance(compilation0, includeSymbols: false);
var context = CreateTypeContext(runtime, "Derived");
ResultProperties resultProperties;
string error;
var testData = new CompilationTestData();
var result = context.CompileExpression("GetDebuggerDisplay()", out resultProperties, out error, testData);
var result = context.CompileExpression("GetDebuggerDisplay()", out error, testData);
Assert.Null(error);
var actualIL = testData.GetMethodData("<>x.<>m0").GetMethodIL();
var expectedIL =
......@@ -384,10 +380,9 @@ .maxstack 1
private static string CompileExpression(EvaluationContext context, string expr)
{
ResultProperties resultProperties;
string error;
var testData = new CompilationTestData();
var result = context.CompileExpression(expr, out resultProperties, out error, testData);
var result = context.CompileExpression(expr, out error, testData);
Assert.NotNull(result.Assembly);
Assert.Null(error);
return testData.GetMethodData(result.TypeName + "." + result.MethodName).GetMethodIL();
......
......@@ -437,6 +437,7 @@ .maxstack 1
result = context.CompileExpression(
"var dd = d;",
DkmEvaluationFlags.None,
NoAliases,
DiagnosticFormatter.Instance,
out resultProperties,
out error,
......@@ -445,7 +446,6 @@ .maxstack 1
testData);
Assert.Null(error);
VerifyCustomTypeInfo(result, null);
Assert.Empty(missingAssemblyIdentities);
Assert.Equal(resultProperties.Flags, DkmClrCompilationResultFlags.PotentialSideEffect | DkmClrCompilationResultFlags.ReadOnlyResult);
testData.GetMethodData("<>x.<>m0").VerifyIL(
@"{
......@@ -491,8 +491,9 @@ static void M()
assemblyName: ExpressionCompilerUtilities.GenerateUniqueName());
var runtime = CreateRuntimeInstance(compilation0);
var context = CreateMethodContext(
runtime,
"C.M",
runtime,
"C.M");
var aliases = ImmutableArray.Create(
Alias(
DkmClrAliasKind.Variable,
"d1",
......@@ -513,6 +514,7 @@ static void M()
context.CompileGetLocals(
locals,
argumentsOnly: false,
aliases: aliases,
diagnostics: diagnostics,
typeName: out typeName,
testData: testData);
......
......@@ -26,6 +26,8 @@ public abstract class ExpressionCompilerTestBase : CSharpTestBase, IDisposable
{
private readonly ArrayBuilder<IDisposable> _runtimeInstances = ArrayBuilder<IDisposable>.GetInstance();
internal static readonly ImmutableArray<Alias> NoAliases = ImmutableArray<Alias>.Empty;
public override void Dispose()
{
base.Dispose();
......@@ -113,32 +115,6 @@ public override void Dispose()
methodOrTypeToken = reader.GetToken(methodOrTypeHandle);
}
internal static EvaluationContext CreateMethodContext(
RuntimeInstance runtime,
string methodName,
params Alias[] aliases)
{
ImmutableArray<MetadataBlock> blocks;
Guid moduleVersionId;
ISymUnmanagedReader symReader;
int methodToken;
int localSignatureToken;
GetContextState(runtime, methodName, out blocks, out moduleVersionId, out symReader, out methodToken, out localSignatureToken);
int ilOffset = ExpressionCompilerTestHelpers.GetOffset(methodToken, symReader);
return EvaluationContext.CreateMethodContext(
default(CSharpMetadataContext),
blocks,
ImmutableArray.Create(aliases),
symReader,
moduleVersionId,
methodToken: methodToken,
methodVersion: 1,
ilOffset: ilOffset,
localSignatureToken: localSignatureToken);
}
internal static EvaluationContext CreateMethodContext(
RuntimeInstance runtime,
string methodName,
......@@ -156,7 +132,6 @@ public override void Dispose()
return EvaluationContext.CreateMethodContext(
default(CSharpMetadataContext),
blocks,
ImmutableArray<Alias>.Empty,
symReader,
moduleVersionId,
methodToken: methodToken,
......@@ -218,6 +193,7 @@ public override void Dispose()
var result = context.CompileExpression(
expr,
DkmEvaluationFlags.TreatAsExpression,
NoAliases,
DiagnosticFormatter.Instance,
out resultProperties,
out error,
......
......@@ -1325,13 +1325,10 @@ static IEnumerable<int> M()
int localSignatureToken;
GetContextState(runtime, "C.<M>d__0.MoveNext", out blocks, out moduleVersionId, out symReader, out methodToken, out localSignatureToken);
var aliases = ImmutableArray<Alias>.Empty;
int ilOffset = ExpressionCompilerTestHelpers.GetOffset(methodToken, symReader, atLineNumber: 100);
var context = EvaluationContext.CreateMethodContext(
default(CSharpMetadataContext),
blocks,
aliases,
symReader,
moduleVersionId,
methodToken: methodToken,
......@@ -1347,9 +1344,8 @@ static IEnumerable<int> M()
ilOffset = ExpressionCompilerTestHelpers.GetOffset(methodToken, symReader, atLineNumber: 200);
context = EvaluationContext.CreateMethodContext(
new CSharpMetadataContext(blocks, aliases, context),
new CSharpMetadataContext(blocks, context),
blocks,
aliases,
symReader,
moduleVersionId,
methodToken: methodToken,
......
......@@ -975,10 +975,9 @@ private static void VerifyHasThis(EvaluationContext context, string expectedType
VerifyMethodData(testData.Methods.Single(m => m.Key.Contains(localAndMethod.MethodName)).Value, expectedType, expectedIL);
locals.Free();
ResultProperties resultProperties;
string error;
testData = new CompilationTestData();
context.CompileExpression("this", out resultProperties, out error, testData);
context.CompileExpression("this", out error, testData);
Assert.Null(error);
VerifyMethodData(testData.Methods.Single(m => m.Key.Contains("<>m0")).Value, expectedType, expectedIL);
}
......@@ -1001,10 +1000,9 @@ private void VerifyNoThis(string source, string methodName)
private static void VerifyNoThis(EvaluationContext context)
{
ResultProperties resultProperties;
string error;
var testData = new CompilationTestData();
context.CompileExpression("this", out resultProperties, out error, testData);
context.CompileExpression("this", out error, testData);
Assert.Contains(error, new[]
{
"error CS0026: Keyword 'this' is not valid in a static property, static method, or static field initializer",
......@@ -1012,7 +1010,7 @@ private static void VerifyNoThis(EvaluationContext context)
});
testData = new CompilationTestData();
context.CompileExpression("base.ToString()", out resultProperties, out error, testData);
context.CompileExpression("base.ToString()", out error, testData);
Assert.Contains(error, new[]
{
"error CS1511: Keyword 'base' is not available in a static method",
......@@ -1047,10 +1045,9 @@ System.Collections.IEnumerable F()
assemblyName: ExpressionCompilerUtilities.GenerateUniqueName());
var runtime = CreateRuntimeInstance(compilation0);
var context = CreateMethodContext(runtime, "C.<F>d__1.MoveNext");
ResultProperties resultProperties;
string error;
var testData = new CompilationTestData();
context.CompileExpression("this.x", out resultProperties, out error, testData);
context.CompileExpression("this.x", out error, testData);
testData.GetMethodData("<>x.<>m0").VerifyIL(@"
{
// Code size 12 (0xc)
......@@ -1086,10 +1083,9 @@ async Task F()
assemblyName: ExpressionCompilerUtilities.GenerateUniqueName());
var runtime = CreateRuntimeInstance(compilation0);
var context = CreateMethodContext(runtime, "C.<F>d__1.MoveNext");
ResultProperties resultProperties;
string error;
var testData = new CompilationTestData();
context.CompileExpression("this.x", out resultProperties, out error, testData);
context.CompileExpression("this.x", out error, testData);
testData.GetMethodData("<>x.<>m0").VerifyIL(@"
{
// Code size 12 (0xc)
......@@ -1125,10 +1121,9 @@ void F()
assemblyName: ExpressionCompilerUtilities.GenerateUniqueName());
var runtime = CreateRuntimeInstance(compilation0);
var context = CreateMethodContext(runtime, "C.<F>b__1_0");
ResultProperties resultProperties;
string error;
var testData = new CompilationTestData();
context.CompileExpression("this.x", out resultProperties, out error, testData);
context.CompileExpression("this.x", out error, testData);
testData.GetMethodData("<>x.<>m0").VerifyIL(@"
{
// Code size 7 (0x7)
......@@ -1163,10 +1158,9 @@ System.Collections.IEnumerable M()
assemblyName: ExpressionCompilerUtilities.GenerateUniqueName());
var runtime = CreateRuntimeInstance(compilation0);
var context = CreateMethodContext(runtime, "Derived.<M>d__1.MoveNext");
ResultProperties resultProperties;
string error;
var testData = new CompilationTestData();
context.CompileExpression("base.x", out resultProperties, out error, testData);
context.CompileExpression("base.x", out error, testData);
testData.GetMethodData("<>x.<>m0").VerifyIL(@"
{
// Code size 12 (0xc)
......@@ -1207,10 +1201,9 @@ async Task M()
assemblyName: ExpressionCompilerUtilities.GenerateUniqueName());
var runtime = CreateRuntimeInstance(compilation0);
var context = CreateMethodContext(runtime, "Derived.<M>d__1.MoveNext");
ResultProperties resultProperties;
string error;
var testData = new CompilationTestData();
context.CompileExpression("base.x", out resultProperties, out error, testData);
context.CompileExpression("base.x", out error, testData);
testData.GetMethodData("<>x.<>m0").VerifyIL(@"
{
// Code size 12 (0xc)
......@@ -1251,10 +1244,9 @@ void F()
assemblyName: ExpressionCompilerUtilities.GenerateUniqueName());
var runtime = CreateRuntimeInstance(compilation0);
var context = CreateMethodContext(runtime, "Derived.<F>b__1_0");
ResultProperties resultProperties;
string error;
var testData = new CompilationTestData();
context.CompileExpression("this.x", out resultProperties, out error, testData);
context.CompileExpression("this.x", out error, testData);
testData.GetMethodData("<>x.<>m0").VerifyIL(@"
{
// Code size 7 (0x7)
......
......@@ -192,14 +192,13 @@ .maxstack 1
}");
locals.Free();
ResultProperties resultProperties;
string error;
testData = new CompilationTestData();
context.CompileExpression("b", out resultProperties, out error, testData);
context.CompileExpression("b", out error, testData);
Assert.Equal(error, "error CS0103: The name 'b' does not exist in the current context");
testData = new CompilationTestData();
context.CompileExpression("a[1]", out resultProperties, out error, testData);
context.CompileExpression("a[1]", out error, testData);
string actualIL = testData.GetMethodData("<>x.<>m0").GetMethodIL();
AssertEx.AssertEqualToleratingWhitespaceDifferences(actualIL,
@"{
......@@ -229,7 +228,8 @@ void M(object o)
var runtime = CreateRuntimeInstance(compilation0);
var context = CreateMethodContext(
runtime,
"C.M",
"C.M");
var aliases = ImmutableArray.Create(
ExceptionAlias(typeof(System.IO.IOException)),
ReturnValueAlias(2, typeof(string)),
ReturnValueAlias(),
......@@ -243,6 +243,7 @@ void M(object o)
context.CompileGetLocals(
locals,
argumentsOnly: true,
aliases: aliases,
diagnostics: diagnostics,
typeName: out typeName,
testData: testData);
......@@ -254,6 +255,7 @@ void M(object o)
context.CompileGetLocals(
locals,
argumentsOnly: false,
aliases: aliases,
diagnostics: diagnostics,
typeName: out typeName,
testData: testData);
......@@ -1768,10 +1770,9 @@ void M(object o)
methodName: "C.M",
atLineNumber: 999);
ResultProperties resultProperties;
string error;
var testData = new CompilationTestData();
context.CompileExpression("o = null", out resultProperties, out error, testData);
context.CompileExpression("o = null", out error, testData);
Assert.Null(error); // In regular code, there would be an error about modifying a lock local.
testData.GetMethodData("<>x.<>m0").VerifyIL(
......
......@@ -93,6 +93,7 @@ public void M(Missing parameter)
context.CompileExpression(
"parameter",
DkmEvaluationFlags.TreatAsExpression,
NoAliases,
DiagnosticFormatter.Instance,
out resultProperties,
out actualError,
......@@ -127,6 +128,7 @@ public void M(int[] array)
context.CompileExpression(
"from i in array select i",
DkmEvaluationFlags.TreatAsExpression,
NoAliases,
DiagnosticFormatter.Instance,
out resultProperties,
out actualError,
......@@ -164,6 +166,7 @@ public void M(int[] array)
context.CompileExpression(
"array.Count()",
DkmEvaluationFlags.TreatAsExpression,
NoAliases,
DiagnosticFormatter.Instance,
out resultProperties,
out actualError,
......@@ -176,6 +179,7 @@ public void M(int[] array)
context.CompileExpression(
"array.NoSuchMethod()",
DkmEvaluationFlags.TreatAsExpression,
NoAliases,
DiagnosticFormatter.Instance,
out resultProperties,
out actualError,
......@@ -225,6 +229,7 @@ public class Dummy
context.CompileExpression(
"array.Count()",
DkmEvaluationFlags.TreatAsExpression,
NoAliases,
DiagnosticFormatter.Instance,
out resultProperties,
out actualError,
......@@ -237,6 +242,7 @@ public class Dummy
context.CompileExpression(
"array.NoSuchMethod()",
DkmEvaluationFlags.TreatAsExpression,
NoAliases,
DiagnosticFormatter.Instance,
out resultProperties,
out actualError,
......@@ -300,6 +306,7 @@ static void M(Dummy d)
context.CompileExpression(
"new global::Forwarded()",
DkmEvaluationFlags.TreatAsExpression,
NoAliases,
DiagnosticFormatter.Instance,
out resultProperties,
out actualError,
......@@ -314,6 +321,7 @@ static void M(Dummy d)
context.CompileExpression(
"new Forwarded()",
DkmEvaluationFlags.TreatAsExpression,
NoAliases,
DiagnosticFormatter.Instance,
out resultProperties,
out actualError,
......@@ -328,6 +336,7 @@ static void M(Dummy d)
context.CompileExpression(
"new NS.Forwarded()",
DkmEvaluationFlags.TreatAsExpression,
NoAliases,
DiagnosticFormatter.Instance,
out resultProperties,
out actualError,
......@@ -466,22 +475,7 @@ static void M()
}
";
var comp = CreateCompilationWithMscorlib(source, options: TestOptions.DebugDll);
byte[] exeBytes;
byte[] pdbBytes;
ImmutableArray<MetadataReference> unusedReferences;
var emitResult = comp.EmitAndGetReferences(out exeBytes, out pdbBytes, out unusedReferences);
Assert.True(emitResult);
var runtime = CreateRuntimeInstance(
GetUniqueName(),
ImmutableArray.Create(CSharpRef, ExpressionCompilerTestHelpers.IntrinsicAssemblyReference),
exeBytes,
new SymReader(pdbBytes));
var context = CreateMethodContext(
runtime,
"C.M",
ExceptionAlias("Microsoft.CSharp.RuntimeBinder.RuntimeBinderException, Microsoft.CSharp, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", stowed: true));
var context = CreateMethodContextWithReferences(comp, "C.M", CSharpRef, ExpressionCompilerTestHelpers.IntrinsicAssemblyReference);
const string expectedError = "error CS0012: The type 'Exception' is defined in an assembly that is not referenced. You must add a reference to assembly 'mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'.";
var expectedMissingAssemblyIdentity = comp.Assembly.CorLibrary.Identity;
......@@ -492,6 +486,7 @@ static void M()
context.CompileExpression(
"$stowedexception",
DkmEvaluationFlags.TreatAsExpression,
ImmutableArray.Create(ExceptionAlias("Microsoft.CSharp.RuntimeBinder.RuntimeBinderException, Microsoft.CSharp, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", stowed: true)),
DiagnosticFormatter.Instance,
out resultProperties,
out actualError,
......@@ -527,6 +522,7 @@ static void M(Windows.Storage.StorageFolder f)
context.CompileExpression(
"typeof(@Windows.UI.Colors)",
DkmEvaluationFlags.None,
NoAliases,
DiagnosticFormatter.Instance,
out resultProperties,
out actualError,
......@@ -565,6 +561,7 @@ static void M(Windows.UI.Colors c)
context.CompileExpression(
"typeof(Windows.@UI.Xaml.Application)",
DkmEvaluationFlags.None,
NoAliases,
DiagnosticFormatter.Instance,
out resultProperties,
out actualError,
......
......@@ -44,10 +44,9 @@ static void Main()
assemblyName: ExpressionCompilerUtilities.GenerateUniqueName());
var runtime = CreateRuntimeInstance(compilation0);
var context = CreateMethodContext(runtime, "C.M");
ResultProperties resultProperties;
string error;
var testData = new CompilationTestData();
var result = context.CompileExpression("this", out resultProperties, out error, testData);
var result = context.CompileExpression("this", out error, testData);
Assert.Null(error);
testData.GetMethodData("<>x.<>m0").VerifyIL(
@"{
......@@ -101,10 +100,9 @@ static void M()
exeBytes,
new SymReader(pdbBytes));
var context = CreateMethodContext(runtime, "C.M");
ResultProperties resultProperties;
string error;
var testData = new CompilationTestData();
var result = context.CompileExpression("o", out resultProperties, out error, testData);
var result = context.CompileExpression("o", out error, testData);
Assert.Null(error);
testData.GetMethodData("<>x.<>m0").VerifyIL(
@"{
......@@ -198,7 +196,7 @@ static void Main()
// Bind to local of embedded PIA type.
var testData = new CompilationTestData();
context.CompileExpression("x", out resultProperties, out error, testData);
context.CompileExpression("x", out error, testData);
Assert.Null(error);
testData.GetMethodData("<>x.<>m0").VerifyIL(
@"{
......@@ -214,6 +212,7 @@ .maxstack 1
context.CompileExpression(
"x.F()",
DkmEvaluationFlags.TreatAsExpression,
NoAliases,
DiagnosticFormatter.Instance,
out resultProperties,
out error,
......@@ -227,7 +226,7 @@ .maxstack 1
// in assembly referencing PIA.dll.
context = CreateMethodContext(runtime, "B.Main");
testData = new CompilationTestData();
context.CompileExpression("y.F()", out resultProperties, out error, testData);
context.CompileExpression("y.F()", out error, testData);
Assert.Null(error);
testData.GetMethodData("<>x.<>m0").VerifyIL(
@"{
......
......@@ -171,8 +171,6 @@ static void M()
GetContextState(runtime, "C.M", out methodBlocks, out moduleVersionId, out symReader, out methodToken, out localSignatureToken);
int ilOffset = ExpressionCompilerTestHelpers.GetOffset(methodToken, symReader);
var aliases = ImmutableArray<Alias>.Empty;
// Compile expression with type context with all modules.
var context = EvaluationContext.CreateTypeContext(
default(CSharpMetadataContext),
......@@ -188,7 +186,7 @@ static void M()
// B is ambiguous.
context.CompileExpression("new B()", out error, testData);
Assert.True(error.StartsWith("error CS0433: The type 'B' exists in both "));
var previous = new CSharpMetadataContext(typeBlocks, aliases, context);
var previous = new CSharpMetadataContext(typeBlocks, context);
// Compile expression with type context with referenced modules only.
context = EvaluationContext.CreateTypeContext(
......@@ -218,6 +216,7 @@ .maxstack 1
context.CompileExpression(
"(new B()).F",
DkmEvaluationFlags.None,
NoAliases,
DiagnosticFormatter.Instance,
out resultProperties,
out error,
......@@ -229,8 +228,7 @@ .maxstack 1
// Compile expression with method context with all modules.
context = EvaluationContext.CreateMethodContext(
previous,
methodBlocks,
aliases,
methodBlocks,
symReader,
moduleVersionId,
methodToken: methodToken,
......@@ -250,8 +248,7 @@ .maxstack 1
// Compile expression with method context with referenced modules only.
context = EvaluationContext.CreateMethodContext(
methodBlocks.ToCompilationReferencedModulesOnly(moduleVersionId),
aliases,
methodBlocks.ToCompilationReferencedModulesOnly(moduleVersionId),
symReader,
moduleVersionId,
methodToken: methodToken,
......@@ -279,6 +276,7 @@ .maxstack 1
context.CompileExpression(
"(new B()).F",
DkmEvaluationFlags.None,
NoAliases,
DiagnosticFormatter.Instance,
out resultProperties,
out error,
......@@ -572,7 +570,6 @@ .maxstack 1
{
return (blocks, useReferencedModulesOnly) => EvaluationContext.CreateMethodContext(
ToCompilation(blocks, useReferencedModulesOnly, moduleVersionId),
ImmutableArray<Alias>.Empty,
symReader,
moduleVersionId,
methodToken,
......
......@@ -301,7 +301,7 @@ void Test()
string error;
var testData = new CompilationTestData();
ImmutableArray<AssemblyIdentity> missingAssemblyIdentities;
context.CompileAssignment("P", "1", DiagnosticFormatter.Instance, out resultProperties, out error, out missingAssemblyIdentities, EnsureEnglishUICulture.PreferredOrNull, testData);
context.CompileAssignment("P", "1", NoAliases, DiagnosticFormatter.Instance, out resultProperties, out error, out missingAssemblyIdentities, EnsureEnglishUICulture.PreferredOrNull, testData);
Assert.Null(error);
Assert.Empty(missingAssemblyIdentities);
......@@ -336,6 +336,7 @@ void Test()
context.CompileExpression(
"int z = 1;",
DkmEvaluationFlags.None,
NoAliases,
DiagnosticFormatter.Instance,
out resultProperties,
out error,
......
......@@ -53,10 +53,9 @@ static void M(Windows.Storage.StorageFolder f, Windows.Foundation.Collections.Pr
exeBytes,
new SymReader(pdbBytes));
var context = CreateMethodContext(runtime, "C.M");
ResultProperties resultProperties;
string error;
var testData = new CompilationTestData();
context.CompileExpression("(p == null) ? f : null", out resultProperties, out error, testData);
context.CompileExpression("(p == null) ? f : null", out error, testData);
Assert.Null(error);
testData.GetMethodData("<>x.<>m0").VerifyIL(
@"{
......@@ -99,10 +98,9 @@ static void M(X::Windows.Storage.StorageFolder f)
exeBytes,
new SymReader(pdbBytes));
var context = CreateMethodContext(runtime, "C.M");
ResultProperties resultProperties;
string error;
var testData = new CompilationTestData();
context.CompileExpression("X::Windows.Storage.FileProperties.PhotoOrientation.Unspecified", out resultProperties, out error, testData);
context.CompileExpression("X::Windows.Storage.FileProperties.PhotoOrientation.Unspecified", out error, testData);
Assert.Null(error);
testData.GetMethodData("<>x.<>m0").VerifyIL(
@"{
......@@ -182,10 +180,9 @@ static void M(LibraryA.A a, LibraryB.B b, Windows.Data.Text.TextSegment t, Windo
}";
var runtime = CreateRuntime(source, compileReferences, runtimeReferences);
var context = CreateMethodContext(runtime, "C.M");
ResultProperties resultProperties;
string error;
var testData = new CompilationTestData();
context.CompileExpression("(object)a ?? (object)b ?? (object)t ?? f", out resultProperties, out error, testData);
context.CompileExpression("(object)a ?? (object)b ?? (object)t ?? f", out error, testData);
Assert.Null(error);
testData.GetMethodData("<>x.<>m0").VerifyIL(
@"{
......@@ -207,7 +204,7 @@ .maxstack 2
IL_0010: ret
}");
testData = new CompilationTestData();
var result = context.CompileExpression("default(Windows.Storage.StorageFolder)", out resultProperties, out error, testData);
var result = context.CompileExpression("default(Windows.Storage.StorageFolder)", out error, testData);
Assert.Null(error);
var methodData = testData.GetMethodData("<>x.<>m0");
methodData.VerifyIL(
......@@ -262,24 +259,19 @@ static void M(Windows.Storage.StorageFolder f, Windows.Foundation.Collections.Pr
ImmutableArray.CreateRange(WinRtRefs),
ImmutableArray.Create(MscorlibRef).Concat(ExpressionCompilerTestHelpers.GetRuntimeWinMds("Windows.Storage", "Windows.Foundation.Collections")));
var context = CreateMethodContext(
runtime,
"C.M",
runtime,
"C.M");
var aliases = ImmutableArray.Create(
VariableAlias("s", "Windows.Storage.StorageFolder, Windows.Storage, Version=255.255.255.255, Culture=neutral, PublicKeyToken=null, ContentType=WindowsRuntime"),
VariableAlias("d", "Windows.Foundation.DateTime, Windows.Foundation, Version=255.255.255.255, Culture=neutral, PublicKeyToken=null, ContentType=WindowsRuntime"));
ResultProperties resultProperties;
string error;
var testData = new CompilationTestData();
ImmutableArray<AssemblyIdentity> missingAssemblyIdentities;
context.CompileExpression(
"(object)s.Attributes ?? d.UniversalTime",
DkmEvaluationFlags.TreatAsExpression,
DiagnosticFormatter.Instance,
out resultProperties,
aliases,
out error,
out missingAssemblyIdentities,
EnsureEnglishUICulture.PreferredOrNull,
testData);
Assert.Empty(missingAssemblyIdentities);
testData.GetMethodData("<>x.<>m0").VerifyIL(
@"{
// Code size 55 (0x37)
......@@ -317,20 +309,14 @@ static void M(Windows.UI.Xaml.FrameworkElement f)
ImmutableArray.CreateRange(WinRtRefs),
ImmutableArray.Create(MscorlibRef).Concat(ExpressionCompilerTestHelpers.GetRuntimeWinMds("Windows.Foundation", "Windows.UI", "Windows.UI.Xaml")));
var context = CreateMethodContext(runtime, "C.M");
ResultProperties resultProperties;
string error;
var testData = new CompilationTestData();
ImmutableArray<AssemblyIdentity> missingAssemblyIdentities;
context.CompileExpression(
"f.RenderSize",
DkmEvaluationFlags.TreatAsExpression,
DiagnosticFormatter.Instance,
out resultProperties,
NoAliases,
out error,
out missingAssemblyIdentities,
EnsureEnglishUICulture.PreferredOrNull,
testData);
Assert.Empty(missingAssemblyIdentities);
testData.GetMethodData("<>x.<>m0").VerifyIL(
@"{
// Code size 55 (0x37)
......
......@@ -24,6 +24,7 @@ internal abstract class EvaluationContextBase
internal abstract CompileResult CompileExpression(
string expr,
DkmEvaluationFlags compilationFlags,
ImmutableArray<Alias> aliases,
DiagnosticBag diagnostics,
out ResultProperties resultProperties,
CompilationTestData testData);
......@@ -31,6 +32,7 @@ internal abstract class EvaluationContextBase
internal abstract CompileResult CompileAssignment(
string target,
string expr,
ImmutableArray<Alias> aliases,
DiagnosticBag diagnostics,
out ResultProperties resultProperties,
CompilationTestData testData);
......@@ -38,6 +40,7 @@ internal abstract class EvaluationContextBase
internal abstract ReadOnlyCollection<byte> CompileGetLocals(
ArrayBuilder<LocalAndMethod> locals,
bool argumentsOnly,
ImmutableArray<Alias> aliases,
DiagnosticBag diagnostics,
out string typeName,
CompilationTestData testData);
......
......@@ -36,12 +36,14 @@ static ExpressionCompiler()
{
var moduleInstance = instructionAddress.ModuleInstance;
var runtimeInstance = instructionAddress.RuntimeInstance;
var aliases = GetAliases(runtimeInstance, inspectionContext); // NB: Not affected by retrying.
var aliases = argumentsOnly
? ImmutableArray<Alias>.Empty
: GetAliases(runtimeInstance, inspectionContext); // NB: Not affected by retrying.
string error;
var r = this.CompileWithRetry(
moduleInstance,
runtimeInstance.GetMetadataBlocks(moduleInstance.AppDomain),
(blocks, useReferencedModulesOnly) => CreateMethodContext(instructionAddress, blocks, aliases, useReferencedModulesOnly),
(blocks, useReferencedModulesOnly) => CreateMethodContext(instructionAddress, blocks, useReferencedModulesOnly),
(context, diagnostics) =>
{
var builder = ArrayBuilder<LocalAndMethod>.GetInstance();
......@@ -49,6 +51,7 @@ static ExpressionCompiler()
var assembly = context.CompileGetLocals(
builder,
argumentsOnly,
aliases,
diagnostics,
out typeName,
testData: null);
......@@ -104,13 +107,14 @@ private static ImmutableArray<Alias> GetAliases(DkmClrRuntimeInstance runtimeIns
var r = this.CompileWithRetry(
moduleInstance,
runtimeInstance.GetMetadataBlocks(moduleInstance.AppDomain),
(blocks, useReferencedModulesOnly) => CreateMethodContext(instructionAddress, blocks, aliases, useReferencedModulesOnly),
(blocks, useReferencedModulesOnly) => CreateMethodContext(instructionAddress, blocks, useReferencedModulesOnly),
(context, diagnostics) =>
{
ResultProperties resultProperties;
var compileResult = context.CompileExpression(
expression.Text,
expression.CompilationFlags,
aliases,
diagnostics,
out resultProperties,
testData: null);
......@@ -140,13 +144,14 @@ private static ImmutableArray<Alias> GetAliases(DkmClrRuntimeInstance runtimeIns
var r = this.CompileWithRetry(
moduleInstance,
runtimeInstance.GetMetadataBlocks(moduleInstance.AppDomain),
(blocks, useReferencedModulesOnly) => CreateMethodContext(instructionAddress, blocks, aliases, useReferencedModulesOnly),
(blocks, useReferencedModulesOnly) => CreateMethodContext(instructionAddress, blocks, useReferencedModulesOnly),
(context, diagnostics) =>
{
ResultProperties resultProperties;
var compileResult = context.CompileAssignment(
lValue.FullName,
expression.Text,
aliases,
diagnostics,
out resultProperties,
testData: null);
......@@ -184,6 +189,7 @@ private static ImmutableArray<Alias> GetAliases(DkmClrRuntimeInstance runtimeIns
return context.CompileExpression(
expression.Text,
DkmEvaluationFlags.TreatAsExpression,
ImmutableArray<Alias>.Empty,
diagnostics,
out unusedResultProperties,
testData: null);
......@@ -239,7 +245,6 @@ void IDkmModuleModifiedNotification.OnModuleModified(DkmModuleInstance moduleIns
internal abstract EvaluationContextBase CreateMethodContext(
DkmClrAppDomain appDomain,
ImmutableArray<MetadataBlock> metadataBlocks,
ImmutableArray<Alias> aliases,
Lazy<ImmutableArray<AssemblyReaders>> lazyAssemblyReaders,
object symReader,
Guid moduleVersionId,
......@@ -254,7 +259,6 @@ void IDkmModuleModifiedNotification.OnModuleModified(DkmModuleInstance moduleIns
private EvaluationContextBase CreateMethodContext(
DkmClrInstructionAddress instructionAddress,
ImmutableArray<MetadataBlock> metadataBlocks,
ImmutableArray<Alias> aliases,
bool useReferencedModulesOnly)
{
var moduleInstance = instructionAddress.ModuleInstance;
......@@ -277,7 +281,6 @@ void IDkmModuleModifiedNotification.OnModuleModified(DkmModuleInstance moduleIns
return this.CreateMethodContext(
moduleInstance.AppDomain,
metadataBlocks,
aliases,
new Lazy<ImmutableArray<AssemblyReaders>>(() => instructionAddress.MakeAssemblyReaders(), LazyThreadSafetyMode.None),
symReader: moduleInstance.GetSymReader(),
moduleVersionId: moduleInstance.Mvid,
......
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using Microsoft.VisualStudio.Debugger.Clr;
using Microsoft.VisualStudio.Debugger.Evaluation.ClrCompilation;
using Roslyn.Utilities;
using System;
using System.Diagnostics;
using System.Globalization;
using Microsoft.VisualStudio.Debugger.Clr;
namespace Microsoft.CodeAnalysis.ExpressionEvaluator
{
......
......@@ -59,6 +59,43 @@ internal static class ExpressionCompilerTestHelpers
this EvaluationContextBase context,
string target,
string expr,
out string error,
CompilationTestData testData = null,
DiagnosticFormatter formatter = null)
{
ResultProperties resultProperties;
ImmutableArray<AssemblyIdentity> missingAssemblyIdentities;
var result = context.CompileAssignment(
target,
expr,
ImmutableArray<Alias>.Empty,
formatter ?? DiagnosticFormatter.Instance,
out resultProperties,
out error,
out missingAssemblyIdentities,
EnsureEnglishUICulture.PreferredOrNull,
testData);
Assert.Empty(missingAssemblyIdentities);
// This is a crude way to test the language, but it's convenient to share this test helper.
var isCSharp = context.GetType().Namespace.IndexOf("csharp", StringComparison.OrdinalIgnoreCase) >= 0;
var expectedFlags = error != null
? DkmClrCompilationResultFlags.None
: isCSharp
? DkmClrCompilationResultFlags.PotentialSideEffect
: DkmClrCompilationResultFlags.PotentialSideEffect | DkmClrCompilationResultFlags.ReadOnlyResult;
Assert.Equal(expectedFlags, resultProperties.Flags);
Assert.Equal(default(DkmEvaluationResultCategory), resultProperties.Category);
Assert.Equal(default(DkmEvaluationResultAccessType), resultProperties.AccessType);
Assert.Equal(default(DkmEvaluationResultStorageType), resultProperties.StorageType);
Assert.Equal(default(DkmEvaluationResultTypeModifierFlags), resultProperties.ModifierFlags);
return result;
}
internal static CompileResult CompileAssignment(
this EvaluationContextBase context,
string target,
string expr,
ImmutableArray<Alias> aliases,
DiagnosticFormatter formatter,
out ResultProperties resultProperties,
out string error,
......@@ -67,7 +104,7 @@ internal static class ExpressionCompilerTestHelpers
CompilationTestData testData)
{
var diagnostics = DiagnosticBag.GetInstance();
var result = context.CompileAssignment(target, expr, diagnostics, out resultProperties, testData);
var result = context.CompileAssignment(target, expr, aliases, diagnostics, out resultProperties, testData);
if (diagnostics.HasAnyErrors())
{
bool useReferencedModulesOnly;
......@@ -94,6 +131,7 @@ internal static class ExpressionCompilerTestHelpers
var result = context.CompileGetLocals(
locals,
argumentsOnly,
ImmutableArray<Alias>.Empty,
diagnostics,
out typeName,
testData);
......@@ -102,6 +140,65 @@ internal static class ExpressionCompilerTestHelpers
return result;
}
internal static CompileResult CompileExpression(
this EvaluationContextBase context,
string expr,
out string error,
CompilationTestData testData = null,
DiagnosticFormatter formatter = null)
{
ResultProperties resultProperties;
return CompileExpression(context, expr, out resultProperties, out error, testData, formatter);
}
internal static CompileResult CompileExpression(
this EvaluationContextBase context,
string expr,
out ResultProperties resultProperties,
out string error,
CompilationTestData testData = null,
DiagnosticFormatter formatter = null)
{
ImmutableArray<AssemblyIdentity> missingAssemblyIdentities;
var result = context.CompileExpression(
expr,
DkmEvaluationFlags.TreatAsExpression,
ImmutableArray<Alias>.Empty,
formatter ?? DiagnosticFormatter.Instance,
out resultProperties,
out error,
out missingAssemblyIdentities,
EnsureEnglishUICulture.PreferredOrNull,
testData);
Assert.Empty(missingAssemblyIdentities);
return result;
}
static internal CompileResult CompileExpression(
this EvaluationContextBase evaluationContext,
string expr,
DkmEvaluationFlags compilationFlags,
ImmutableArray<Alias> aliases,
out string error,
CompilationTestData testData = null,
DiagnosticFormatter formatter = null)
{
ResultProperties resultProperties;
ImmutableArray<AssemblyIdentity> missingAssemblyIdentities;
var result = evaluationContext.CompileExpression(
expr,
compilationFlags,
aliases,
formatter ?? DiagnosticFormatter.Instance,
out resultProperties,
out error,
out missingAssemblyIdentities,
EnsureEnglishUICulture.PreferredOrNull,
testData);
Assert.Empty(missingAssemblyIdentities);
return result;
}
/// <summary>
/// Compile C# expression and emit assembly with evaluation method.
/// </summary>
......@@ -112,6 +209,7 @@ internal static class ExpressionCompilerTestHelpers
this EvaluationContextBase evaluationContext,
string expr,
DkmEvaluationFlags compilationFlags,
ImmutableArray<Alias> aliases,
DiagnosticFormatter formatter,
out ResultProperties resultProperties,
out string error,
......@@ -120,7 +218,7 @@ internal static class ExpressionCompilerTestHelpers
CompilationTestData testData)
{
var diagnostics = DiagnosticBag.GetInstance();
var result = evaluationContext.CompileExpression(expr, compilationFlags, diagnostics, out resultProperties, testData);
var result = evaluationContext.CompileExpression(expr, compilationFlags, aliases, diagnostics, out resultProperties, testData);
if (diagnostics.HasAnyErrors())
{
bool useReferencedModulesOnly;
......@@ -170,6 +268,7 @@ internal static class ExpressionCompilerTestHelpers
var compileResult = context.CompileExpression(
expr,
DkmEvaluationFlags.TreatAsExpression,
ImmutableArray<Alias>.Empty,
diagnostics,
out resultProperties,
td);
......
......@@ -74,7 +74,6 @@
<DesignTime>True</DesignTime>
<DependentUpon>Resources.resx</DependentUpon>
</Compile>
<Compile Include="TestExtensions.cs" />
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
......
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using Microsoft.CodeAnalysis.CodeGen;
using Microsoft.VisualStudio.Debugger.Evaluation;
using Microsoft.VisualStudio.Debugger.Evaluation.ClrCompilation;
using Roslyn.Test.Utilities;
using System;
using System.Collections.Immutable;
using Xunit;
namespace Microsoft.CodeAnalysis.ExpressionEvaluator
{
internal static class TestExtensions
{
internal static CompileResult CompileExpression(
this EvaluationContextBase context,
string expr,
out string error,
CompilationTestData testData = null,
DiagnosticFormatter formatter = null)
{
ResultProperties resultProperties;
return CompileExpression(context, expr, out resultProperties, out error, testData, formatter);
}
internal static CompileResult CompileExpression(
this EvaluationContextBase context,
string expr,
out ResultProperties resultProperties,
out string error,
CompilationTestData testData = null,
DiagnosticFormatter formatter = null)
{
ImmutableArray<AssemblyIdentity> missingAssemblyIdentities;
var result = context.CompileExpression(
expr,
DkmEvaluationFlags.TreatAsExpression,
formatter ?? DiagnosticFormatter.Instance,
out resultProperties,
out error,
out missingAssemblyIdentities,
EnsureEnglishUICulture.PreferredOrNull,
testData);
Assert.Empty(missingAssemblyIdentities);
return result;
}
internal static CompileResult CompileAssignment(
this EvaluationContextBase context,
string target,
string expr,
out string error,
CompilationTestData testData = null,
DiagnosticFormatter formatter = null)
{
ResultProperties resultProperties;
ImmutableArray<AssemblyIdentity> missingAssemblyIdentities;
var result = context.CompileAssignment(
target,
expr,
formatter ?? DiagnosticFormatter.Instance,
out resultProperties,
out error,
out missingAssemblyIdentities,
EnsureEnglishUICulture.PreferredOrNull,
testData);
Assert.Empty(missingAssemblyIdentities);
// This is a crude way to test the language, but it's convenient to share this test helper.
var isCSharp = context.GetType().Namespace.IndexOf("csharp", StringComparison.OrdinalIgnoreCase) >= 0;
var expectedFlags = error != null
? DkmClrCompilationResultFlags.None
: isCSharp
? DkmClrCompilationResultFlags.PotentialSideEffect
: DkmClrCompilationResultFlags.PotentialSideEffect | DkmClrCompilationResultFlags.ReadOnlyResult;
Assert.Equal(expectedFlags, resultProperties.Flags);
Assert.Equal(default(DkmEvaluationResultCategory), resultProperties.Category);
Assert.Equal(default(DkmEvaluationResultAccessType), resultProperties.AccessType);
Assert.Equal(default(DkmEvaluationResultStorageType), resultProperties.StorageType);
Assert.Equal(default(DkmEvaluationResultTypeModifierFlags), resultProperties.ModifierFlags);
return result;
}
}
}
......@@ -2,7 +2,9 @@
Imports System.Collections.Immutable
Imports System.Runtime.InteropServices
Imports Microsoft.CodeAnalysis.ExpressionEvaluator
Imports Microsoft.CodeAnalysis.VisualBasic.Symbols
Imports Microsoft.CodeAnalysis.VisualBasic.Symbols.Metadata.PE
Imports Microsoft.CodeAnalysis.VisualBasic.Syntax
Imports Roslyn.Utilities
......@@ -16,8 +18,9 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.ExpressionEvaluator
Private ReadOnly _implicitDeclarations As Dictionary(Of String, LocalSymbol)
Friend Sub New(
aliases As ImmutableArray(Of [Alias]),
containingMethod As MethodSymbol,
aliasLocals As ImmutableArray(Of LocalSymbol),
typeNameDecoder As EETypeNameDecoder,
allowImplicitDeclarations As Boolean,
containingBinder As Binder)
......@@ -25,9 +28,16 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.ExpressionEvaluator
_containingMethod = containingMethod
_allowImplicitDeclarations = allowImplicitDeclarations
Dim compilation = containingBinder.Compilation
Dim sourceAssembly = compilation.SourceAssembly
_implicitDeclarations = New Dictionary(Of String, LocalSymbol)(CaseInsensitiveComparison.Comparer)
For Each aliasLocal As LocalSymbol In aliasLocals
_implicitDeclarations.Add(aliasLocal.Name, aliasLocal)
For Each [alias] As [Alias] In aliases
Dim local = PlaceholderLocalSymbol.Create(
typeNameDecoder,
containingMethod,
[alias])
_implicitDeclarations.Add(local.Name, local)
Next
End Sub
......
......@@ -31,7 +31,6 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.ExpressionEvaluator
Private ReadOnly _metadataDecoder As MetadataDecoder
Private ReadOnly _currentFrame As MethodSymbol
Private ReadOnly _locals As ImmutableArray(Of LocalSymbol)
Private ReadOnly _aliasLocals As ImmutableArray(Of LocalSymbol)
Private ReadOnly _displayClassVariables As ImmutableDictionary(Of String, DisplayClassVariable)
Private ReadOnly _hoistedParameterNames As ImmutableHashSet(Of String)
Private ReadOnly _localsForBinding As ImmutableArray(Of LocalSymbol)
......@@ -47,14 +46,12 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.ExpressionEvaluator
metadataDecoder As MetadataDecoder,
currentFrame As MethodSymbol,
locals As ImmutableArray(Of LocalSymbol),
aliasLocals As ImmutableArray(Of LocalSymbol),
inScopeHoistedLocals As InScopeHoistedLocals,
methodDebugInfo As MethodDebugInfo,
syntax As ExecutableStatementSyntax)
_syntax = syntax
_currentFrame = currentFrame
_aliasLocals = aliasLocals
Debug.Assert(compilation.Options.RootNamespace = "") ' Default value.
Debug.Assert(methodDebugInfo.ExternAliasRecords.IsDefaultOrEmpty)
......@@ -114,6 +111,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.ExpressionEvaluator
Friend Function Compile(
typeName As String,
methodName As String,
aliases As ImmutableArray(Of [Alias]),
testData As Microsoft.CodeAnalysis.CodeGen.CompilationTestData,
diagnostics As DiagnosticBag,
<Out> ByRef resultProperties As ResultProperties) As CommonPEModuleBuilder
......@@ -132,7 +130,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.ExpressionEvaluator
Dim hasDisplayClassMe = _displayClassVariables.ContainsKey(StringConstants.HoistedMeName)
Dim bindAsExpression = _syntax.Kind = SyntaxKind.PrintStatement
Dim binder = ExtendBinderChain(
_aliasLocals,
aliases,
method,
NamespaceBinder,
hasDisplayClassMe,
......@@ -190,6 +188,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.ExpressionEvaluator
typeName As String,
localBuilder As ArrayBuilder(Of LocalAndMethod),
argumentsOnly As Boolean,
aliases As ImmutableArray(Of [Alias]),
testData As Microsoft.CodeAnalysis.CodeGen.CompilationTestData,
diagnostics As DiagnosticBag) As CommonPEModuleBuilder
......@@ -228,34 +227,38 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.ExpressionEvaluator
Dim methodBuilder = ArrayBuilder(Of MethodSymbol).GetInstance()
If Not argumentsOnly Then
' Pseudo-variables: $exception, $ReturnValue, etc.
For Each aliasLocal As LocalSymbol In _aliasLocals
Dim methodName = GetNextMethodName(methodBuilder)
Dim syntax = SyntaxFactory.IdentifierName(SyntaxFactory.MissingToken(SyntaxKind.IdentifierToken))
Dim aliasMethod = Me.CreateMethod(
container,
methodName,
syntax,
Function(method, diags)
Dim expression = New BoundLocal(syntax, aliasLocal, isLValue:=False, type:=aliasLocal.Type)
Return New BoundReturnStatement(syntax, expression, Nothing, Nothing).MakeCompilerGenerated()
End Function)
localBuilder.Add(New VisualBasicLocalAndMethod(aliasLocal, methodName, If(aliasLocal.IsReadOnly, DkmClrCompilationResultFlags.ReadOnlyResult, DkmClrCompilationResultFlags.None)))
methodBuilder.Add(aliasMethod)
Next
If aliases.Length > 0 Then
' Pseudo-variables: $exception, $ReturnValue, etc.
Dim typeNameDecoder = New EETypeNameDecoder(Me.Compilation, DirectCast(_currentFrame.ContainingModule, PEModuleSymbol))
For Each [alias] As [Alias] In aliases
Dim methodName = GetNextMethodName(methodBuilder)
Dim syntax = SyntaxFactory.IdentifierName(SyntaxFactory.MissingToken(SyntaxKind.IdentifierToken))
Dim local = PlaceholderLocalSymbol.Create(typeNameDecoder, _currentFrame, [alias])
Dim aliasMethod = Me.CreateMethod(
container,
methodName,
syntax,
Function(method, diags)
Dim expression = New BoundLocal(syntax, local, isLValue:=False, type:=local.Type)
Return New BoundReturnStatement(syntax, expression, Nothing, Nothing).MakeCompilerGenerated()
End Function)
localBuilder.Add(MakeLocalAndMethod(local, methodName, If(local.IsReadOnly, DkmClrCompilationResultFlags.ReadOnlyResult, DkmClrCompilationResultFlags.None)))
methodBuilder.Add(aliasMethod)
Next
End If
' "Me" for non-shared methods that are not display class methods
' or display class methods where the display class contains "$VB$Me".
If Not m.IsShared AndAlso (Not m.ContainingType.IsClosureOrStateMachineType() OrElse _displayClassVariables.ContainsKey(GeneratedNames.MakeStateMachineCapturedMeName())) Then
Dim methodName = GetNextMethodName(methodBuilder)
Dim method = Me.GetMeMethod(container, methodName)
localBuilder.Add(New VisualBasicLocalAndMethod("Me", "Me", methodName, DkmClrCompilationResultFlags.None)) ' NOTE: writable in Dev11.
methodBuilder.Add(method)
Dim methodName = GetNextMethodName(methodBuilder)
Dim method = Me.GetMeMethod(container, methodName)
localBuilder.Add(New VisualBasicLocalAndMethod("Me", "Me", methodName, DkmClrCompilationResultFlags.None)) ' NOTE: writable in Dev11.
methodBuilder.Add(method)
End If
End If
End If
' Hoisted method parameters (represented as locals in the EE).
If Not _hoistedParameterNames.IsEmpty Then
' Hoisted method parameters (represented as locals in the EE).
If Not _hoistedParameterNames.IsEmpty Then
Dim localIndex As Integer = 0
For Each local In _localsForBinding
......@@ -341,7 +344,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.ExpressionEvaluator
Dim methodName = GetNextMethodName(methodBuilder)
Dim method = Me.GetLocalMethod(container, methodName, local.Name, localIndex)
localBuilder.Add(New VisualBasicLocalAndMethod(local, methodName, resultFlags))
localBuilder.Add(MakeLocalAndMethod(local, methodName, resultFlags))
methodBuilder.Add(method)
End Sub
......@@ -362,6 +365,15 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.ExpressionEvaluator
methodBuilder.Add(method)
End Sub
Private Shared Function MakeLocalAndMethod(local As LocalSymbol, methodName As String, flags As DkmClrCompilationResultFlags) As LocalAndMethod
' 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 "Me" And "[Me]",
' which it can't do correctly without semantic information.
Dim escapedName = SyntaxHelpers.EscapeKeywordIdentifiers(local.Name)
Dim displayName = If(TryCast(local, PlaceholderLocalSymbol)?.DisplayName, escapedName)
Return New VisualBasicLocalAndMethod(escapedName, displayName, methodName, flags)
End Function
Private Shared Function CreateModuleBuilder(
compilation As VisualBasicCompilation,
methods As ImmutableArray(Of MethodSymbol),
......@@ -559,7 +571,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.ExpressionEvaluator
End Function
Private Shared Function ExtendBinderChain(
aliasLocals As ImmutableArray(Of LocalSymbol),
aliases As ImmutableArray(Of [Alias]),
method As EEMethodSymbol,
binder As Binder,
hasDisplayClassMe As Boolean,
......@@ -591,7 +603,8 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.ExpressionEvaluator
' We have chosen to explicitly disallow pseudo variables in that scenario.
If methodNotType Then
' Method locals and parameters shadow pseudo-variables.
binder = New PlaceholderLocalBinder(method, aliasLocals, allowImplicitDeclarations, binder)
Dim typeNameDecoder = New EETypeNameDecoder(binder.Compilation, DirectCast(substitutedSourceMethod.ContainingModule, PEModuleSymbol))
binder = New PlaceholderLocalBinder(aliases, method, typeNameDecoder, allowImplicitDeclarations, binder)
End If
' Even if there are no parameters or locals, this has the effect of setting
......
......@@ -37,7 +37,6 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.ExpressionEvaluator
Private ReadOnly _metadataDecoder As MetadataDecoder
Private ReadOnly _currentFrame As MethodSymbol
Private ReadOnly _locals As ImmutableArray(Of LocalSymbol)
Private ReadOnly _aliasLocals As ImmutableArray(Of LocalSymbol)
Private ReadOnly _inScopeHoistedLocals As InScopeHoistedLocals
Private ReadOnly _methodDebugInfo As MethodDebugInfo
......@@ -47,7 +46,6 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.ExpressionEvaluator
metadataDecoder As MetadataDecoder,
currentFrame As MethodSymbol,
locals As ImmutableArray(Of LocalSymbol),
aliasLocals As ImmutableArray(Of LocalSymbol),
inScopeHoistedLocals As InScopeHoistedLocals,
methodDebugInfo As MethodDebugInfo)
......@@ -56,7 +54,6 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.ExpressionEvaluator
_metadataDecoder = metadataDecoder
_currentFrame = currentFrame
_locals = locals
_aliasLocals = aliasLocals
_inScopeHoistedLocals = inScopeHoistedLocals
_methodDebugInfo = methodDebugInfo
End Sub
......@@ -104,7 +101,6 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.ExpressionEvaluator
metadataDecoder,
currentFrame,
locals:=Nothing,
aliasLocals:=Nothing,
inScopeHoistedLocals:=Nothing,
methodDebugInfo:=Nothing)
End Function
......@@ -124,7 +120,6 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.ExpressionEvaluator
Friend Shared Function CreateMethodContext(
previous As VisualBasicMetadataContext,
metadataBlocks As ImmutableArray(Of MetadataBlock),
aliases As ImmutableArray(Of [Alias]),
lazyAssemblyReaders As Lazy(Of ImmutableArray(Of AssemblyReaders)),
symReader As Object,
moduleVersionId As Guid,
......@@ -150,7 +145,6 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.ExpressionEvaluator
Return CreateMethodContext(
compilation,
aliases,
lazyAssemblyReaders,
symReader,
moduleVersionId,
......@@ -162,7 +156,6 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.ExpressionEvaluator
Friend Shared Function CreateMethodContext(
compilation As VisualBasicCompilation,
aliases As ImmutableArray(Of [Alias]),
lazyAssemblyReaders As Lazy(Of ImmutableArray(Of AssemblyReaders)),
symReader As Object,
moduleVersionId As Guid,
......@@ -194,10 +187,6 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.ExpressionEvaluator
containingScopes.Free()
Dim locals = localsBuilder.ToImmutableAndFree()
Dim aliasLocalsBuilder = ArrayBuilder(Of LocalSymbol).GetInstance()
GetAliasLocals(aliasLocalsBuilder, aliases, currentFrame, compilation)
Dim aliasLocals = aliasLocalsBuilder.ToImmutableAndFree()
Dim methodDebugInfo As MethodDebugInfo
Dim inScopeHoistedLocals As InScopeHoistedLocals
If IsDteeEntryPoint(currentFrame) Then
......@@ -219,7 +208,6 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.ExpressionEvaluator
metadataDecoder,
currentFrame,
locals,
aliasLocals,
inScopeHoistedLocals,
methodDebugInfo)
End Function
......@@ -346,7 +334,6 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.ExpressionEvaluator
_metadataDecoder,
_currentFrame,
_locals,
_aliasLocals,
_inScopeHoistedLocals,
_methodDebugInfo,
syntax)
......@@ -355,6 +342,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.ExpressionEvaluator
Friend Overrides Function CompileExpression(
expr As String,
compilationFlags As DkmEvaluationFlags,
aliases As ImmutableArray(Of [Alias]),
diagnostics As DiagnosticBag,
<Out> ByRef resultProperties As ResultProperties,
testData As Microsoft.CodeAnalysis.CodeGen.CompilationTestData) As CompileResult
......@@ -375,7 +363,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.ExpressionEvaluator
Dim context = Me.CreateCompilationContext(DirectCast(syntax, ExecutableStatementSyntax))
Dim properties As ResultProperties = Nothing
Dim moduleBuilder = context.Compile(s_typeName, s_methodName, testData, diagnostics, properties)
Dim moduleBuilder = context.Compile(s_typeName, s_methodName, aliases, testData, diagnostics, properties)
If moduleBuilder Is Nothing Then
Return Nothing
End If
......@@ -407,6 +395,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.ExpressionEvaluator
Friend Overrides Function CompileAssignment(
target As String,
expr As String,
aliases As ImmutableArray(Of [Alias]),
diagnostics As DiagnosticBag,
<Out> ByRef resultProperties As ResultProperties,
testData As Microsoft.CodeAnalysis.CodeGen.CompilationTestData) As CompileResult
......@@ -418,7 +407,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.ExpressionEvaluator
Dim context = Me.CreateCompilationContext(assignment)
Dim properties As ResultProperties = Nothing
Dim modulebuilder = context.Compile(s_typeName, s_methodName, testData, diagnostics, properties)
Dim modulebuilder = context.Compile(s_typeName, s_methodName, aliases, testData, diagnostics, properties)
If modulebuilder Is Nothing Then
Return Nothing
End If
......@@ -457,12 +446,13 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.ExpressionEvaluator
Friend Overrides Function CompileGetLocals(
locals As ArrayBuilder(Of LocalAndMethod),
argumentsOnly As Boolean,
aliases As ImmutableArray(Of [Alias]),
diagnostics As DiagnosticBag,
<Out> ByRef typeName As String,
testData As CompilationTestData) As ReadOnlyCollection(Of Byte)
Dim context = Me.CreateCompilationContext(Nothing)
Dim modulebuilder = context.CompileGetLocals(EvaluationContext.s_typeName, locals, argumentsOnly, testData, diagnostics)
Dim modulebuilder = context.CompileGetLocals(s_typeName, locals, argumentsOnly, aliases, testData, diagnostics)
Dim assembly As ReadOnlyCollection(Of Byte) = Nothing
If modulebuilder IsNot Nothing AndAlso locals.Count > 0 Then
......@@ -600,50 +590,6 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.ExpressionEvaluator
Next
End Sub
Private Shared Sub GetAliasLocals(
builder As ArrayBuilder(Of LocalSymbol),
aliases As ImmutableArray(Of [Alias]),
method As MethodSymbol,
compilation As VisualBasicCompilation)
Dim typeNameDecoder = New EETypeNameDecoder(compilation, DirectCast(method.ContainingModule, PEModuleSymbol))
For Each [alias] As [Alias] In aliases
builder.Add(CreateAliasLocal(typeNameDecoder, method, [alias]))
Next
End Sub
Private Shared Function CreateAliasLocal(
typeNameDecoder As TypeNameDecoder(Of PEModuleSymbol, TypeSymbol),
containingMethod As MethodSymbol,
[alias] As [Alias]) As PlaceholderLocalSymbol
Dim typeName = [alias].Type
Debug.Assert(typeName.Length > 0)
Dim type = typeNameDecoder.GetTypeSymbolForSerializedType(typeName)
Debug.Assert(type IsNot Nothing)
Dim name = [alias].FullName
Dim displayName = [alias].Name
Select Case [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
Dim index As Integer = 0
PseudoVariableUtilities.TryParseReturnValueIndex(name, index)
Return New ReturnValueLocalSymbol(containingMethod, name, displayName, type, index)
Case DkmClrAliasKind.ObjectId
Debug.Assert(name.Length > 0 AndAlso name(0) <> "$"c)
Return New ObjectIdLocalSymbol(containingMethod, type, "$" + name, displayName, isReadOnly:=True)
Case DkmClrAliasKind.Variable
Return New ObjectIdLocalSymbol(containingMethod, type, name, displayName, isReadOnly:=False)
Case Else
Throw ExceptionUtilities.UnexpectedValue([alias].Kind)
End Select
End Function
Friend Overrides Function HasDuplicateTypesOrAssemblies(diagnostic As Diagnostic) As Boolean
Select Case CType(diagnostic.Code, ERRID)
Case ERRID.ERR_DuplicateReferenceStrong,
......
......@@ -9,12 +9,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.ExpressionEvaluator
Friend NotInheritable Class ObjectIdLocalSymbol
Inherits PlaceholderLocalSymbol
Private ReadOnly _id As String
Private ReadOnly _isReadOnly As Boolean
Friend Sub New(method As MethodSymbol, type As TypeSymbol, id As String, displayName As String, isReadOnly As Boolean)
MyBase.New(method, id, displayName, type)
_id = id
Friend Sub New(method As MethodSymbol, type As TypeSymbol, name As String, displayName As String, isReadOnly As Boolean)
MyBase.New(method, name, displayName, type)
_isReadOnly = isReadOnly
End Sub
......
......@@ -3,6 +3,8 @@
Imports System.Collections.Immutable
Imports Microsoft.CodeAnalysis.ExpressionEvaluator
Imports Microsoft.CodeAnalysis.VisualBasic.Symbols
Imports Microsoft.CodeAnalysis.VisualBasic.Symbols.Metadata.PE
Imports Microsoft.VisualStudio.Debugger.Clr
Imports Roslyn.Utilities
Namespace Microsoft.CodeAnalysis.VisualBasic.ExpressionEvaluator
......@@ -20,6 +22,38 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.ExpressionEvaluator
Me.DisplayName = displayName
End Sub
Friend Overloads Shared Function Create(
typeNameDecoder As TypeNameDecoder(Of PEModuleSymbol, TypeSymbol),
containingMethod As MethodSymbol,
[alias] As [Alias]) As PlaceholderLocalSymbol
Dim typeName = [alias].Type
Debug.Assert(typeName.Length > 0)
Dim type = typeNameDecoder.GetTypeSymbolForSerializedType(typeName)
Debug.Assert(type IsNot Nothing)
Dim name = [alias].FullName
Dim displayName = [alias].Name
Select Case [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
Dim index As Integer = 0
PseudoVariableUtilities.TryParseReturnValueIndex(name, index)
Return New ReturnValueLocalSymbol(containingMethod, name, displayName, type, index)
Case DkmClrAliasKind.ObjectId
Debug.Assert(name.Length > 0 AndAlso name(0) <> "$"c)
Return New ObjectIdLocalSymbol(containingMethod, type, "$" + name, displayName, isReadOnly:=True)
Case DkmClrAliasKind.Variable
Return New ObjectIdLocalSymbol(containingMethod, type, name, displayName, isReadOnly:=False)
Case Else
Throw ExceptionUtilities.UnexpectedValue([alias].Kind)
End Select
End Function
Friend Overrides ReadOnly Property DeclarationKind As LocalDeclarationKind
Get
Return LocalDeclarationKind.Variable
......
......@@ -62,7 +62,6 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.ExpressionEvaluator
Friend Overrides Function CreateMethodContext(
appDomain As DkmClrAppDomain,
metadataBlocks As ImmutableArray(Of MetadataBlock),
aliases As ImmutableArray(Of [Alias]),
lazyAssemblyReaders As Lazy(Of ImmutableArray(Of AssemblyReaders)),
symReader As Object,
moduleVersionId As Guid,
......@@ -78,7 +77,6 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.ExpressionEvaluator
Dim compilation = metadataBlocks.ToCompilationReferencedModulesOnly(moduleVersionId)
Return EvaluationContext.CreateMethodContext(
compilation,
aliases,
lazyAssemblyReaders,
symReader,
moduleVersionId,
......@@ -92,7 +90,6 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.ExpressionEvaluator
Dim context = EvaluationContext.CreateMethodContext(
previous,
metadataBlocks,
aliases,
lazyAssemblyReaders,
symReader,
moduleVersionId,
......
' Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
Imports Microsoft.CodeAnalysis.ExpressionEvaluator
Imports Microsoft.CodeAnalysis.VisualBasic.Symbols
Imports Microsoft.VisualStudio.Debugger.Evaluation.ClrCompilation
Namespace Microsoft.CodeAnalysis.VisualBasic.ExpressionEvaluator
......@@ -12,17 +11,6 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.ExpressionEvaluator
MyBase.New(localName, localDisplayName, methodName, flags)
End Sub
Public Sub New(local As LocalSymbol, methodName As String, flags As DkmClrCompilationResultFlags)
' 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 "Me" And "[Me]",
' which it can't do correctly without semantic information.
MyClass.New(
SyntaxHelpers.EscapeKeywordIdentifiers(local.Name),
If(TryCast(local, PlaceholderLocalSymbol)?.DisplayName, SyntaxHelpers.EscapeKeywordIdentifiers(local.Name)),
methodName,
flags)
End Sub
Public Overrides Function GetCustomTypeInfo() As CustomTypeInfo
Return Nothing
End Function
......
......@@ -34,8 +34,8 @@ End Class
"
Dim comp = CreateCompilationWithMscorlib({source}, options:=TestOptions.DebugDll)
Dim Runtime = CreateRuntimeInstance(comp)
Dim context = CreateMethodContext(Runtime, "C.M")
Dim runtime = CreateRuntimeInstance(comp)
Dim context = CreateMethodContext(runtime, "C.M")
Dim resultProperties As ResultProperties = Nothing
Dim errorMessage As String = Nothing
......@@ -43,6 +43,7 @@ End Class
context.CompileExpression(
"Me.get_P()",
DkmEvaluationFlags.TreatAsExpression,
NoAliases,
DiagnosticFormatter.Instance,
resultProperties,
errorMessage,
......@@ -170,10 +171,9 @@ End Class
Dim context = CreateMethodContext(
runtime,
methodName:="C.Test")
Dim resultProperties As ResultProperties = Nothing
Dim errorMessage As String = Nothing
Dim testData = New CompilationTestData()
context.CompileExpression("Me.M(Me.P)", resultProperties, errorMessage, testData)
context.CompileExpression("Me.M(Me.P)", errorMessage, testData)
testData.GetMethodData("<>x.<>m0").VerifyIL(
"{
// Code size 13 (0xd)
......
......@@ -33,10 +33,9 @@ End Class
Dim comp = CreateCompilationWithMscorlib({source}, options:=TestOptions.DebugDll)
Dim runtime = CreateRuntimeInstance(comp, includeSymbols:=False)
Dim context = CreateTypeContext(runtime, "Derived")
Dim resultProperties As ResultProperties = Nothing
Dim errorMessage As String = Nothing
Dim testData As New CompilationTestData()
Dim result = context.CompileExpression("GetDebuggerDisplay()", resultProperties, errorMessage, testData)
Dim result = context.CompileExpression("GetDebuggerDisplay()", errorMessage, testData)
Assert.Null(errorMessage)
testData.GetMethodData("<>x.<>m0").VerifyIL("
{
......
......@@ -27,6 +27,8 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.UnitTests
Private ReadOnly _runtimeInstances As ArrayBuilder(Of IDisposable) = ArrayBuilder(Of IDisposable).GetInstance()
Friend Shared ReadOnly NoAliases As ImmutableArray(Of [Alias]) = ImmutableArray(Of [Alias]).Empty
Public Overrides Sub Dispose()
MyBase.Dispose()
......@@ -111,34 +113,6 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.UnitTests
methodOrTypeToken = reader.GetToken(methodOrTypeHandle)
End Sub
Friend Shared Function CreateMethodContext(
runtime As RuntimeInstance,
methodName As String,
ParamArray aliases As [Alias]()) As EvaluationContext
Dim blocks As ImmutableArray(Of MetadataBlock) = Nothing
Dim moduleVersionId As Guid = Nothing
Dim symReader As ISymUnmanagedReader = Nothing
Dim methodToken = 0
Dim localSignatureToken = 0
GetContextState(runtime, methodName, blocks, moduleVersionId, symReader, methodToken, localSignatureToken)
Const methodVersion = 1
Dim ilOffset As Integer = ExpressionCompilerTestHelpers.GetOffset(methodToken, symReader)
Return EvaluationContext.CreateMethodContext(
Nothing,
blocks,
aliases.ToImmutableArray(),
MakeDummyLazyAssemblyReaders(),
symReader,
moduleVersionId,
methodToken,
methodVersion,
ilOffset,
localSignatureToken)
End Function
Friend Shared Function CreateMethodContext(
runtime As RuntimeInstance,
methodName As String,
......@@ -158,7 +132,6 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.UnitTests
Return EvaluationContext.CreateMethodContext(
Nothing,
blocks,
ImmutableArray(Of [Alias]).Empty,
If(lazyAssemblyReaders, MakeDummyLazyAssemblyReaders()),
symReader,
moduleVersionId,
......@@ -231,6 +204,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.UnitTests
Dim result = context.CompileExpression(
expr,
DkmEvaluationFlags.TreatAsExpression,
NoAliases,
VisualBasicDiagnosticFormatter.Instance,
resultProperties,
errorMessage,
......
......@@ -649,10 +649,9 @@ End Module
VerifyMethodData(testData.Methods.Single(Function(m) m.Key.Contains(localAndMethod.MethodName)).Value, expectedType, expectedIL)
locals.Free()
Dim resultProperties As ResultProperties = Nothing
Dim errorMessage As String = Nothing
testData = New CompilationTestData()
context.CompileExpression("Me", resultProperties, errorMessage, testData)
context.CompileExpression("Me", errorMessage, testData)
Assert.Null(errorMessage)
VerifyMethodData(testData.Methods.Single(Function(m) m.Key.Contains("<>m0")).Value, expectedType, expectedIL)
End Sub
......@@ -684,10 +683,9 @@ End Module
AssertEx.None(locals, Function(l) l.LocalName.Contains("Me"))
locals.Free()
Dim resultProperties As ResultProperties = Nothing
Dim errorMessage As String = Nothing
testData = New CompilationTestData()
context.CompileExpression("Me", resultProperties, errorMessage, testData)
context.CompileExpression("Me", errorMessage, testData)
Assert.Contains(errorMessage,
{
"(1,2): error BC32001: 'Me' is not valid within a Module.",
......@@ -695,7 +693,7 @@ End Module
})
testData = New CompilationTestData()
context.CompileExpression("MyBase.ToString()", resultProperties, errorMessage, testData)
context.CompileExpression("MyBase.ToString()", errorMessage, testData)
Assert.Contains(errorMessage,
{
"(1,2): error BC32001: 'MyBase' is not valid within a Module.",
......@@ -703,7 +701,7 @@ End Module
})
testData = New CompilationTestData()
context.CompileExpression("MyClass.ToString()", resultProperties, errorMessage, testData)
context.CompileExpression("MyClass.ToString()", errorMessage, testData)
Assert.Contains(errorMessage,
{
"(1,2): error BC30470: 'MyClass' cannot be used outside of a class.",
......@@ -731,7 +729,7 @@ End Class
Dim resultProperties As ResultProperties = Nothing
Dim errorMessage As String = Nothing
Dim testData = New CompilationTestData()
context.CompileExpression("Me.x", resultProperties, errorMessage, testData)
context.CompileExpression("Me.x", errorMessage, testData)
Assert.Null(errorMessage)
testData.GetMethodData("<>x.<>m0").VerifyIL("
{
......@@ -767,7 +765,7 @@ End Class
Dim resultProperties As ResultProperties = Nothing
Dim errorMessage As String = Nothing
Dim testData = New CompilationTestData()
context.CompileExpression("Me.x", resultProperties, errorMessage, testData)
context.CompileExpression("Me.x", errorMessage, testData)
Assert.Null(errorMessage)
testData.GetMethodData("<>x.<>m0").VerifyIL("
{
......@@ -805,7 +803,7 @@ End Class
Dim resultProperties As ResultProperties = Nothing
Dim errorMessage As String = Nothing
Dim testData = New CompilationTestData()
context.CompileExpression("Me.x", resultProperties, errorMessage, testData)
context.CompileExpression("Me.x", errorMessage, testData)
Assert.Null(errorMessage)
testData.GetMethodData("<>x.<>m0").VerifyIL("
{
......@@ -846,7 +844,7 @@ End Class
Dim resultProperties As ResultProperties = Nothing
Dim errorMessage As String = Nothing
Dim testData = New CompilationTestData()
context.CompileExpression("MyBase.x", resultProperties, errorMessage, testData)
context.CompileExpression("MyBase.x", errorMessage, testData)
Assert.Null(errorMessage)
testData.GetMethodData("<>x.<>m0").VerifyIL("
{
......@@ -890,7 +888,7 @@ End Class
Dim resultProperties As ResultProperties = Nothing
Dim errorMessage As String = Nothing
Dim testData = New CompilationTestData()
context.CompileExpression("MyBase.x", resultProperties, errorMessage, testData)
context.CompileExpression("MyBase.x", errorMessage, testData)
Assert.Null(errorMessage)
testData.GetMethodData("<>x.<>m0").VerifyIL("
{
......@@ -932,7 +930,7 @@ End Class
Dim resultProperties As ResultProperties = Nothing
Dim errorMessage As String = Nothing
Dim testData = New CompilationTestData()
context.CompileExpression("MyBase.x", resultProperties, errorMessage, testData)
context.CompileExpression("MyBase.x", errorMessage, testData)
Assert.Null(errorMessage)
testData.GetMethodData("<>x.<>m0").VerifyIL("
{
......
......@@ -726,12 +726,11 @@ End Class
Dim context = CreateMethodContext(runtime, "D._Closure$__2-0.VB$StateMachine___Lambda$__0.MoveNext")
Dim errorMessage As String = Nothing
Dim testData As CompilationTestData = Nothing
context.CompileExpression("t1", errorMessage)
Assert.Equal("(1,2): error BC30043: 't1' is valid only within an instance method.", errorMessage)
testData = New CompilationTestData()
Dim testData = New CompilationTestData()
context.CompileExpression("u1", errorMessage, testData)
Assert.Null(errorMessage)
testData.GetMethodData("<>x.<>m0").VerifyIL("
......@@ -1399,13 +1398,10 @@ End Class
GetContextState(runtime, "C.VB$StateMachine_1_M.MoveNext", blocks, moduleVersionId, symReader, methodToken, localSignatureToken)
Const methodVersion = 1
Dim aliases = ImmutableArray(Of [Alias]).Empty
Dim ilOffset = ExpressionCompilerTestHelpers.GetOffset(methodToken, symReader, atLineNumber:=100)
Dim context = EvaluationContext.CreateMethodContext(
Nothing,
blocks,
aliases,
MakeDummyLazyAssemblyReaders(),
symReader,
moduleVersionId,
......@@ -1424,7 +1420,6 @@ End Class
context = EvaluationContext.CreateMethodContext(
New VisualBasicMetadataContext(blocks, context),
blocks,
aliases,
MakeDummyLazyAssemblyReaders(),
symReader,
moduleVersionId,
......
......@@ -135,7 +135,8 @@ End Class"
Dim runtime = CreateRuntimeInstance(comp)
Dim context = CreateMethodContext(
runtime,
"C.M",
"C.M")
Dim aliases = ImmutableArray.Create(
ExceptionAlias(GetType(System.IO.IOException)),
ReturnValueAlias(2, GetType(String)),
ReturnValueAlias(),
......@@ -149,6 +150,7 @@ End Class"
context.CompileGetLocals(
locals,
argumentsOnly:=True,
aliases:=aliases,
diagnostics:=diagnostics,
typeName:=typeName,
testData:=testData)
......@@ -160,6 +162,7 @@ End Class"
context.CompileGetLocals(
locals,
argumentsOnly:=False,
aliases:=aliases,
diagnostics:=diagnostics,
typeName:=typeName,
testData:=testData)
......@@ -276,14 +279,13 @@ End Class"
}")
locals.Free()
Dim resultProperties As ResultProperties = Nothing
Dim errorMessage As String = Nothing
testData = New CompilationTestData()
context.CompileExpression("b", resultProperties, errorMessage, testData, VisualBasicDiagnosticFormatter.Instance)
context.CompileExpression("b", errorMessage, testData, VisualBasicDiagnosticFormatter.Instance)
Assert.Equal(errorMessage, "(1) : error BC30451: 'b' is not declared. It may be inaccessible due to its protection level.")
testData = New CompilationTestData()
context.CompileExpression("a(1)", resultProperties, errorMessage, testData)
context.CompileExpression("a(1)", errorMessage, testData)
testData.GetMethodData("<>x.<>m0").VerifyIL(
"{
// Code size 4 (0x4)
......@@ -1802,12 +1804,12 @@ End Class
methodName:="C.M")
Dim errorMessage As String = Nothing
Dim testData As New CompilationTestData()
context.CompileAssignment("d", "Nothing", errorMessage, testData, VisualBasicDiagnosticFormatter.Instance)
context.CompileAssignment("d", "Nothing", errorMessage, formatter:=VisualBasicDiagnosticFormatter.Instance)
Assert.Equal("(1) : error BC30074: Constant cannot be the target of an assignment.", errorMessage)
Dim locals = ArrayBuilder(Of LocalAndMethod).GetInstance()
Dim typeName As String = Nothing
Dim testData As New CompilationTestData()
context.CompileGetLocals(locals, argumentsOnly:=False, typeName:=typeName, testData:=testData)
Assert.Equal(2, locals.Count)
VerifyLocal(testData, typeName, locals(0), "<>m0", "dt", expectedILOpt:=
......@@ -1851,12 +1853,12 @@ End Class
methodName:="C.M")
Dim errorMessage As String = Nothing
Dim testData As New CompilationTestData()
context.CompileAssignment("d", "Nothing", errorMessage, testData, VisualBasicDiagnosticFormatter.Instance)
context.CompileAssignment("d", "Nothing", errorMessage, formatter:=VisualBasicDiagnosticFormatter.Instance)
Assert.Equal("(1) : error BC30074: Constant cannot be the target of an assignment.", errorMessage)
Dim locals = ArrayBuilder(Of LocalAndMethod).GetInstance()
Dim typeName As String = Nothing
Dim testData As New CompilationTestData()
context.CompileGetLocals(locals, argumentsOnly:=False, typeName:=typeName, testData:=testData)
Assert.Equal(1, locals.Count)
VerifyLocal(testData, typeName, locals(0), "<>m0", "d", expectedFlags:=DkmClrCompilationResultFlags.ReadOnlyResult, expectedILOpt:=
......
......@@ -95,6 +95,7 @@ End Class
context.CompileExpression(
"parameter",
DkmEvaluationFlags.TreatAsExpression,
NoAliases,
DiagnosticFormatter.Instance,
resultProperties,
actualError,
......@@ -151,6 +152,7 @@ End Class
context.CompileExpression(
"New Forwarded()",
DkmEvaluationFlags.TreatAsExpression,
NoAliases,
DiagnosticFormatter.Instance,
resultProperties,
actualError,
......@@ -183,6 +185,7 @@ End Class
context.CompileExpression(
"<value/>",
DkmEvaluationFlags.TreatAsExpression,
NoAliases,
DiagnosticFormatter.Instance,
resultProperties,
actualError,
......@@ -218,6 +221,7 @@ End Class
context.CompileExpression(
"o = o",
DkmEvaluationFlags.TreatAsExpression,
NoAliases,
DiagnosticFormatter.Instance,
resultProperties,
actualError,
......@@ -290,6 +294,7 @@ End Class
context.CompileExpression(
"array.Count()",
DkmEvaluationFlags.TreatAsExpression,
NoAliases,
DiagnosticFormatter.Instance,
resultProperties,
actualError,
......@@ -302,6 +307,7 @@ End Class
context.CompileExpression(
"array.NoSuchMethod()",
DkmEvaluationFlags.TreatAsExpression,
NoAliases,
DiagnosticFormatter.Instance,
resultProperties,
actualError,
......@@ -338,8 +344,8 @@ End Class
New SymReader(pdbBytes))
Dim context = CreateMethodContext(
runtime,
"C.M",
ExceptionAlias("Microsoft.CSharp.RuntimeBinder.RuntimeBinderException, Microsoft.CSharp, Version = 4.0.0.0, Culture = neutral, PublicKeyToken = b03f5f7f11d50a3a", stowed:=True))
"C.M")
Dim aliases = ImmutableArray.Create(ExceptionAlias("Microsoft.CSharp.RuntimeBinder.RuntimeBinderException, Microsoft.CSharp, Version = 4.0.0.0, Culture = neutral, PublicKeyToken = b03f5f7f11d50a3a", stowed:=True))
Const expectedError = "(1,1): error BC30002: Type 'System.Void' is not defined."
Dim expectedMissingAssemblyIdentity = comp.Assembly.CorLibrary.Identity
......@@ -351,6 +357,7 @@ End Class
context.CompileExpression(
"$stowedexception",
DkmEvaluationFlags.TreatAsExpression,
aliases,
DiagnosticFormatter.Instance,
resultProperties,
actualError,
......@@ -386,6 +393,7 @@ End Class
context.CompileExpression(
"Windows.UI.Colors",
DkmEvaluationFlags.None,
NoAliases,
DiagnosticFormatter.Instance,
resultProperties,
actualError,
......@@ -423,6 +431,7 @@ End Class
context.CompileExpression(
"Windows.[UI].Xaml.Application",
DkmEvaluationFlags.None,
NoAliases,
DiagnosticFormatter.Instance,
resultProperties,
actualError,
......@@ -457,6 +466,7 @@ End Class
context.CompileExpression(
"GetType([Windows].UI.Colors)",
DkmEvaluationFlags.None,
NoAliases,
DiagnosticFormatter.Instance,
resultProperties,
actualError,
......
......@@ -32,10 +32,9 @@ End Class"
Dim context = CreateMethodContext(
runtime,
methodName:="C.M")
Dim resultProperties As ResultProperties = Nothing
Dim errorMessage As String = Nothing
Dim testData = New CompilationTestData()
context.CompileExpression("Me", resultProperties, errorMessage, testData, VisualBasicDiagnosticFormatter.Instance)
context.CompileExpression("Me", errorMessage, testData, VisualBasicDiagnosticFormatter.Instance)
Assert.Null(errorMessage)
testData.GetMethodData("<>x.<>m0").VerifyIL(
"{
......
......@@ -116,12 +116,10 @@ End Class"
typeToken)
Dim errorMessage As String = Nothing
' A is ambiguous since there were no explicit references to AS1 or AS2.
Dim testData = New CompilationTestData()
context.CompileExpression("New A()", errorMessage, testData)
context.CompileExpression("New A()", errorMessage)
Assert.Equal(errorMessage, "(1,6): error BC30554: 'A' is ambiguous.")
testData = New CompilationTestData()
' Ideally, B should be resolved to BS1.
context.CompileExpression("New B()", errorMessage, testData)
context.CompileExpression("New B()", errorMessage)
Assert.Equal(errorMessage, "(1,6): error BC30554: 'B' is ambiguous.")
' Compile expression with method context.
......@@ -129,7 +127,6 @@ End Class"
context = EvaluationContext.CreateMethodContext(
previous,
methodBlocks,
ImmutableArray(Of [Alias]).Empty,
MakeDummyLazyAssemblyReaders(),
symReader,
moduleVersionId,
......@@ -138,9 +135,8 @@ End Class"
ilOffset:=0,
localSignatureToken:=localSignatureToken)
Assert.Equal(previous.Compilation, context.Compilation) ' re-use type context compilation
testData = New CompilationTestData()
' Ideally, B should be resolved to BS1.
context.CompileExpression("New B()", errorMessage, testData)
context.CompileExpression("New B()", errorMessage)
Assert.Equal(errorMessage, "(1,6): error BC30554: 'B' is ambiguous.")
End Using
End Sub
......@@ -365,7 +361,6 @@ End Class"
Dim context = EvaluationContext.CreateMethodContext(
Nothing,
blocks,
ImmutableArray(Of [Alias]).Empty,
MakeDummyLazyAssemblyReaders(),
symReader,
moduleVersionId,
......@@ -374,10 +369,10 @@ End Class"
ilOffset:=0,
localSignatureToken:=localSignatureToken)
Dim errorMessage As String = Nothing
Dim testData As New CompilationTestData()
context.CompileExpression("F()", errorMessage, testData)
context.CompileExpression("F()", errorMessage)
Assert.Equal(errorMessage, "(1,2): error BC30562: 'F' is ambiguous between declarations in Modules 'N.M, N.M'.")
Dim testData As New CompilationTestData()
Dim contextFactory = CreateMethodContextFactory(moduleVersionId, symReader, methodToken, localSignatureToken)
ExpressionCompilerTestHelpers.CompileExpressionWithRetry(blocks, "F()", contextFactory, getMetaDataBytesPtr:=Nothing, errorMessage:=errorMessage, testData:=testData)
Assert.Null(errorMessage)
......@@ -414,7 +409,6 @@ End Class"
Dim compilation = If(useReferencedModulesOnly, blocks.ToCompilationReferencedModulesOnly(moduleVersionId), blocks.ToCompilation())
Return EvaluationContext.CreateMethodContext(
compilation,
ImmutableArray(Of [Alias]).Empty,
MakeDummyLazyAssemblyReaders(),
symReader,
moduleVersionId,
......
......@@ -294,6 +294,7 @@ End Class
context.CompileAssignment(
"P",
"1",
NoAliases,
DiagnosticFormatter.Instance,
resultProperties,
errorMessage,
......@@ -329,6 +330,7 @@ End Class
context.CompileExpression(
"z = 1", ' VB only supports implicit declarations
DkmEvaluationFlags.None,
NoAliases,
DiagnosticFormatter.Instance,
resultProperties,
errorMessage,
......
......@@ -835,6 +835,7 @@ End Class
Dim result = context.CompileExpression(
expr,
compilationFlags,
NoAliases,
VisualBasicDiagnosticFormatter.Instance,
resultProperties,
errorMessage,
......
......@@ -149,13 +149,11 @@ End Class"
' Instance method.
Dim context = CreateMethodContext(runtime, "C._Closure$__1-0._Lambda$__0")
Dim errorMessage As String = Nothing
Dim testData = New CompilationTestData()
context.CompileExpression("If(x, y)", errorMessage, testData)
context.CompileExpression("If(x, y)", errorMessage)
Assert.Equal(errorMessage, "(1,8): error BC30451: 'y' is not declared. It may be inaccessible due to its protection level.")
' Shared method.
context = CreateMethodContext(runtime, "C._Closure$__2-0._Lambda$__0")
testData = New CompilationTestData()
context.CompileExpression("x + z", errorMessage, testData)
context.CompileExpression("x + z", errorMessage)
Assert.Equal(errorMessage, "(1,6): error BC30451: 'z' is not declared. It may be inaccessible due to its protection level.")
End Sub
......@@ -185,13 +183,9 @@ End Class"
Dim methodToken = 0
Dim localSignatureToken = 0
GetContextState(runtime, "C.F(Boolean)", blocks, moduleVersionId, symReader, methodToken, localSignatureToken)
Dim aliases = ImmutableArray(Of [Alias]).Empty
Dim context = EvaluationContext.CreateMethodContext(
Nothing,
blocks,
aliases,
MakeDummyLazyAssemblyReaders(),
symReader,
moduleVersionId,
......@@ -234,7 +228,6 @@ End Class"
context = EvaluationContext.CreateMethodContext(
Nothing,
blocks,
aliases,
MakeDummyLazyAssemblyReaders(),
symReader,
moduleVersionId,
......
......@@ -43,10 +43,9 @@ End Class"
exeBytes,
New SymReader(pdbBytes))
Dim context = CreateMethodContext(runtime, "C.M")
Dim resultProperties As ResultProperties = Nothing
Dim errorMessage As String = Nothing
Dim testData = New CompilationTestData()
context.CompileExpression("If(p Is Nothing, f, Nothing)", resultProperties, errorMessage, testData)
context.CompileExpression("If(p Is Nothing, f, Nothing)", errorMessage, testData)
testData.GetMethodData("<>x.<>m0").VerifyIL(
"{
// Code size 7 (0x7)
......@@ -122,10 +121,9 @@ End Class"
End Class"
Dim runtime = CreateRuntime(source, compileReferences, runtimeReferences)
Dim context = CreateMethodContext(runtime, "C.M")
Dim resultProperties As ResultProperties = Nothing
Dim errorMessage As String = Nothing
Dim testData = New CompilationTestData()
context.CompileExpression("If(a, If(b, If(t, f)))", resultProperties, errorMessage, testData)
context.CompileExpression("If(a, If(b, If(t, f)))", errorMessage, testData)
Assert.Null(errorMessage)
testData.GetMethodData("<>x.<>m0").VerifyIL(
"{
......@@ -147,7 +145,7 @@ End Class"
IL_0010: ret
}")
testData = New CompilationTestData()
Dim result = context.CompileExpression("f", resultProperties, errorMessage, testData)
Dim result = context.CompileExpression("f", errorMessage, testData)
Assert.Null(errorMessage)
Dim methodData = testData.GetMethodData("<>x.<>m0")
methodData.VerifyIL(
......@@ -199,23 +197,18 @@ End Class"
ImmutableArray.Create(MscorlibRef).Concat(ExpressionCompilerTestHelpers.GetRuntimeWinMds("Windows.Storage", "Windows.Foundation.Collections")))
Dim context = CreateMethodContext(
runtime,
"C.M",
"C.M")
Dim aliases = ImmutableArray.Create(
VariableAlias("s", "Windows.Storage.StorageFolder, Windows.Storage, Version=255.255.255.255, Culture=neutral, PublicKeyToken=null, ContentType=WindowsRuntime"),
VariableAlias("d", "Windows.Foundation.DateTime, Windows.Foundation, Version=255.255.255.255, Culture=neutral, PublicKeyToken=null, ContentType=WindowsRuntime"))
Dim resultProperties As ResultProperties = Nothing
Dim errorMessage As String = Nothing
Dim missingAssemblyIdentities As ImmutableArray(Of AssemblyIdentity) = Nothing
Dim testData = New CompilationTestData()
context.CompileExpression(
"If(DirectCast(s.Attributes, Object), d.UniversalTime)",
DkmEvaluationFlags.TreatAsExpression,
DiagnosticFormatter.Instance,
resultProperties,
aliases,
errorMessage,
missingAssemblyIdentities,
EnsureEnglishUICulture.PreferredOrNull,
testData)
Assert.Empty(missingAssemblyIdentities)
testData.GetMethodData("<>x.<>m0").VerifyIL(
"{
// Code size 55 (0x37)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册