54 votes

Baisse des opérations à Roslyn

Lorsque les opérations ont été introduites dans Roslyn, l'un des objectifs était de fournir des opérations abaissées (je pense que c'était dans la vidéo de la réunion de revue de conception) qui, d'après ce que je comprends, devraient fournir des opérations explicites pour les actions implicites du compilateur sur les opérations de haut niveau. Je vois le répertoire Lowering dans Roslyn, mais les classes y sont internes. Est-il possible d'obtenir des opérations abaissées maintenant ou aucune API publique n'est encore disponible ?

Dans l'exemple ci-dessous, les opérations ont déjà supprimé certaines parties implicites - en ajoutant l'instruction return pour le corps de l'expression et le symbole expose pour l'opérateur surchargé. Mais les incréments pré et post ne diffèrent que par leur nature.

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?
            }
        }
    }
}

Code sur github - https://github.com/isanych/so-39468373

3 votes

D'après ce que je peux voir, il y a un certain nombre de questions ouvertes concernant ce sujet, vous pouvez en suivre l'évolution ici : github.com/dotnet/roslyn/

1voto

GlennFerrieLive Points 4524

Un angle différent pour cette réponse : qu'en est-il de cet aspect du compilateur ?

InternalVisibleTo Attribute

lien : https://msdn.microsoft.com/en-us/library/system.runtime.compilerservices.internalsvisibletoattribute(v=vs.110).aspx

Cela pourrait faire un sujet de conversation intéressant lié à un "angle différent" à utiliser pour aborder le débogage ?

PLUS D'INFOS (extrait de l'article) :

Informations sur la version

Plate-forme universelle Windows Disponible depuis 8 Cadre .NET
Disponible depuis 2.0 Bibliothèque de classes portables
Pris en charge par : les plateformes .NET portables Silverlight
Disponible depuis 2.0 Windows Phone Silverlight
Disponible depuis 7.0 Windows Phone
Disponible depuis 8.1

0voto

Vérifiez cet exemple qui vous aidera à résoudre son problème.

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 };
            }
        }
    }
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X