Опускаемые операции в рослине
Когда в Roslyn были введены операции, одна из целей заключалась в том, чтобы обеспечить пониженные операции (я думаю, это было в видеоролике, посвященном обзору дизайна), который, насколько я понимаю, должен обеспечивать явные операции для неявных действий компилятора на высокоуровневых. Я вижу, что в Roslyn находится каталог, но классы там внутренние. Можно ли теперь опускать операции или нет общедоступного API?
В примере ниже операции уже удаляются некоторые неявные части - добавление оператора return для тела выражения и отображение символа для перегруженного оператора. Но pre и post increments отличаются только по виду.
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Semantics;
using System.Linq;
namespace so39468373
{
internal static class Program
{
private static void Main()
{
var tree = CSharpSyntaxTree.ParseText(@"
public class c
{
public static c operator ++(c o) { return o; }
static c pre(c o) => ++o;
static c post(c o) => o++;
public static void Main() {}
}");
var mscorlib = MetadataReference.CreateFromFile(typeof(object).Assembly.Location);
var compilation = CSharpCompilation.Create(null, new[] { tree }, new[] { mscorlib });
var model = compilation.GetSemanticModel(tree);
foreach (var node in tree.GetRoot().DescendantNodes().OfType<ArrowExpressionClauseSyntax>())
{
var operation = model.GetOperation(node);
var block = (IBlockStatement)operation;
var statement = (IReturnStatement)block.Statements.First();
var increment = (IIncrementExpression)statement.ReturnedValue;
// How to get lowered operations for increment here?
}
}
}
}
Код в github - https://github.com/isanych/so-39468373
Ответы
Ответ 1
Разный угол на этом ответе - что относительно этого аспекта компилятора?
InternalVisibleTo Attribute
ссылка: https://msdn.microsoft.com/en-us/library/system.runtime.compilerservices.internalsvisibletoattribute(v=vs.110).aspx
Возможно ли сделать интересную тему разговора, связанную с "другим углом", чтобы использовать подход к отладке?
ДОПОЛНИТЕЛЬНАЯ ИНФОРМАЦИЯ (из статьи):
Информация о версии
Универсальная платформа Windows
Доступно с 8
.NET Framework
Доступно с 2.0
Портативная библиотека классов
Поддерживается в: переносных платформах .NET
Silverlight
Доступно с 2.0
Windows Phone Silverlight
Доступно с 7.0
Телефон Windows
Доступно с 8.1
Ответ 2
Этот пример поможет вам решить его поблем
using System.Collections.Immutable;
using System.Diagnostics;
using Microsoft.CodeAnalysis.CSharp.Symbols;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Text;
namespace Microsoft.CodeAnalysis.CSharp
{
/// <summary>
/// The dynamic operation factories below return this struct so that the caller
/// have the option of separating the call-site initialization from its invocation.
///
/// Most callers just call <see cref="ToExpression"/> to get the combo but some (object and array initializers)
/// hoist all call-site initialization code and emit multiple invocations of the same site.
/// </summary>
internal struct LoweredDynamicOperation
{
private readonly SyntheticBoundNodeFactory _factory;
private readonly TypeSymbol _resultType;
private readonly ImmutableArray<LocalSymbol> _temps;
public readonly BoundExpression SiteInitialization;
public readonly BoundExpression SiteInvocation;
public LoweredDynamicOperation(SyntheticBoundNodeFactory factory, BoundExpression siteInitialization, BoundExpression siteInvocation, TypeSymbol resultType, ImmutableArray<LocalSymbol> temps)
{
_factory = factory;
_resultType = resultType;
_temps = temps;
this.SiteInitialization = siteInitialization;
this.SiteInvocation = siteInvocation;
}
public static LoweredDynamicOperation Bad(
BoundExpression loweredReceiver,
ImmutableArray<BoundExpression> loweredArguments,
BoundExpression loweredRight,
TypeSymbol resultType)
{
var children = ArrayBuilder<BoundNode>.GetInstance();
children.AddOptional(loweredReceiver);
children.AddRange(loweredArguments);
children.AddOptional(loweredRight);
return LoweredDynamicOperation.Bad(resultType, children.ToImmutableAndFree());
}
public static LoweredDynamicOperation Bad(TypeSymbol resultType, ImmutableArray<BoundNode> children)
{
Debug.Assert(children.Length > 0);
var bad = new BoundBadExpression(children[0].Syntax, LookupResultKind.Empty, ImmutableArray<Symbol>.Empty, children, resultType);
return new LoweredDynamicOperation(null, null, bad, resultType, default(ImmutableArray<LocalSymbol>));
}
public BoundExpression ToExpression()
{
if (_factory == null)
{
Debug.Assert(SiteInitialization == null && SiteInvocation is BoundBadExpression && _temps.IsDefaultOrEmpty);
return SiteInvocation;
}
// TODO (tomat): we might be able to use SiteInvocation.Type instead of resultType once we stop using GetLoweredType
if (_temps.IsDefaultOrEmpty)
{
return _factory.Sequence(new[] { SiteInitialization }, SiteInvocation, _resultType);
}
else
{
return new BoundSequence(_factory.Syntax, _temps, ImmutableArray.Create(SiteInitialization), SiteInvocation, _resultType) { WasCompilerGenerated = true };
}
}
}
}