提交 6f53207a 编写于 作者: B beep boop 提交者: RoslynTeam

Move Expression Evaluator to Open (changeset 1411117)

上级 ccb1afd7
// 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 System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics;
using Microsoft.CodeAnalysis.CSharp.Symbols;
using Roslyn.Utilities;
namespace Microsoft.CodeAnalysis.CSharp.ExpressionEvaluator
{
internal sealed class EEMethodBinder : Binder
{
private readonly MethodSymbol _containingMethod;
private readonly int _parameterOffset;
private readonly ImmutableArray<ParameterSymbol> _targetParameters;
private readonly Binder _sourceBinder;
internal EEMethodBinder(EEMethodSymbol method, MethodSymbol containingMethod, Binder next) : base(next)
{
// There are a lot of method symbols floating around and we're doing some subtle things with them.
// 1) method is the EEMethodSymbol that we're going to synthesize and hand to the debugger to evaluate.
// 2) containingMethod is the method that we are conceptually in, e.g. the method containing the
// lambda that is on top of the call stack. Any type parameters will have been replaced with the
// corresponding type parameters from (1) and its containing type.
// 3) method.SubstitutedSourceMethod is the method that we are actually in, e.g. a lambda method in
// a display class. Any type parameters will have been replaced with the corresponding type parameters
// from (1).
// So why do we need all these methods?
// 1) gives us the parameters that we need to actually bind to (it's no good to bind to the symbols
// owned by (2) or (3)). Also, it happens to contain (3), so we don't need to pass (3) explicitly.
// 2) is where we want to pretend we're binding expressions, so we make it the containing symbol of
// this binder.
// 3) is where we'll pretend to be for the purposes of looking up parameters by name. However, any
// parameters we bind to from (3) will be replaced by the corresponding parameters from (1).
_containingMethod = containingMethod;
var substitutedSourceMethod = method.SubstitutedSourceMethod;
_parameterOffset = substitutedSourceMethod.IsStatic ? 0 : 1;
_targetParameters = method.Parameters;
_sourceBinder = new InMethodBinder(substitutedSourceMethod, new BuckStopsHereBinder(next.Compilation));
}
internal override void LookupSymbolsInSingleBinder(LookupResult result, string name, int arity, ConsList<Symbol> basesBeingResolved, LookupOptions options, Binder originalBinder, bool diagnose, ref HashSet<DiagnosticInfo> useSiteDiagnostics)
{
_sourceBinder.LookupSymbolsInSingleBinder(result, name, arity, basesBeingResolved, options, this, diagnose, ref useSiteDiagnostics);
var symbols = result.Symbols;
for (int i = 0; i < symbols.Count; i++)
{
// Type parameters requiring mapping to the target type and
// should be found by WithMethodTypeParametersBinder instead.
var parameter = (ParameterSymbol)symbols[i];
Debug.Assert(parameter.ContainingSymbol == _sourceBinder.ContainingMemberOrLambda);
symbols[i] = _targetParameters[parameter.Ordinal + _parameterOffset];
}
}
protected override void AddLookupSymbolsInfoInSingleBinder(LookupSymbolsInfo info, LookupOptions options, Binder originalBinder)
{
throw new NotImplementedException();
}
internal override Symbol ContainingMemberOrLambda
{
get { return _containingMethod; }
}
}
}
// 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 System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics;
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 Roslyn.Utilities;
namespace Microsoft.CodeAnalysis.CSharp.ExpressionEvaluator
{
internal sealed class PlaceholderLocalBinder : LocalScopeBinder
{
private readonly InspectionContext _inspectionContext;
private readonly TypeNameDecoder<PEModuleSymbol, TypeSymbol> _typeNameDecoder;
private readonly CSharpSyntaxNode _syntax;
private readonly MethodSymbol _containingMethod;
internal PlaceholderLocalBinder(
InspectionContext inspectionContext,
TypeNameDecoder<PEModuleSymbol, TypeSymbol> typeNameDecoder,
CSharpSyntaxNode syntax,
MethodSymbol containingMethod,
Binder next) :
base(next)
{
_inspectionContext = inspectionContext;
_typeNameDecoder = typeNameDecoder;
_syntax = syntax;
_containingMethod = containingMethod;
}
internal sealed override void LookupSymbolsInSingleBinder(
LookupResult result,
string name,
int arity,
ConsList<Symbol> basesBeingResolved,
LookupOptions options,
Binder originalBinder,
bool diagnose,
ref HashSet<DiagnosticInfo> useSiteDiagnostics)
{
if ((options & (LookupOptions.NamespaceAliasesOnly | LookupOptions.NamespacesOrTypesOnly | LookupOptions.LabelsOnly)) != 0)
{
return;
}
var local = this.LookupPlaceholder(name);
if ((object)local == null)
{
base.LookupSymbolsInSingleBinder(result, name, arity, basesBeingResolved, options, originalBinder, diagnose, ref useSiteDiagnostics);
}
else
{
result.MergeEqual(this.CheckViability(local, arity, options, null, diagnose, ref useSiteDiagnostics, basesBeingResolved));
}
}
protected sealed override void AddLookupSymbolsInfoInSingleBinder(LookupSymbolsInfo info, LookupOptions options, Binder originalBinder)
{
throw new NotImplementedException();
}
protected override ImmutableArray<LocalSymbol> BuildLocals()
{
var builder = ArrayBuilder<LocalSymbol>.GetInstance();
var declaration = _syntax as LocalDeclarationStatementSyntax;
if (declaration != null)
{
var kind = declaration.IsConst ? LocalDeclarationKind.Constant : LocalDeclarationKind.RegularVariable;
foreach (var variable in declaration.Declaration.Variables)
{
var local = SourceLocalSymbol.MakeLocal(_containingMethod, this, declaration.Declaration.Type, variable.Identifier, kind, variable.Initializer);
builder.Add(local);
}
}
return builder.ToImmutableAndFree();
}
private PlaceholderLocalSymbol LookupPlaceholder(string name)
{
if (name.StartsWith("0x", StringComparison.OrdinalIgnoreCase))
{
var valueText = name.Substring(2);
ulong address;
if (!ulong.TryParse(valueText, NumberStyles.AllowHexSpecifier, CultureInfo.InvariantCulture, out address))
{
// Invalid value should have been caught by Lexer.
throw ExceptionUtilities.UnexpectedValue(valueText);
}
return new ObjectAddressLocalSymbol(_containingMethod, name, this.Compilation.GetSpecialType(SpecialType.System_Object), address);
}
PseudoVariableKind kind;
string id;
int index;
if (!PseudoVariableUtilities.TryParseVariableName(name, caseSensitive: true, kind: out kind, id: out id, index: out index))
{
return null;
}
var typeName = PseudoVariableUtilities.GetTypeName(_inspectionContext, kind, id, index);
if (typeName == null)
{
return null;
}
Debug.Assert(typeName.Length > 0);
var type = _typeNameDecoder.GetTypeSymbolForSerializedType(typeName);
Debug.Assert((object)type != null);
switch (kind)
{
case PseudoVariableKind.Exception:
case PseudoVariableKind.StowedException:
return new ExceptionLocalSymbol(_containingMethod, id, type);
case PseudoVariableKind.ReturnValue:
return new ReturnValueLocalSymbol(_containingMethod, id, type, index);
case PseudoVariableKind.ObjectId:
return new ObjectIdLocalSymbol(_containingMethod, type, id, isWritable: false);
case PseudoVariableKind.DeclaredLocal:
return new ObjectIdLocalSymbol(_containingMethod, type, id, isWritable: true);
default:
throw ExceptionUtilities.UnexpectedValue(kind);
}
}
}
}
// 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.CSharp.Symbols;
using Roslyn.Utilities;
using System.Collections.Immutable;
using System.Diagnostics;
using System.Linq;
using System.Threading;
namespace Microsoft.CodeAnalysis.CSharp.ExpressionEvaluator
{
internal sealed class WithTypeArgumentsBinder : WithTypeParametersBinder
{
private readonly ImmutableArray<TypeSymbol> _typeArguments;
private MultiDictionary<string, TypeParameterSymbol> _lazyTypeParameterMap;
internal WithTypeArgumentsBinder(ImmutableArray<TypeSymbol> typeArguments, Binder next)
: base(next)
{
Debug.Assert(!typeArguments.IsDefaultOrEmpty);
Debug.Assert(typeArguments.All(ta => ta.Kind == SymbolKind.TypeParameter));
_typeArguments = typeArguments;
}
protected override MultiDictionary<string, TypeParameterSymbol> TypeParameterMap
{
get
{
if (_lazyTypeParameterMap == null)
{
var result = new MultiDictionary<string, TypeParameterSymbol>();
foreach (TypeParameterSymbol tps in _typeArguments)
{
result.Add(tps.Name, tps);
}
Interlocked.CompareExchange(ref _lazyTypeParameterMap, result, null);
}
return _lazyTypeParameterMap;
}
}
protected override void AddLookupSymbolsInfoInSingleBinder(LookupSymbolsInfo result, LookupOptions options, Binder originalBinder)
{
if (CanConsiderTypeParameters(options))
{
foreach (var parameter in _typeArguments)
{
if (originalBinder.CanAddLookupSymbolInfo(parameter, options, null))
{
result.AddSymbol(parameter, parameter.Name, 0);
}
}
}
}
}
}
// 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 System;
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;
namespace Microsoft.CodeAnalysis.CSharp.ExpressionEvaluator
{
[DkmReportNonFatalWatsonException(ExcludeExceptionType = typeof(NotImplementedException)), DkmContinueCorruptingException]
internal sealed class CSharpExpressionCompiler : ExpressionCompiler
{
private static readonly DkmCompilerId s_compilerId = new DkmCompilerId(DkmVendorId.Microsoft, DkmLanguageId.CSharp);
internal override DiagnosticFormatter DiagnosticFormatter
{
get { return DiagnosticFormatter.Instance; }
}
internal override DkmCompilerId CompilerId
{
get { return s_compilerId; }
}
internal override EvaluationContextBase CreateTypeContext(
DkmClrAppDomain appDomain,
ImmutableArray<MetadataBlock> metadataBlocks,
Guid moduleVersionId,
int typeToken)
{
var previous = appDomain.GetDataItem<CSharpMetadataContext>();
var context = EvaluationContext.CreateTypeContext(
appDomain.GetDataItem<CSharpMetadataContext>(),
metadataBlocks,
moduleVersionId,
typeToken);
// New type context is not attached to the AppDomain since it is less
// re-usable than the previous attached method context. (We could hold
// on to it if we don't have a previous method context but it's unlikely
// that we evaluated a type-level expression before a method-level.)
Debug.Assert(previous == null || context != previous.EvaluationContext);
return context;
}
internal override EvaluationContextBase CreateMethodContext(
DkmClrAppDomain appDomain,
ImmutableArray<MetadataBlock> metadataBlocks,
Lazy<ImmutableArray<AssemblyReaders>> unusedLazyAssemblyReaders,
object symReader,
Guid moduleVersionId,
int methodToken,
int methodVersion,
int ilOffset,
int localSignatureToken)
{
var previous = appDomain.GetDataItem<CSharpMetadataContext>();
var context = EvaluationContext.CreateMethodContext(
previous,
metadataBlocks,
symReader,
moduleVersionId,
methodToken,
methodVersion,
ilOffset,
localSignatureToken);
if (previous == null || context != previous.EvaluationContext)
{
appDomain.SetDataItem(DkmDataCreationDisposition.CreateAlways, new CSharpMetadataContext(context));
}
return context;
}
internal override bool RemoveDataItem(DkmClrAppDomain appDomain)
{
return appDomain.RemoveDataItem<CSharpMetadataContext>();
}
}
}
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ImportGroup Label="Settings">
<Import Project="..\..\..\..\Tools\Microsoft.CodeAnalysis.Toolset.Open\Targets\VSL.Settings.targets" />
<Import Project="..\..\..\..\..\build\VSL.Settings.Closed.targets" />
</ImportGroup>
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{FD6BA96C-7905-4876-8BCC-E38E2CA64F31}</ProjectGuid>
<OutputType>Library</OutputType>
<RootNamespace>Microsoft.CodeAnalysis.CSharp.ExpressionEvaluator</RootNamespace>
<AssemblyName>Microsoft.CodeAnalysis.CSharp.ExpressionEvaluator.ExpressionCompiler</AssemblyName>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<SolutionDir Condition="'$(SolutionDir)' == '' OR '$(SolutionDir)' == '*Undefined*'">..\..\..\..\..\</SolutionDir>
<UseCommonOutputDirectory>True</UseCommonOutputDirectory>
<RestorePackages>true</RestorePackages>
<!-- Don't transitively copy output files, since everything builds to the same folder. -->
</PropertyGroup>
<ItemGroup Label="File References">
<Reference Include="$(OutDir)Microsoft.VisualStudio.Debugger.Engine.dll" />
<Reference Include="System.Reflection.Metadata, Version=1.0.18.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\..\..\..\packages\System.Reflection.Metadata.1.0.18-beta\lib\portable-net45+win8\System.Reflection.Metadata.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup Label="Project References">
<ProjectReference Include="..\..\..\Core\Source\Concord\Concord.csproj">
<Project>{5002636a-fe8d-40bf-8818-ab513a2194fa}</Project>
<Name>Concord</Name>
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
</ProjectReference>
<ProjectReference Include="..\..\..\..\Compilers\Core\Desktop\CodeAnalysis.Desktop.csproj">
<Project>{dfa21ca1-7f96-47ee-940c-069858e81727}</Project>
<Name>CodeAnalysis.Desktop</Name>
</ProjectReference>
<ProjectReference Include="..\..\..\..\Compilers\Core\Portable\CodeAnalysis.csproj">
<Project>{1EE8CAD3-55F9-4D91-96B2-084641DA9A6C}</Project>
<Name>CodeAnalysis</Name>
</ProjectReference>
<ProjectReference Include="..\..\..\..\Compilers\CSharp\Portable\CSharpCodeAnalysis.csproj">
<Project>{B501A547-C911-4A05-AC6E-274A50DFF30E}</Project>
<Name>CSharpCodeAnalysis</Name>
</ProjectReference>
<ProjectReference Include="..\..\..\Core\Source\ExpressionCompiler\ExpressionCompiler.csproj">
<Project>{b8da3a90-a60c-42e3-9d8e-6c67b800c395}</Project>
<Name>ExpressionCompiler</Name>
</ProjectReference>
</ItemGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DefineConstants>TRACE;DEBUG</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Collections.Immutable, Version=1.1.33.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\..\..\..\packages\System.Collections.Immutable.1.1.33-beta\lib\portable-net45+win8+wp8+wpa81\System.Collections.Immutable.dll</HintPath>
</Reference>
<Reference Include="System.Core" />
</ItemGroup>
<ItemGroup>
<Compile Include="Binders\EEMethodBinder.cs" />
<Compile Include="Binders\WithTypeArgumentsBinder.cs" />
<Compile Include="Binders\PlaceholderLocalBinder.cs" />
<Compile Include="CompilationContext.cs" />
<Compile Include="CompilationExtensions.cs" />
<Compile Include="CSharpLanguageInstructionDecoder.cs" />
<Compile Include="CSharpMetadataContext.cs" />
<Compile Include="CSharpExpressionCompiler.cs" />
<Compile Include="CSharpFrameDecoder.cs" />
<Compile Include="CSharpInstructionDecoder.cs" />
<Compile Include="EEAssemblyBuilder.cs" />
<Compile Include="EETypeNameDecoder.cs" />
<Compile Include="EvaluationContext.cs" />
<Compile Include="InternalsVisibleTo.cs" />
<Compile Include="Rewriters\CapturedVariableRewriter.cs" />
<Compile Include="Rewriters\LocalDeclarationRewriter.cs" />
<Compile Include="Rewriters\MayHaveSideEffectsVisitor.cs" />
<Compile Include="Rewriters\PlaceholderLocalRewriter.cs" />
<Compile Include="Symbols\DisplayClassInstance.cs" />
<Compile Include="Symbols\DisplayClassVariable.cs" />
<Compile Include="Symbols\EEDisplayClassFieldLocalSymbol.cs" />
<Compile Include="Symbols\EELocalConstantSymbol.cs" />
<Compile Include="Symbols\EELocalSymbol.cs" />
<Compile Include="Symbols\EELocalSymbolBase.cs" />
<Compile Include="Symbols\EEConstructorSymbol.cs" />
<Compile Include="Symbols\EEMethodSymbol.cs" />
<Compile Include="Symbols\EENamedTypeSymbol.cs" />
<Compile Include="Symbols\EETypeParameterSymbol.cs" />
<Compile Include="Symbols\ObjectAddressLocalSymbol.cs" />
<Compile Include="Symbols\ObjectIdLocalSymbol.cs" />
<Compile Include="Symbols\PlaceholderLocalSymbol.cs" />
<Compile Include="Symbols\PlaceholderMethodSymbol.cs" />
<Compile Include="Symbols\ExceptionLocalSymbol.cs" />
<Compile Include="Symbols\ReturnValueLocalSymbol.cs" />
<Compile Include="Symbols\SimpleTypeParameterSymbol.cs" />
<Compile Include="Symbols\SynthesizedContextMethodSymbol.cs" />
<Compile Include="SyntaxHelpers.cs" />
<Compile Include="TypeParameterChecker.cs" />
<VsdConfigXml Include="CSharpExpressionCompiler.vsdconfigxml" />
</ItemGroup>
<ItemGroup>
<InternalsVisibleToTest Include="Roslyn.ExpressionEvaluator.CSharp.ExpressionCompiler.UnitTests" />
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<ImportGroup Label="Targets">
<Import Project="..\..\..\..\Tools\Vsdconfig\Vsdconfig.targets" />
<Import Project="..\..\..\..\Tools\Microsoft.CodeAnalysis.Toolset.Open\Targets\VSL.Imports.targets" />
<Import Project="..\..\..\..\..\build\VSL.Imports.Closed.targets" />
<Import Project="$(SolutionDir)\.nuget\NuGet.targets" Condition="Exists('$(SolutionDir)\.nuget\NuGet.targets')" />
</ImportGroup>
</Project>
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (c) Microsoft Corporation. All rights reserved.
-->
<Configuration xmlns="http://schemas.microsoft.com/vstudio/vsdconfig/2008">
<DefineGuid Name="CSharpExpressionCompilerId" Value="CFC88282-E29A-47A1-9FAD-E46391CBD26D"/>
<ManagedComponent
ComponentId="CSharpExpressionCompilerId"
ComponentLevel="9991500"
Synchronized="true"
AssemblyName="Microsoft.CodeAnalysis.CSharp.ExpressionEvaluator.ExpressionCompiler">
<Class Name="Microsoft.CodeAnalysis.CSharp.ExpressionEvaluator.CSharpExpressionCompiler">
<Implements>
<InterfaceGroup Priority="Low">
<NoFilter/>
<Interface Name="IDkmClrExpressionCompiler"/>
<Interface Name="IDkmClrExpressionCompilerCallback"/>
</InterfaceGroup>
<InterfaceGroup
CallOnlyWhenLoaded="true">
<NoFilter/>
<Interface Name="IDkmModuleModifiedNotification"/>
</InterfaceGroup>
</Implements>
</Class>
<Class Name="Microsoft.CodeAnalysis.CSharp.ExpressionEvaluator.CSharpFrameDecoder">
<Implements>
<InterfaceGroup Priority="Low">
<Filter>
<RuntimeId RequiredValue="DkmRuntimeId.Clr"/>
</Filter>
<Interface Name="IDkmLanguageFrameDecoder"/>
</InterfaceGroup>
</Implements>
</Class>
<Class Name="Microsoft.CodeAnalysis.CSharp.ExpressionEvaluator.CSharpLanguageInstructionDecoder">
<Implements>
<InterfaceGroup Priority="Low">
<Filter>
<RuntimeId RequiredValue="DkmRuntimeId.Clr"/>
</Filter>
<Interface Name="IDkmLanguageInstructionDecoder"/>
</InterfaceGroup>
</Implements>
</Class>
</ManagedComponent>
</Configuration>
\ No newline at end of file
// 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 System;
using Microsoft.CodeAnalysis.ExpressionEvaluator;
namespace Microsoft.CodeAnalysis.CSharp.ExpressionEvaluator
{
[DkmReportNonFatalWatsonException(ExcludeExceptionType = typeof(NotImplementedException)), DkmContinueCorruptingException]
internal sealed class CSharpFrameDecoder : FrameDecoder
{
public CSharpFrameDecoder()
: base(CSharpInstructionDecoder.Instance)
{
}
}
}
// 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 System.Text;
using Microsoft.CodeAnalysis.CSharp.Symbols;
using Microsoft.CodeAnalysis.CSharp.Symbols.Metadata.PE;
using Microsoft.CodeAnalysis.ExpressionEvaluator;
using Microsoft.VisualStudio.Debugger;
using Microsoft.VisualStudio.Debugger.Clr;
namespace Microsoft.CodeAnalysis.CSharp.ExpressionEvaluator
{
internal sealed class CSharpInstructionDecoder : InstructionDecoder<PEMethodSymbol>
{
// This string was not localized in the old EE. We'll keep it that way
// so as not to break consumers who may have been parsing frame names...
private const string AnonymousMethodName = "AnonymousMethod";
/// <summary>
/// Singleton instance of <see cref="CSharpInstructionDecoder"/> (created using default constructor).
/// </summary>
internal static readonly CSharpInstructionDecoder Instance = new CSharpInstructionDecoder();
private CSharpInstructionDecoder()
{
}
private static readonly SymbolDisplayFormat s_propertyDisplayFormat = DisplayFormat.
AddMemberOptions(SymbolDisplayMemberOptions.IncludeParameters).
WithParameterOptions(SymbolDisplayParameterOptions.IncludeType);
internal override void AppendFullName(StringBuilder builder, PEMethodSymbol method)
{
var displayFormat =
((method.MethodKind == MethodKind.PropertyGet) || (method.MethodKind == MethodKind.PropertySet)) ?
s_propertyDisplayFormat :
DisplayFormat;
var parts = method.ToDisplayParts(displayFormat);
var numParts = parts.Length;
for (int i = 0; i < numParts; i++)
{
var part = parts[i];
var displayString = part.ToString();
switch (part.Kind)
{
case SymbolDisplayPartKind.ClassName:
if (GeneratedNames.GetKind(displayString) != GeneratedNameKind.LambdaDisplayClass)
{
builder.Append(displayString);
}
else
{
// Drop any remaining display class name parts and the subsequent dot...
do
{
i++;
}
while ((i < numParts) && parts[i].Kind != SymbolDisplayPartKind.MethodName);
i--;
}
break;
case SymbolDisplayPartKind.MethodName:
GeneratedNameKind kind;
int openBracketOffset, closeBracketOffset;
if (GeneratedNames.TryParseGeneratedName(displayString, out kind, out openBracketOffset, out closeBracketOffset) &&
(kind == GeneratedNameKind.LambdaMethod))
{
builder.Append(displayString, openBracketOffset + 1, closeBracketOffset - openBracketOffset - 1); // source method name
builder.Append('.');
builder.Append(AnonymousMethodName);
// NOTE: The old implementation only appended the first ordinal number. Since this is not useful
// in uniquely identifying the lambda, we'll append the entire ordinal suffix (which may contain
// multiple numbers, as well as '-' or '_').
builder.Append(displayString.Substring(closeBracketOffset + 2)); // ordinal suffix (e.g. "__1")
}
else
{
builder.Append(displayString);
}
break;
default:
builder.Append(displayString);
break;
}
}
}
internal override PEMethodSymbol GetMethod(DkmClrInstructionAddress instructionAddress)
{
var moduleInstance = instructionAddress.ModuleInstance;
var appDomain = moduleInstance.AppDomain;
var previous = appDomain.GetDataItem<CSharpMetadataContext>();
var metadataBlocks = instructionAddress.Process.GetMetadataBlocks(appDomain);
CSharpCompilation compilation;
if (metadataBlocks.HaveNotChanged(previous))
{
compilation = previous.Compilation;
}
else
{
var dataItem = new CSharpMetadataContext(metadataBlocks);
appDomain.SetDataItem(DkmDataCreationDisposition.CreateAlways, dataItem);
compilation = dataItem.Compilation;
}
return compilation.GetSourceMethod(moduleInstance.Mvid, instructionAddress.MethodId.Token);
}
}
}
// 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 System;
using Microsoft.CodeAnalysis.ExpressionEvaluator;
using Microsoft.CodeAnalysis.CSharp.Symbols.Metadata.PE;
namespace Microsoft.CodeAnalysis.CSharp.ExpressionEvaluator
{
[DkmReportNonFatalWatsonException(ExcludeExceptionType = typeof(NotImplementedException)), DkmContinueCorruptingException]
internal sealed class CSharpLanguageInstructionDecoder : LanguageInstructionDecoder<PEMethodSymbol>
{
public CSharpLanguageInstructionDecoder()
: base(CSharpInstructionDecoder.Instance)
{
}
}
}
// 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 System.Collections.Immutable;
using Microsoft.CodeAnalysis.ExpressionEvaluator;
namespace Microsoft.CodeAnalysis.CSharp.ExpressionEvaluator
{
internal sealed class CSharpMetadataContext : MetadataContext
{
internal readonly CSharpCompilation Compilation;
internal readonly EvaluationContext EvaluationContext;
internal CSharpMetadataContext(ImmutableArray<MetadataBlock> metadataBlocks)
: base(metadataBlocks)
{
this.Compilation = metadataBlocks.ToCompilation();
}
internal CSharpMetadataContext(EvaluationContext evaluationContext)
: base(evaluationContext.MetadataBlocks)
{
this.Compilation = evaluationContext.Compilation;
this.EvaluationContext = evaluationContext;
}
}
}
// 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 System;
using System.Collections.Immutable;
using System.Reflection.Metadata;
using System.Reflection.Metadata.Ecma335;
using Microsoft.CodeAnalysis.CSharp.Symbols;
using Microsoft.CodeAnalysis.CSharp.Symbols.Metadata.PE;
using Microsoft.CodeAnalysis.ExpressionEvaluator;
namespace Microsoft.CodeAnalysis.CSharp.ExpressionEvaluator
{
internal static class CompilationExtensions
{
private static PENamedTypeSymbol GetType(PEModuleSymbol module, TypeDefinitionHandle typeHandle)
{
var metadataDecoder = new MetadataDecoder(module);
return (PENamedTypeSymbol)metadataDecoder.GetTypeOfToken(typeHandle);
}
internal static PENamedTypeSymbol GetType(this CSharpCompilation compilation, Guid moduleVersionId, int typeToken, out MetadataDecoder metadataDecoder)
{
var module = compilation.GetModule(moduleVersionId);
var reader = module.Module.MetadataReader;
var typeHandle = (TypeDefinitionHandle)MetadataTokens.Handle(typeToken);
var type = GetType(module, typeHandle);
metadataDecoder = new MetadataDecoder(module, type);
return type;
}
internal static PEMethodSymbol GetSourceMethod(this CSharpCompilation compilation, Guid moduleVersionId, int methodToken)
{
var methodHandle = (MethodDefinitionHandle)MetadataTokens.Handle(methodToken);
var method = GetMethod(compilation, moduleVersionId, methodHandle);
var metadataDecoder = new MetadataDecoder((PEModuleSymbol)method.ContainingModule);
var containingType = method.ContainingType;
string sourceMethodName;
if (GeneratedNames.TryParseSourceMethodNameFromGeneratedName(containingType.Name, GeneratedNameKind.StateMachineType, out sourceMethodName))
{
foreach (var member in containingType.ContainingType.GetMembers(sourceMethodName))
{
var candidateMethod = member as PEMethodSymbol;
if (candidateMethod != null)
{
var module = metadataDecoder.Module;
methodHandle = candidateMethod.Handle;
string stateMachineTypeName;
if (module.HasStringValuedAttribute(methodHandle, AttributeDescription.AsyncStateMachineAttribute, out stateMachineTypeName) ||
module.HasStringValuedAttribute(methodHandle, AttributeDescription.IteratorStateMachineAttribute, out stateMachineTypeName))
{
if (metadataDecoder.GetTypeSymbolForSerializedType(stateMachineTypeName).OriginalDefinition.Equals(containingType))
{
return candidateMethod;
}
}
}
}
}
return method;
}
internal static PEMethodSymbol GetMethod(this CSharpCompilation compilation, Guid moduleVersionId, MethodDefinitionHandle methodHandle)
{
var module = compilation.GetModule(moduleVersionId);
var reader = module.Module.MetadataReader;
var typeHandle = reader.GetMethodDefinition(methodHandle).GetDeclaringType();
var type = GetType(module, typeHandle);
var method = (PEMethodSymbol)new MetadataDecoder(module, type).GetMethodSymbolForMethodDefOrMemberRef(methodHandle, type);
return method;
}
internal static PEModuleSymbol GetModule(this CSharpCompilation compilation, Guid moduleVersionId)
{
foreach (var pair in compilation.GetBoundReferenceManager().GetReferencedAssemblies())
{
var assembly = (AssemblySymbol)pair.Value;
foreach (var module in assembly.Modules)
{
var m = (PEModuleSymbol)module;
var id = m.Module.GetModuleVersionIdOrThrow();
if (id == moduleVersionId)
{
return m;
}
}
}
return null;
}
internal static CSharpCompilation ToCompilation(this ImmutableArray<MetadataBlock> metadataBlocks)
{
return CSharpCompilation.Create(
assemblyName: ExpressionCompilerUtilities.GenerateUniqueName(),
references: metadataBlocks.MakeAssemblyReferences(),
options: s_compilationOptions);
}
// XML file references, #r directives not supported:
private static readonly CSharpCompilationOptions s_compilationOptions = new CSharpCompilationOptions(
outputKind: OutputKind.DynamicallyLinkedLibrary,
allowUnsafe: true,
platform: Platform.AnyCpu, // Platform should match PEModule.Machine, in this case I386.
optimizationLevel: OptimizationLevel.Release,
assemblyIdentityComparer: DesktopAssemblyIdentityComparer.Default).
WithMetadataImportOptions(MetadataImportOptions.All);
}
}
// 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.Cci;
using Microsoft.CodeAnalysis.CodeGen;
using Microsoft.CodeAnalysis.CSharp.Emit;
using Microsoft.CodeAnalysis.CSharp.Symbols;
using Microsoft.CodeAnalysis.CSharp.Symbols.Metadata.PE;
using Microsoft.CodeAnalysis.Emit;
using Microsoft.CodeAnalysis.ExpressionEvaluator;
using Roslyn.Utilities;
using System.Collections.Immutable;
using System.Diagnostics;
namespace Microsoft.CodeAnalysis.CSharp.ExpressionEvaluator
{
internal sealed class EEAssemblyBuilder : PEAssemblyBuilderBase
{
private readonly ImmutableHashSet<MethodSymbol> _methods;
public EEAssemblyBuilder(
SourceAssemblySymbol sourceAssembly,
EmitOptions emitOptions,
ImmutableArray<MethodSymbol> methods,
ModulePropertiesForSerialization serializationProperties,
ImmutableArray<NamedTypeSymbol> additionalTypes,
CompilationTestData testData) :
base(
sourceAssembly,
emitOptions,
outputKind: OutputKind.DynamicallyLinkedLibrary,
serializationProperties: serializationProperties,
manifestResources: SpecializedCollections.EmptyEnumerable<ResourceDescription>(),
assemblySymbolMapper: null,
additionalTypes: additionalTypes)
{
_methods = ImmutableHashSet.CreateRange(methods);
if (testData != null)
{
this.SetMethodTestData(testData.Methods);
testData.Module = this;
}
}
protected override IModuleReference TranslateModule(ModuleSymbol symbol, DiagnosticBag diagnostics)
{
var moduleSymbol = symbol as PEModuleSymbol;
if ((object)moduleSymbol != null)
{
var module = moduleSymbol.Module;
// Expose the individual runtime Windows.*.winmd modules as assemblies.
// (The modules were wrapped in a placeholder Windows.winmd assembly
// in MetadataUtilities.MakeAssemblyReferences.)
if (MetadataUtilities.IsWindowsComponent(module.MetadataReader, module.Name) &&
MetadataUtilities.IsWindowsAssemblyName(moduleSymbol.ContainingAssembly.Name))
{
var identity = module.ReadAssemblyIdentityOrThrow();
return new Microsoft.CodeAnalysis.ExpressionEvaluator.AssemblyReference(identity);
}
}
return base.TranslateModule(symbol, diagnostics);
}
public override int CurrentGenerationOrdinal => 0;
internal override VariableSlotAllocator TryCreateVariableSlotAllocator(MethodSymbol symbol)
{
var method = symbol as EEMethodSymbol;
if (((object)method != null) && _methods.Contains(method))
{
var defs = GetLocalDefinitions(method.Locals);
return new SlotAllocator(defs);
}
Debug.Assert(!_methods.Contains(symbol));
return null;
}
private static ImmutableArray<LocalDefinition> GetLocalDefinitions(ImmutableArray<LocalSymbol> locals)
{
var builder = ArrayBuilder<LocalDefinition>.GetInstance();
foreach (var local in locals)
{
if (local.DeclarationKind == LocalDeclarationKind.Constant)
{
continue;
}
var def = ToLocalDefinition(local, builder.Count);
Debug.Assert(((EELocalSymbol)local).Ordinal == def.SlotIndex);
builder.Add(def);
}
return builder.ToImmutableAndFree();
}
private static LocalDefinition ToLocalDefinition(LocalSymbol local, int index)
{
// See EvaluationContext.GetLocals.
TypeSymbol type;
LocalSlotConstraints constraints;
if (local.DeclarationKind == LocalDeclarationKind.FixedVariable)
{
type = ((PointerTypeSymbol)local.Type).PointedAtType;
constraints = LocalSlotConstraints.ByRef | LocalSlotConstraints.Pinned;
}
else
{
type = local.Type;
constraints = (local.IsPinned ? LocalSlotConstraints.Pinned : LocalSlotConstraints.None) |
((local.RefKind == RefKind.None) ? LocalSlotConstraints.None : LocalSlotConstraints.ByRef);
}
return new LocalDefinition(
local,
local.Name,
(Cci.ITypeReference)type,
slot: index,
synthesizedKind: (SynthesizedLocalKind)local.SynthesizedKind,
id: LocalDebugId.None,
pdbAttributes: Cci.PdbWriter.DefaultLocalAttributesValue,
constraints: constraints,
isDynamic: false,
dynamicTransformFlags: ImmutableArray<TypedConstant>.Empty);
}
private sealed class SlotAllocator : VariableSlotAllocator
{
private readonly ImmutableArray<LocalDefinition> _locals;
internal SlotAllocator(ImmutableArray<LocalDefinition> locals)
{
_locals = locals;
}
public override void AddPreviousLocals(ArrayBuilder<Cci.ILocalDefinition> builder)
{
builder.AddRange(_locals);
}
public override LocalDefinition GetPreviousLocal(
Cci.ITypeReference type,
ILocalSymbolInternal symbol,
string nameOpt,
SynthesizedLocalKind synthesizedKind,
LocalDebugId id,
uint pdbAttributes,
LocalSlotConstraints constraints,
bool isDynamic,
ImmutableArray<TypedConstant> dynamicTransformFlags)
{
var local = symbol as EELocalSymbol;
if ((object)local == null)
{
return null;
}
return _locals[local.Ordinal];
}
public override string PreviousStateMachineTypeName
{
get { return null; }
}
public override bool TryGetPreviousHoistedLocalSlotIndex(SyntaxNode currentDeclarator, Cci.ITypeReference currentType, SynthesizedLocalKind synthesizedKind, LocalDebugId currentId, out int slotIndex)
{
slotIndex = -1;
return false;
}
public override int PreviousHoistedLocalSlotCount
{
get { return 0; }
}
public override bool TryGetPreviousAwaiterSlotIndex(Cci.ITypeReference currentType, out int slotIndex)
{
slotIndex = -1;
return false;
}
public override bool TryGetPreviousClosure(SyntaxNode closureSyntax, out int closureOrdinal)
{
closureOrdinal = -1;
return false;
}
public override bool TryGetPreviousLambda(SyntaxNode lambdaOrLambdaBodySyntax, bool isLambdaBody, out int lambdaOrdinal)
{
lambdaOrdinal = -1;
return false;
}
public override int PreviousAwaiterSlotCount
{
get { return 0; }
}
public override MethodDebugId PreviousMethodId
{
get
{
return default(MethodDebugId);
}
}
}
}
}
// 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 System.Collections.Immutable;
using System.Linq;
using Microsoft.CodeAnalysis.CSharp.Symbols;
using Microsoft.CodeAnalysis.CSharp.Symbols.Metadata.PE;
using Microsoft.CodeAnalysis.ExpressionEvaluator;
namespace Microsoft.CodeAnalysis.CSharp.ExpressionEvaluator
{
internal sealed class EETypeNameDecoder : TypeNameDecoder<PEModuleSymbol, TypeSymbol>
{
private readonly CSharpCompilation _compilation;
internal EETypeNameDecoder(CSharpCompilation compilation, PEModuleSymbol moduleSymbol) :
base(SymbolFactory.Instance, moduleSymbol)
{
_compilation = compilation;
}
protected override int GetIndexOfReferencedAssembly(AssemblyIdentity identity)
{
var assemblies = this.GetAssemblies();
// Find assembly matching identity.
int index = assemblies.IndexOf((assembly, id) => id.Equals(assembly.Identity), identity);
if (index >= 0)
{
return index;
}
if (identity.IsWindowsComponent())
{
// Find placeholder Windows.winmd assembly (created
// in MetadataUtilities.MakeAssemblyReferences).
index = assemblies.IndexOf((assembly, unused) => assembly.Identity.IsWindowsRuntime(), (object)null);
if (index >= 0)
{
// Find module in Windows.winmd matching identity.
var modules = assemblies[index].Modules;
var moduleIndex = modules.IndexOf((m, id) => id.Equals(GetComponentAssemblyIdentity(m)), identity);
if (moduleIndex >= 0)
{
return index;
}
}
}
return -1;
}
protected override bool IsContainingAssembly(AssemblyIdentity identity)
{
return false;
}
protected override TypeSymbol LookupNestedTypeDefSymbol(TypeSymbol container, ref MetadataTypeName emittedName)
{
return container.LookupMetadataType(ref emittedName);
}
protected override TypeSymbol LookupTopLevelTypeDefSymbol(int referencedAssemblyIndex, ref MetadataTypeName emittedName)
{
var assembly = this.GetAssemblies()[referencedAssemblyIndex];
return assembly.LookupTopLevelMetadataType(ref emittedName, digThroughForwardedTypes: true);
}
protected override TypeSymbol LookupTopLevelTypeDefSymbol(ref MetadataTypeName emittedName, out bool isNoPiaLocalType)
{
return this.moduleSymbol.LookupTopLevelMetadataType(ref emittedName, out isNoPiaLocalType);
}
private ImmutableArray<AssemblySymbol> GetAssemblies()
{
return _compilation.Assembly.Modules.Single().GetReferencedAssemblySymbols();
}
private static AssemblyIdentity GetComponentAssemblyIdentity(ModuleSymbol module)
{
return ((PEModuleSymbol)module).Module.ReadAssemblyIdentityOrThrow();
}
}
}
// 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 System.Runtime.CompilerServices;
[assembly: InternalsVisibleTo("Microsoft.VisualStudio.ProductionBreakpoints.CodeAnalysis, PublicKey=002400000480000094000000060200000024000052534131000400000100010007d1fa57c4aed9f0a32e84aa0faefd0de9e8fd6aec8f87fb03766c834c99921eb23be79ad9d5dcc1dd9ad236132102900b723cf980957fc4e177108fc607774f29e8320e92ea05ece4e821c0a5efe8f1645c4c0c93c1ab99285d622caa652c1dfad63d745d6f2de5f17e5eaf0fc4963d261c8a12436518206dc093344d5ad293")]
// 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.CSharp.Symbols;
using Roslyn.Utilities;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics;
using System.Linq;
namespace Microsoft.CodeAnalysis.CSharp.ExpressionEvaluator
{
internal sealed class CapturedVariableRewriter : BoundTreeRewriter
{
internal static BoundNode Rewrite(
ParameterSymbol targetMethodThisParameter,
Conversions conversions,
ImmutableDictionary<string, DisplayClassVariable> displayClassVariables,
BoundNode node,
DiagnosticBag diagnostics)
{
var rewriter = new CapturedVariableRewriter(targetMethodThisParameter, conversions, displayClassVariables, diagnostics);
return rewriter.Visit(node);
}
private readonly ParameterSymbol _targetMethodThisParameter;
private readonly Conversions _conversions;
private readonly ImmutableDictionary<string, DisplayClassVariable> _displayClassVariables;
private readonly DiagnosticBag _diagnostics;
private CapturedVariableRewriter(
ParameterSymbol targetMethodThisParameter,
Conversions conversions,
ImmutableDictionary<string, DisplayClassVariable> displayClassVariables,
DiagnosticBag diagnostics)
{
_targetMethodThisParameter = targetMethodThisParameter;
_conversions = conversions;
_displayClassVariables = displayClassVariables;
_diagnostics = diagnostics;
}
public override BoundNode VisitBlock(BoundBlock node)
{
var rewrittenLocals = node.Locals.WhereAsArray(local => local.IsCompilerGenerated || local.Name == null || this.GetVariable(local.Name) == null);
var rewrittenStatements = VisitList(node.Statements);
return node.Update(rewrittenLocals, rewrittenStatements);
}
public override BoundNode VisitLocal(BoundLocal node)
{
var local = node.LocalSymbol;
if (!local.IsCompilerGenerated)
{
var variable = this.GetVariable(local.Name);
if (variable != null)
{
var result = variable.ToBoundExpression(node.Syntax);
Debug.Assert(node.Type == result.Type);
return result;
}
}
return node;
}
public override BoundNode VisitParameter(BoundParameter node)
{
return RewriteParameter(node.Syntax, node.ParameterSymbol, node);
}
public override BoundNode VisitMethodGroup(BoundMethodGroup node)
{
if ((node.Flags & BoundMethodGroupFlags.HasImplicitReceiver) == BoundMethodGroupFlags.HasImplicitReceiver &&
(object)_targetMethodThisParameter == null)
{
// This can happen in static contexts.
// NOTE: LocalRewriter has already been run, so the receiver has already been replaced with an
// appropriate type expression, if this is a static context.
// NOTE: Don't go through VisitThisReference, because it'll produce a diagnostic.
return node.Update(
node.TypeArgumentsOpt,
node.Name,
node.Methods,
node.LookupSymbolOpt,
node.LookupError,
node.Flags,
receiverOpt: null,
resultKind: node.ResultKind);
}
else
{
return base.VisitMethodGroup(node);
}
}
public override BoundNode VisitThisReference(BoundThisReference node)
{
return RewriteParameter(node.Syntax, _targetMethodThisParameter, node);
}
public override BoundNode VisitBaseReference(BoundBaseReference node)
{
var syntax = node.Syntax;
var rewrittenParameter = RewriteParameter(syntax, _targetMethodThisParameter, node);
var baseType = node.Type;
HashSet<DiagnosticInfo> unusedUseSiteDiagnostics = null;
var conversion = _conversions.ClassifyImplicitConversionFromExpression(rewrittenParameter, baseType, ref unusedUseSiteDiagnostics);
Debug.Assert(unusedUseSiteDiagnostics == null || !conversion.IsValid || unusedUseSiteDiagnostics.All(d => d.Severity < DiagnosticSeverity.Error));
// It would be nice if we could just call BoundConversion.Synthesized, but it doesn't seem worthwile to
// introduce a bunch of new overloads to accommodate isBaseConversion.
return new BoundConversion(
syntax,
rewrittenParameter,
conversion.Kind,
conversion.ResultKind,
isBaseConversion: true,
symbolOpt: conversion.Method,
@checked: false,
explicitCastInCode: false,
isExtensionMethod: conversion.IsExtensionMethod,
isArrayIndex: conversion.IsArrayIndex,
constantValueOpt: null,
type: baseType,
hasErrors: !conversion.IsValid)
{ WasCompilerGenerated = true };
}
private BoundExpression RewriteParameter(CSharpSyntaxNode syntax, ParameterSymbol symbol, BoundExpression node)
{
// This can happen in error scenarios (e.g. user binds "this" in a lambda in a static method).
if ((object)symbol == null)
{
ReportMissingThis(node.Kind, syntax);
return node;
}
var variable = this.GetVariable(symbol.Name);
if (variable == null)
{
var typeNameKind = GeneratedNames.GetKind(symbol.Type.Name);
if (typeNameKind != GeneratedNameKind.None)
{
// The state machine case is for async lambdas. The state machine
// will have a hoisted "this" field if it needs to access the
// containing display class, but the display class may not have a
// "this" field.
Debug.Assert(typeNameKind == GeneratedNameKind.LambdaDisplayClass ||
typeNameKind == GeneratedNameKind.StateMachineType);
ReportMissingThis(node.Kind, syntax);
return node;
}
return (node as BoundParameter) ?? new BoundParameter(syntax, symbol);
}
var result = variable.ToBoundExpression(syntax);
Debug.Assert(node.Kind == BoundKind.BaseReference
? result.Type.BaseType.Equals(node.Type, ignoreDynamic: true)
: result.Type.Equals(node.Type, ignoreDynamic: true));
return result;
}
private void ReportMissingThis(BoundKind boundKind, CSharpSyntaxNode syntax)
{
Debug.Assert(boundKind == BoundKind.ThisReference || boundKind == BoundKind.BaseReference);
var errorCode = boundKind == BoundKind.BaseReference
? ErrorCode.ERR_BaseInBadContext
: ErrorCode.ERR_ThisInBadContext;
_diagnostics.Add(new CSDiagnostic(new CSDiagnosticInfo(errorCode), syntax.Location));
}
private DisplayClassVariable GetVariable(string name)
{
DisplayClassVariable variable;
_displayClassVariables.TryGetValue(name, out variable);
return variable;
}
}
}
// 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.CSharp.Symbols;
using Microsoft.CodeAnalysis.ExpressionEvaluator;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics;
namespace Microsoft.CodeAnalysis.CSharp.ExpressionEvaluator
{
internal sealed class LocalDeclarationRewriter
{
internal static BoundNode Rewrite(CSharpCompilation compilation, EENamedTypeSymbol container, HashSet<LocalSymbol> declaredLocals, BoundNode node)
{
var builder = ArrayBuilder<BoundStatement>.GetInstance();
bool hasChanged;
// Rewrite top-level declarations only.
switch (node.Kind)
{
case BoundKind.LocalDeclaration:
RewriteLocalDeclaration(compilation, container, declaredLocals, builder, (BoundLocalDeclaration)node);
hasChanged = true;
break;
case BoundKind.MultipleLocalDeclarations:
foreach (var declaration in ((BoundMultipleLocalDeclarations)node).LocalDeclarations)
{
RewriteLocalDeclaration(compilation, container, declaredLocals, builder, declaration);
}
hasChanged = true;
break;
default:
hasChanged = false;
break;
}
if (hasChanged)
{
node = new BoundBlock(node.Syntax, ImmutableArray<LocalSymbol>.Empty, builder.ToImmutable()) { WasCompilerGenerated = true };
}
builder.Free();
return node;
}
private static void RewriteLocalDeclaration(
CSharpCompilation compilation,
EENamedTypeSymbol container,
HashSet<LocalSymbol> declaredLocals,
ArrayBuilder<BoundStatement> statements,
BoundLocalDeclaration node)
{
Debug.Assert(node.ArgumentsOpt.IsDefault);
var local = node.LocalSymbol;
var syntax = node.Syntax;
declaredLocals.Add(local);
var voidType = compilation.GetSpecialType(SpecialType.System_Void);
var objectType = compilation.GetSpecialType(SpecialType.System_Object);
var typeType = compilation.GetWellKnownType(WellKnownType.System_Type);
var stringType = compilation.GetSpecialType(SpecialType.System_String);
// <>CreateVariable(Type type, string name)
var method = container.GetOrAddSynthesizedMethod(
ExpressionCompilerConstants.CreateVariableMethodName,
(c, n, s) => new PlaceholderMethodSymbol(
c,
s,
n,
voidType,
m => ImmutableArray.Create<ParameterSymbol>(
new SynthesizedParameterSymbol(m, typeType, ordinal: 0, refKind: RefKind.None),
new SynthesizedParameterSymbol(m, stringType, ordinal: 1, refKind: RefKind.None))));
var type = new BoundTypeOfOperator(syntax, new BoundTypeExpression(syntax, aliasOpt: null, type: local.Type), null, typeType);
var name = new BoundLiteral(syntax, ConstantValue.Create(local.Name), stringType);
var call = BoundCall.Synthesized(
syntax,
receiverOpt: null,
method: method,
arguments: ImmutableArray.Create<BoundExpression>(type, name));
statements.Add(new BoundExpressionStatement(syntax, call));
var initializer = node.InitializerOpt;
if (initializer != null)
{
// Generate assignment to local. The assignment will
// be rewritten in PlaceholderLocalRewriter.
var assignment = new BoundAssignmentOperator(
syntax,
new BoundLocal(syntax, local, constantValueOpt: null, type: local.Type),
initializer,
RefKind.None,
local.Type);
statements.Add(new BoundExpressionStatement(syntax, assignment));
}
}
}
}
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
namespace Microsoft.CodeAnalysis.CSharp.ExpressionEvaluator
{
internal sealed class MayHaveSideEffectsVisitor : BoundTreeWalker
{
private bool _mayHaveSideEffects;
internal static bool MayHaveSideEffects(BoundNode node)
{
var visitor = new MayHaveSideEffectsVisitor();
visitor.Visit(node);
return visitor._mayHaveSideEffects;
}
public override BoundNode Visit(BoundNode node)
{
if (_mayHaveSideEffects)
{
return null;
}
return base.Visit(node);
}
public override BoundNode VisitAssignmentOperator(BoundAssignmentOperator node)
{
return this.SetMayHaveSideEffects();
}
// Calls are treated as having side effects, but properties and
// indexers are not. (Since this visitor is run on the bound tree
// before lowering, properties are not represented as calls.)
public override BoundNode VisitCall(BoundCall node)
{
return this.SetMayHaveSideEffects();
}
public override BoundNode VisitDynamicInvocation(BoundDynamicInvocation node)
{
return this.SetMayHaveSideEffects();
}
public override BoundNode VisitCompoundAssignmentOperator(BoundCompoundAssignmentOperator node)
{
return this.SetMayHaveSideEffects();
}
public override BoundNode VisitEventAssignmentOperator(BoundEventAssignmentOperator node)
{
return this.SetMayHaveSideEffects();
}
public override BoundNode VisitIncrementOperator(BoundIncrementOperator node)
{
return this.SetMayHaveSideEffects();
}
public override BoundNode VisitObjectInitializerExpression(BoundObjectInitializerExpression node)
{
foreach (var initializer in node.Initializers)
{
// Do not treat initializer assignment as a side effect since it is
// part of an object creation. In short, visit the RHS only.
var expr = (initializer.Kind == BoundKind.AssignmentOperator) ?
((BoundAssignmentOperator)initializer).Right :
initializer;
this.Visit(expr);
}
return null;
}
private BoundNode SetMayHaveSideEffects()
{
_mayHaveSideEffects = true;
return null;
}
}
}
// 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.CSharp.Symbols;
using System.Collections.Generic;
using System.Diagnostics;
namespace Microsoft.CodeAnalysis.CSharp.ExpressionEvaluator
{
internal sealed class PlaceholderLocalRewriter : BoundTreeRewriter
{
internal static BoundNode Rewrite(CSharpCompilation compilation, EENamedTypeSymbol container, HashSet<LocalSymbol> declaredLocals, BoundNode node)
{
var rewriter = new PlaceholderLocalRewriter(compilation, container, declaredLocals);
return rewriter.Visit(node);
}
private readonly CSharpCompilation _compilation;
private readonly EENamedTypeSymbol _container;
private readonly HashSet<LocalSymbol> _declaredLocals;
private PlaceholderLocalRewriter(CSharpCompilation compilation, EENamedTypeSymbol container, HashSet<LocalSymbol> declaredLocals)
{
_compilation = compilation;
_container = container;
_declaredLocals = declaredLocals;
}
public override BoundNode VisitLocal(BoundLocal node)
{
var result = RewriteLocal(node);
Debug.Assert(result.Type == node.Type);
return result;
}
private BoundExpression RewriteLocal(BoundLocal node)
{
var local = node.LocalSymbol;
var placeholder = local as PlaceholderLocalSymbol;
if ((object)placeholder != null)
{
return placeholder.RewriteLocal(_compilation, _container, node.Syntax);
}
if (_declaredLocals.Contains(local))
{
return ObjectIdLocalSymbol.RewriteLocal(_compilation, _container, node.Syntax, local);
}
return node;
}
}
}
// 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.CSharp.Symbols;
using System.Diagnostics;
namespace Microsoft.CodeAnalysis.CSharp.ExpressionEvaluator
{
internal abstract class DisplayClassInstance
{
internal abstract Symbol ContainingSymbol { get; }
internal abstract NamedTypeSymbol Type { get; }
internal abstract DisplayClassInstance ToOtherMethod(MethodSymbol method, TypeMap typeMap);
internal abstract BoundExpression ToBoundExpression(CSharpSyntaxNode syntax);
}
internal sealed class DisplayClassInstanceFromLocal : DisplayClassInstance
{
internal readonly EELocalSymbol Local;
internal DisplayClassInstanceFromLocal(EELocalSymbol local)
{
Debug.Assert(!local.IsPinned);
Debug.Assert(local.RefKind == RefKind.None);
Debug.Assert(local.DeclarationKind == LocalDeclarationKind.RegularVariable);
this.Local = local;
}
internal override Symbol ContainingSymbol
{
get { return this.Local.ContainingSymbol; }
}
internal override NamedTypeSymbol Type
{
get { return (NamedTypeSymbol)this.Local.Type; }
}
internal override DisplayClassInstance ToOtherMethod(MethodSymbol method, TypeMap typeMap)
{
var otherInstance = (EELocalSymbol)this.Local.ToOtherMethod(method, typeMap);
return new DisplayClassInstanceFromLocal(otherInstance);
}
internal override BoundExpression ToBoundExpression(CSharpSyntaxNode syntax)
{
return new BoundLocal(syntax, this.Local, constantValueOpt: null, type: this.Local.Type) { WasCompilerGenerated = true };
}
}
internal sealed class DisplayClassInstanceFromThis : DisplayClassInstance
{
internal readonly ParameterSymbol ThisParameter;
internal DisplayClassInstanceFromThis(ParameterSymbol thisParameter)
{
Debug.Assert(thisParameter != null);
this.ThisParameter = thisParameter;
}
internal override Symbol ContainingSymbol
{
get { return this.ThisParameter.ContainingSymbol; }
}
internal override NamedTypeSymbol Type
{
get { return (NamedTypeSymbol)this.ThisParameter.Type; }
}
internal override DisplayClassInstance ToOtherMethod(MethodSymbol method, TypeMap typeMap)
{
Debug.Assert(method.IsStatic);
var otherParameter = method.Parameters[0];
return new DisplayClassInstanceFromThis(otherParameter);
}
internal override BoundExpression ToBoundExpression(CSharpSyntaxNode syntax)
{
return new BoundParameter(syntax, this.ThisParameter) { WasCompilerGenerated = true };
}
}
}
// 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.CSharp.Symbols;
using Roslyn.Utilities;
using System.Collections.Immutable;
using System.Diagnostics;
namespace Microsoft.CodeAnalysis.CSharp.ExpressionEvaluator
{
internal enum DisplayClassVariableKind
{
Local,
Parameter,
This,
}
/// <summary>
/// A field in a display class that represents a captured
/// variable: either a local, a parameter, or "this".
/// </summary>
internal sealed class DisplayClassVariable
{
internal readonly string Name;
internal readonly DisplayClassVariableKind Kind;
internal readonly DisplayClassInstance DisplayClassInstance;
internal readonly ConsList<FieldSymbol> DisplayClassFields;
internal DisplayClassVariable(string name, DisplayClassVariableKind kind, DisplayClassInstance displayClassInstance, ConsList<FieldSymbol> displayClassFields)
{
Debug.Assert(displayClassFields.Any());
this.Name = name;
this.Kind = kind;
this.DisplayClassInstance = displayClassInstance;
this.DisplayClassFields = displayClassFields;
// Verify all type parameters are substituted.
Debug.Assert(this.ContainingSymbol.IsContainingSymbolOfAllTypeParameters(this.Type));
}
internal TypeSymbol Type
{
get { return this.DisplayClassFields.Head.Type; }
}
internal Symbol ContainingSymbol
{
get { return this.DisplayClassInstance.ContainingSymbol; }
}
internal DisplayClassVariable ToOtherMethod(MethodSymbol method, TypeMap typeMap)
{
var otherInstance = this.DisplayClassInstance.ToOtherMethod(method, typeMap);
return SubstituteFields(otherInstance, typeMap);
}
internal BoundExpression ToBoundExpression(CSharpSyntaxNode syntax)
{
var expr = this.DisplayClassInstance.ToBoundExpression(syntax);
var fields = ArrayBuilder<FieldSymbol>.GetInstance();
fields.AddRange(this.DisplayClassFields);
fields.ReverseContents();
foreach (var field in fields)
{
expr = new BoundFieldAccess(syntax, expr, field, constantValueOpt: null) { WasCompilerGenerated = true };
}
fields.Free();
return expr;
}
internal DisplayClassVariable SubstituteFields(DisplayClassInstance otherInstance, TypeMap typeMap)
{
var otherFields = SubstituteFields(this.DisplayClassFields, typeMap);
return new DisplayClassVariable(this.Name, this.Kind, otherInstance, otherFields);
}
private static ConsList<FieldSymbol> SubstituteFields(ConsList<FieldSymbol> fields, TypeMap typeMap)
{
if (!fields.Any())
{
return ConsList<FieldSymbol>.Empty;
}
var head = SubstituteField(fields.Head, typeMap);
var tail = SubstituteFields(fields.Tail, typeMap);
return tail.Prepend(head);
}
private static FieldSymbol SubstituteField(FieldSymbol field, TypeMap typeMap)
{
Debug.Assert(!field.IsStatic);
Debug.Assert(!field.IsReadOnly);
Debug.Assert(field.CustomModifiers.Length == 0);
// CONSIDER: Instead of digging fields out of the unsubstituted type and then performing substitution
// on each one individually, we could dig fields out of the substituted type.
return new EEDisplayClassFieldSymbol(typeMap.SubstituteNamedType(field.ContainingType), field.Name, typeMap.SubstituteType(field.Type));
}
private sealed class EEDisplayClassFieldSymbol : FieldSymbol
{
private readonly NamedTypeSymbol _container;
private readonly string _name;
private readonly TypeSymbol _type;
internal EEDisplayClassFieldSymbol(NamedTypeSymbol container, string name, TypeSymbol type)
{
_container = container;
_name = name;
_type = type;
}
public override Symbol AssociatedSymbol
{
get { throw ExceptionUtilities.Unreachable; }
}
public override Symbol ContainingSymbol
{
get { return _container; }
}
public override ImmutableArray<CustomModifier> CustomModifiers
{
get { return ImmutableArray<CustomModifier>.Empty; }
}
public override Accessibility DeclaredAccessibility
{
get { throw ExceptionUtilities.Unreachable; }
}
public override ImmutableArray<SyntaxReference> DeclaringSyntaxReferences
{
get { throw ExceptionUtilities.Unreachable; }
}
public override bool IsConst
{
get { return false; }
}
public override bool IsReadOnly
{
get { return false; }
}
public override bool IsStatic
{
get { return false; }
}
public override bool IsVolatile
{
get { return false; }
}
public override ImmutableArray<Location> Locations
{
get { throw ExceptionUtilities.Unreachable; }
}
public override string Name
{
get { return _name; }
}
internal override bool HasRuntimeSpecialName
{
get { throw ExceptionUtilities.Unreachable; }
}
internal override bool HasSpecialName
{
get { throw ExceptionUtilities.Unreachable; }
}
internal override bool IsNotSerialized
{
get { throw ExceptionUtilities.Unreachable; }
}
internal override MarshalPseudoCustomAttributeData MarshallingInformation
{
get { throw ExceptionUtilities.Unreachable; }
}
internal override ObsoleteAttributeData ObsoleteAttributeData
{
get { throw ExceptionUtilities.Unreachable; }
}
internal override int? TypeLayoutOffset
{
get { throw ExceptionUtilities.Unreachable; }
}
internal override ConstantValue GetConstantValue(ConstantFieldsInProgress inProgress, bool earlyDecodingWellKnownAttributes)
{
throw ExceptionUtilities.Unreachable;
}
internal override TypeSymbol GetFieldType(ConsList<FieldSymbol> fieldsBeingBound)
{
return _type;
}
}
}
}
// 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 System.Collections.Immutable;
using Microsoft.CodeAnalysis.CSharp.Symbols;
namespace Microsoft.CodeAnalysis.CSharp.ExpressionEvaluator
{
/// <summary>
/// Synthesized expression evaluation method.
/// </summary>
internal sealed class EEConstructorSymbol : SynthesizedInstanceConstructor
{
internal EEConstructorSymbol(NamedTypeSymbol containingType)
: base(containingType)
{
}
internal override void GenerateMethodBody(TypeCompilationState compilationState, DiagnosticBag diagnostics)
{
var noLocals = ImmutableArray<LocalSymbol>.Empty;
var initializerInvocation = MethodCompiler.BindConstructorInitializer(this, diagnostics, compilationState.Compilation);
var syntax = initializerInvocation.Syntax;
compilationState.AddSynthesizedMethod(this,
new BoundBlock(
syntax,
noLocals,
ImmutableArray.Create<BoundStatement>(
new BoundExpressionStatement(syntax, initializerInvocation),
new BoundReturnStatement(syntax, null))));
}
}
}
// 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.CSharp.Symbols;
using System.Collections.Immutable;
using System.Diagnostics;
using Roslyn.Utilities;
namespace Microsoft.CodeAnalysis.CSharp.ExpressionEvaluator
{
/// <summary>
/// A display class field representing a local, exposed
/// as a local on the original method.
/// </summary>
internal sealed class EEDisplayClassFieldLocalSymbol : EELocalSymbolBase
{
private readonly DisplayClassVariable _variable;
public EEDisplayClassFieldLocalSymbol(DisplayClassVariable variable)
{
_variable = variable;
// Verify all type parameters are substituted.
Debug.Assert(this.ContainingSymbol.IsContainingSymbolOfAllTypeParameters(this.Type));
}
internal override EELocalSymbolBase ToOtherMethod(MethodSymbol method, TypeMap typeMap)
{
return new EEDisplayClassFieldLocalSymbol(_variable.ToOtherMethod(method, typeMap));
}
public override string Name
{
get { return _variable.Name; }
}
internal override LocalDeclarationKind DeclarationKind
{
get { return LocalDeclarationKind.RegularVariable; }
}
internal override SyntaxToken IdentifierToken
{
get { throw ExceptionUtilities.Unreachable; }
}
public override Symbol ContainingSymbol
{
get { return _variable.ContainingSymbol; }
}
public override TypeSymbol Type
{
get { return _variable.Type; }
}
internal override bool IsPinned
{
get { return false; }
}
internal override bool IsCompilerGenerated
{
get { return false; }
}
internal override RefKind RefKind
{
get { return RefKind.None; }
}
public override ImmutableArray<Location> Locations
{
get { return NoLocations; }
}
public override ImmutableArray<SyntaxReference> DeclaringSyntaxReferences
{
get { return ImmutableArray<SyntaxReference>.Empty; }
}
}
}
// 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 System.Collections.Immutable;
using Microsoft.CodeAnalysis.CSharp.Symbols;
using Roslyn.Utilities;
namespace Microsoft.CodeAnalysis.CSharp.ExpressionEvaluator
{
internal sealed class EELocalConstantSymbol : EELocalSymbolBase
{
private readonly MethodSymbol _method;
private readonly string _name;
private readonly TypeSymbol _type;
private readonly ConstantValue _value;
public EELocalConstantSymbol(
MethodSymbol method,
string name,
TypeSymbol type,
ConstantValue value)
{
_method = method;
_name = name;
_type = type;
_value = value;
}
internal override EELocalSymbolBase ToOtherMethod(MethodSymbol method, TypeMap typeMap)
{
var type = typeMap.SubstituteType(_type);
return new EELocalConstantSymbol(method, _name, type, _value);
}
public override string Name
{
get { return _name; }
}
internal override LocalDeclarationKind DeclarationKind
{
get { return LocalDeclarationKind.Constant; }
}
internal override SyntaxToken IdentifierToken
{
get { throw ExceptionUtilities.Unreachable; }
}
public override Symbol ContainingSymbol
{
get { return _method; }
}
public override TypeSymbol Type
{
get { return _type; }
}
internal override bool IsPinned
{
get { return false; }
}
internal override bool IsCompilerGenerated
{
get { return false; }
}
internal override ConstantValue GetConstantValue(SyntaxNode node, LocalSymbol inProgress, DiagnosticBag diagnostics)
{
return _value;
}
internal override RefKind RefKind
{
get { return RefKind.None; }
}
public override ImmutableArray<Location> Locations
{
get { return NoLocations; }
}
public override ImmutableArray<SyntaxReference> DeclaringSyntaxReferences
{
get { return ImmutableArray<SyntaxReference>.Empty; }
}
}
}
// 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 System;
using System.Collections.Immutable;
using System.Diagnostics;
using Microsoft.CodeAnalysis.CSharp.Symbols;
using Roslyn.Utilities;
namespace Microsoft.CodeAnalysis.CSharp.ExpressionEvaluator
{
internal sealed class EELocalSymbol : EELocalSymbolBase
{
private readonly MethodSymbol _method;
private readonly TypeSymbol _type;
private readonly LocalDeclarationKind _declarationKind;
private readonly bool _isCompilerGenerated;
private readonly ImmutableArray<Location> _locations;
private readonly string _nameOpt;
private readonly int _ordinal; // index in locals of containing block
private readonly bool _isPinned;
private readonly RefKind _refKind;
private readonly bool _canScheduleToStack;
public EELocalSymbol(
MethodSymbol method,
ImmutableArray<Location> locations,
string nameOpt,
int ordinal,
LocalDeclarationKind declarationKind,
TypeSymbol type,
RefKind refKind,
bool isPinned,
bool isCompilerGenerated,
bool canScheduleToStack)
{
Debug.Assert(method != null);
Debug.Assert(ordinal >= -1);
Debug.Assert(!locations.IsDefault);
Debug.Assert(type != null);
_method = method;
_locations = locations;
_nameOpt = nameOpt;
_ordinal = ordinal;
_declarationKind = declarationKind;
_type = type;
_refKind = refKind;
_isPinned = isPinned;
_isCompilerGenerated = isCompilerGenerated;
_canScheduleToStack = canScheduleToStack;
}
internal override EELocalSymbolBase ToOtherMethod(MethodSymbol method, TypeMap typeMap)
{
var type = typeMap.SubstituteType(_type);
return new EELocalSymbol(method, _locations, _nameOpt, _ordinal, _declarationKind, type, _refKind, _isPinned, _isCompilerGenerated, _canScheduleToStack);
}
internal override LocalDeclarationKind DeclarationKind
{
get { return _declarationKind; }
}
internal override bool CanScheduleToStack
{
get { return _canScheduleToStack; }
}
internal int Ordinal
{
get { return _ordinal; }
}
public override string Name
{
get { return _nameOpt; }
}
internal override SyntaxToken IdentifierToken
{
get { throw ExceptionUtilities.Unreachable; }
}
public override ImmutableArray<SyntaxReference> DeclaringSyntaxReferences
{
get { return ImmutableArray<SyntaxReference>.Empty; }
}
public override ImmutableArray<Location> Locations
{
get { return _locations; }
}
public override Symbol ContainingSymbol
{
get { return _method; }
}
public override TypeSymbol Type
{
get { return _type; }
}
internal override bool IsPinned
{
get { return _isPinned; }
}
internal override bool IsCompilerGenerated
{
get { return _isCompilerGenerated; }
}
internal override RefKind RefKind
{
get { return _refKind; }
}
}
}
// 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 System;
using System.Collections.Generic;
using System.Collections.Immutable;
using Microsoft.CodeAnalysis.CSharp.Symbols;
using Roslyn.Utilities;
namespace Microsoft.CodeAnalysis.CSharp.ExpressionEvaluator
{
internal static class LocalSymbolExtensions
{
internal static LocalSymbol ToOtherMethod(this LocalSymbol local, MethodSymbol method, TypeMap typeMap)
{
var l = local as EELocalSymbolBase;
if ((object)l != null)
{
return l.ToOtherMethod(method, typeMap);
}
var type = typeMap.SubstituteType(local.Type);
return new EELocalSymbol(method, local.Locations, local.Name, -1, local.DeclarationKind, type, local.RefKind, local.IsPinned, local.IsCompilerGenerated, local.CanScheduleToStack);
}
}
internal abstract class EELocalSymbolBase : LocalSymbol
{
internal static readonly ImmutableArray<Location> NoLocations = ImmutableArray.Create(NoLocation.Singleton);
internal abstract EELocalSymbolBase ToOtherMethod(MethodSymbol method, TypeMap typeMap);
internal override ConstantValue GetConstantValue(SyntaxNode node, LocalSymbol inProgress, DiagnosticBag diagnostics)
{
return null;
}
internal override ImmutableArray<Diagnostic> GetConstantValueDiagnostics(BoundExpression boundInitValue)
{
return ImmutableArray<Diagnostic>.Empty;
}
internal sealed override SynthesizedLocalKind SynthesizedKind
{
get { return SynthesizedLocalKind.UserDefined; }
}
internal sealed override bool IsImportedFromMetadata
{
get { return true; }
}
internal override SyntaxNode GetDeclaratorSyntax()
{
throw ExceptionUtilities.Unreachable;
}
internal sealed override DiagnosticInfo GetUseSiteDiagnostic()
{
var type = this.Type;
DiagnosticInfo result = null;
if (!DeriveUseSiteDiagnosticFromType(ref result, type) && this.ContainingModule.HasUnifiedReferences)
{
// If the member is in an assembly with unified references,
// we check if its definition depends on a type from a unified reference.
HashSet<TypeSymbol> unificationCheckedTypes = null;
type.GetUnificationUseSiteDiagnosticRecursive(ref result, this, ref unificationCheckedTypes);
}
return result;
}
}
}
// 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 System.Collections.Immutable;
using System.Diagnostics;
using Microsoft.CodeAnalysis.CSharp.Symbols;
namespace Microsoft.CodeAnalysis.CSharp.ExpressionEvaluator
{
internal sealed class ExceptionLocalSymbol : PlaceholderLocalSymbol
{
internal ExceptionLocalSymbol(MethodSymbol method, string name, TypeSymbol type) :
base(method, name, type)
{
}
internal override bool IsWritable
{
get { return false; }
}
internal override BoundExpression RewriteLocal(CSharpCompilation compilation, EENamedTypeSymbol container, CSharpSyntaxNode syntax)
{
Debug.Assert(this.Name == this.Name.ToLowerInvariant());
var method = container.GetOrAddSynthesizedMethod(
this.Name,
(c, n, s) =>
{
var returnType = compilation.GetWellKnownType(WellKnownType.System_Exception);
return new PlaceholderMethodSymbol(
c,
s,
n,
returnType,
m => ImmutableArray<ParameterSymbol>.Empty);
});
var call = BoundCall.Synthesized(syntax, receiverOpt: null, method: method);
return ConvertToLocalType(compilation, call, this.Type);
}
}
}
// 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 System.Collections.Immutable;
using System.Diagnostics;
using Microsoft.CodeAnalysis.CSharp.Symbols;
using Microsoft.CodeAnalysis.ExpressionEvaluator;
namespace Microsoft.CodeAnalysis.CSharp.ExpressionEvaluator
{
internal sealed class ObjectAddressLocalSymbol : PlaceholderLocalSymbol
{
private readonly ulong _address;
internal ObjectAddressLocalSymbol(MethodSymbol method, string name, TypeSymbol type, ulong address) :
base(method, name, type)
{
Debug.Assert(type.SpecialType == SpecialType.System_Object);
_address = address;
}
internal override bool IsWritable
{
// Return true?
get { return false; }
}
internal override BoundExpression RewriteLocal(CSharpCompilation compilation, EENamedTypeSymbol container, CSharpSyntaxNode syntax)
{
var method = container.GetOrAddSynthesizedMethod(
ExpressionCompilerConstants.GetObjectAtAddressMethodName,
(c, n, s) =>
{
var parameterType = compilation.GetSpecialType(SpecialType.System_UInt64);
return new PlaceholderMethodSymbol(
c,
s,
n,
this.Type,
m => ImmutableArray.Create<ParameterSymbol>(new SynthesizedParameterSymbol(m, parameterType, ordinal: 0, refKind: RefKind.None)));
});
var argument = new BoundLiteral(
syntax,
Microsoft.CodeAnalysis.ConstantValue.Create(_address),
method.Parameters[0].Type);
var call = BoundCall.Synthesized(
syntax,
receiverOpt: null,
method: method,
arguments: ImmutableArray.Create<BoundExpression>(argument));
Debug.Assert(call.Type == this.Type);
return call;
}
}
}
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="StyleCop.MSBuild" version="4.7.48.2" targetFramework="net45" developmentDependency="true" />
<package id="System.Collections.Immutable" version="1.1.33-beta" targetFramework="net45" />
<package id="System.Reflection.Metadata" version="1.0.18-beta" targetFramework="net45" />
</packages>
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="CSharpResultProvider.csproj" />
<Import Project="..\..\..\CoreSystem.Settings.targets" />
<PropertyGroup>
<ProjectGuid>{BF9DAC1E-3A5E-4DC3-BB44-9A64E0D4E9D4}</ProjectGuid>
</PropertyGroup>
<ItemGroup Label="Project References">
<ProjectReference Include="CSharpResultProvider.csproj">
<Project>{BF9DAC1E-3A5E-4DC3-BB44-9A64E0D4E9D3}</Project>
<Name>CSharpResultProvider</Name>
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<!--
The following two entries are simply to avoid the project system generating spurious
IDS_LANGBLD_TLE_PROJFILE_MISSING_DEPENDENCY warnings.
-->
<None Include="Resources.resx" />
<None Include="Resources.Designer.cs" />
</ItemGroup>
</Project>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<packages>
</packages>
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册