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;
 }
        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;
        }
示例#3
0
        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 = BoundBlock.SynthesizedNoLocals(node.Syntax, builder.ToImmutable());
            }

            builder.Free();
            return(node);
        }
示例#4
0
        internal override BoundExpression RewriteLocal(
            CSharpCompilation compilation,
            EENamedTypeSymbol container,
            SyntaxNode syntax,
            DiagnosticBag diagnostics
            )
        {
            var method = GetIntrinsicMethod(
                compilation,
                ExpressionCompilerConstants.GetReturnValueMethodName
                );
            var argument = new BoundLiteral(
                syntax,
                Microsoft.CodeAnalysis.ConstantValue.Create(_index),
                method.Parameters[0].Type
                );
            var call = BoundCall.Synthesized(
                syntax,
                receiverOpt: null,
                method: method,
                arguments: ImmutableArray.Create <BoundExpression>(argument)
                );

            return(ConvertToLocalType(compilation, call, this.Type, diagnostics));
        }
示例#5
0
 private static BoundExpression RewriteLocalInternal(CSharpCompilation compilation, EENamedTypeSymbol container, CSharpSyntaxNode syntax, LocalSymbol local)
 {
     var parameterType = compilation.GetSpecialType(SpecialType.System_String);
     var getValueMethod = container.GetOrAddSynthesizedMethod(
         ExpressionCompilerConstants.GetVariableValueMethodName,
         (c, n, s) =>
         {
             var returnType = compilation.GetSpecialType(SpecialType.System_Object);
             return new PlaceholderMethodSymbol(
                 c,
                 s,
                 n,
                 returnType,
                 m => ImmutableArray.Create<ParameterSymbol>(new SynthesizedParameterSymbol(m, parameterType, ordinal: 0, refKind: RefKind.None)));
         });
     var getAddressMethod = container.GetOrAddSynthesizedMethod(
         ExpressionCompilerConstants.GetVariableAddressMethodName,
         (c, n, s) =>
         {
             return new PlaceholderMethodSymbol(
                 c,
                 s,
                 n,
                 m => ImmutableArray.Create<TypeParameterSymbol>(new SimpleTypeParameterSymbol(m, 0, "<>T")),
                 m => m.TypeParameters[0], // return type is <>T&
                 m => ImmutableArray.Create<ParameterSymbol>(new SynthesizedParameterSymbol(m, parameterType, ordinal: 0, refKind: RefKind.None)),
                 returnValueIsByRef: true);
         });
     return new BoundPseudoVariable(
         syntax,
         local,
         new ObjectIdExpressions(compilation, getValueMethod, getAddressMethod),
         local.Type);
 }
 private PlaceholderLocalRewriter(CSharpCompilation compilation, EENamedTypeSymbol container, HashSet<LocalSymbol> declaredLocals, DiagnosticBag diagnostics)
 {
     _compilation = compilation;
     _container = container;
     _declaredLocals = declaredLocals;
     _diagnostics = diagnostics;
 }
示例#7
0
        internal override BoundExpression RewriteLocal(
            CSharpCompilation compilation,
            EENamedTypeSymbol container,
            SyntaxNode syntax,
            DiagnosticBag diagnostics
            )
        {
            var method = GetIntrinsicMethod(
                compilation,
                ExpressionCompilerConstants.GetObjectAtAddressMethodName
                );
            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(
                TypeSymbol.Equals(call.Type, this.Type, TypeCompareKind.ConsiderEverything2)
                );
            return(call);
        }
示例#8
0
 private PlaceholderLocalRewriter(CSharpCompilation compilation, EENamedTypeSymbol container, HashSet <LocalSymbol> declaredLocals, DiagnosticBag diagnostics)
 {
     _compilation    = compilation;
     _container      = container;
     _declaredLocals = declaredLocals;
     _diagnostics    = diagnostics;
 }
 private static BoundExpression RewriteLocalInternal(CSharpCompilation compilation, EENamedTypeSymbol container, CSharpSyntaxNode syntax, LocalSymbol local)
 {
     return new BoundPseudoVariable(
         syntax,
         local,
         new ObjectIdExpressions(compilation),
         local.Type);
 }
示例#10
0
 internal override BoundExpression RewriteLocal(
     CSharpCompilation compilation,
     EENamedTypeSymbol container,
     SyntaxNode syntax,
     DiagnosticBag diagnostics
     )
 {
     return(RewriteLocalInternal(compilation, container, syntax, this));
 }
示例#11
0
 internal static BoundExpression RewriteLocal(
     CSharpCompilation compilation,
     EENamedTypeSymbol container,
     SyntaxNode syntax,
     LocalSymbol local
     )
 {
     return(RewriteLocalInternal(compilation, container, syntax, local));
 }
        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));
            }
        }
        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));
            }
        }
示例#14
0
        internal override BoundExpression RewriteLocal(
            CSharpCompilation compilation,
            EENamedTypeSymbol container,
            SyntaxNode syntax,
            DiagnosticBag diagnostics
            )
        {
            var method = GetIntrinsicMethod(compilation, _getExceptionMethodName);
            var call   = BoundCall.Synthesized(syntax, receiverOpt: null, method: method);

            return(ConvertToLocalType(compilation, call, this.Type, diagnostics));
        }
示例#15
0
 private static BoundExpression RewriteLocalInternal(
     CSharpCompilation compilation,
     EENamedTypeSymbol container,
     SyntaxNode syntax,
     LocalSymbol local
     )
 {
     return(new BoundPseudoVariable(
                syntax,
                local,
                new ObjectIdExpressions(compilation),
                local.Type
                ));
 }
 internal override BoundExpression RewriteLocal(CSharpCompilation compilation, EENamedTypeSymbol container, CSharpSyntaxNode syntax, DiagnosticBag diagnostics)
 {
     var method = GetIntrinsicMethod(compilation, ExpressionCompilerConstants.GetReturnValueMethodName);
     var argument = new BoundLiteral(
         syntax,
         Microsoft.CodeAnalysis.ConstantValue.Create(_index),
         method.Parameters[0].Type);
     var call = BoundCall.Synthesized(
         syntax,
         receiverOpt: null,
         method: method,
         arguments: ImmutableArray.Create<BoundExpression>(argument));
     return ConvertToLocalType(compilation, call, this.Type, diagnostics);
 }
        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 typeType        = compilation.GetWellKnownType(WellKnownType.System_Type);
            var stringType      = compilation.GetSpecialType(SpecialType.System_String);
            var guidConstructor = (MethodSymbol)compilation.GetWellKnownTypeMember(WellKnownMember.System_Guid__ctor);

            // CreateVariable(Type type, string name)
            var method = PlaceholderLocalSymbol.GetIntrinsicMethod(compilation, ExpressionCompilerConstants.CreateVariableMethodName);
            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);

            bool hasCustomTypeInfoPayload;
            var  customTypeInfoPayload   = GetCustomTypeInfoPayload(local, syntax, compilation, out hasCustomTypeInfoPayload);
            var  customTypeInfoPayloadId = GetCustomTypeInfoPayloadId(syntax, guidConstructor, hasCustomTypeInfoPayload);
            var  call = BoundCall.Synthesized(
                syntax,
                receiverOpt: null,
                method: method,
                arguments: ImmutableArray.Create(type, name, customTypeInfoPayloadId, customTypeInfoPayload));

            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));
            }
        }
示例#18
0
        internal static BoundStatement Rewrite(
            CSharpCompilation compilation,
            EENamedTypeSymbol container,
            HashSet <LocalSymbol> declaredLocals,
            BoundStatement node,
            ImmutableArray <LocalSymbol> declaredLocalsArray,
            DiagnosticBag diagnostics
            )
        {
            var builder = ArrayBuilder <BoundStatement> .GetInstance();

            foreach (var local in declaredLocalsArray)
            {
                CreateLocal(compilation, declaredLocals, builder, local, node.Syntax, diagnostics);
            }

            // Rewrite top-level declarations only.
            switch (node.Kind)
            {
            case BoundKind.LocalDeclaration:
                Debug.Assert(
                    declaredLocals.Contains(((BoundLocalDeclaration)node).LocalSymbol)
                    );
                RewriteLocalDeclaration(builder, (BoundLocalDeclaration)node);
                break;

            case BoundKind.MultipleLocalDeclarations:
                foreach (
                    var declaration in ((BoundMultipleLocalDeclarations)node).LocalDeclarations
                    )
                {
                    Debug.Assert(declaredLocals.Contains(declaration.LocalSymbol));
                    RewriteLocalDeclaration(builder, declaration);
                }
                break;

            default:
                if (builder.Count == 0)
                {
                    builder.Free();
                    return(node);
                }

                builder.Add(node);
                break;
            }

            return(BoundBlock.SynthesizedNoLocals(node.Syntax, builder.ToImmutableAndFree()));
        }
 internal override BoundExpression RewriteLocal(CSharpCompilation compilation, EENamedTypeSymbol container, SyntaxNode syntax, DiagnosticBag diagnostics)
 {
     var method = GetIntrinsicMethod(compilation, ExpressionCompilerConstants.GetObjectAtAddressMethodName);
     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;
 }
示例#20
0
        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 typeType = compilation.GetWellKnownType(WellKnownType.System_Type);
            var stringType = compilation.GetSpecialType(SpecialType.System_String);
            var guidConstructor = (MethodSymbol)compilation.GetWellKnownTypeMember(WellKnownMember.System_Guid__ctor);

            // CreateVariable(Type type, string name)
            var method = PlaceholderLocalSymbol.GetIntrinsicMethod(compilation, ExpressionCompilerConstants.CreateVariableMethodName);
            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);

            bool hasCustomTypeInfoPayload;
            var customTypeInfoPayload = GetCustomTypeInfoPayload(local, syntax, compilation, out hasCustomTypeInfoPayload);
            var customTypeInfoPayloadId = GetCustomTypeInfoPayloadId(syntax, guidConstructor, hasCustomTypeInfoPayload);
            var call = BoundCall.Synthesized(
                syntax,
                receiverOpt: null,
                method: method,
                arguments: ImmutableArray.Create(type, name, customTypeInfoPayloadId, customTypeInfoPayload));
            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));
            }
        }
示例#21
0
        internal static BoundNode Rewrite(
            CSharpCompilation compilation,
            EENamedTypeSymbol container,
            HashSet <LocalSymbol> declaredLocals,
            BoundNode node,
            DiagnosticBag diagnostics
            )
        {
            var rewriter = new PlaceholderLocalRewriter(
                compilation,
                container,
                declaredLocals,
                diagnostics
                );

            return(rewriter.Visit(node));
        }
示例#22
0
 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);
 }
示例#23
0
        internal static BoundStatement Rewrite(CSharpCompilation compilation, EENamedTypeSymbol container, HashSet<LocalSymbol> declaredLocals, BoundStatement node, ImmutableArray<LocalSymbol> declaredLocalsArray)
        {
            var builder = ArrayBuilder<BoundStatement>.GetInstance();

            foreach (var local in declaredLocalsArray)
            {
                CreateLocal(compilation, declaredLocals, builder, local, node.Syntax);
            }

            // Rewrite top-level declarations only.
            switch (node.Kind)
            {
                case BoundKind.LocalDeclaration:
                    Debug.Assert(declaredLocals.Contains(((BoundLocalDeclaration)node).LocalSymbol));
                    RewriteLocalDeclaration(builder, (BoundLocalDeclaration)node);
                    break;

                case BoundKind.MultipleLocalDeclarations:
                    foreach (var declaration in ((BoundMultipleLocalDeclarations)node).LocalDeclarations)
                    {
                        Debug.Assert(declaredLocals.Contains(declaration.LocalSymbol));
                        RewriteLocalDeclaration(builder, declaration);
                    }

                    break;

                default:
                    if (builder.Count == 0)
                    {
                        builder.Free();
                        return node;
                    }

                    builder.Add(node);
                    break; 
            }

            return BoundBlock.SynthesizedNoLocals(node.Syntax, builder.ToImmutableAndFree());
        }
 internal override BoundExpression RewriteLocal(CSharpCompilation compilation, EENamedTypeSymbol container, CSharpSyntaxNode syntax, DiagnosticBag diagnostics)
 {
     return RewriteLocalInternal(compilation, container, syntax, this);
 }
示例#25
0
        internal EEMethodSymbol(
            EENamedTypeSymbol container,
            string name,
            Location location,
            MethodSymbol sourceMethod,
            ImmutableArray<LocalSymbol> sourceLocals,
            ImmutableArray<LocalSymbol> sourceLocalsForBinding,
            ImmutableDictionary<string, DisplayClassVariable> sourceDisplayClassVariables,
            GenerateMethodBody generateMethodBody)
        {
            Debug.Assert(sourceMethod.IsDefinition);
            Debug.Assert(sourceMethod.ContainingSymbol == container.SubstitutedSourceType.OriginalDefinition);
            Debug.Assert(sourceLocals.All(l => l.ContainingSymbol == sourceMethod));

            _container = container;
            _name = name;
            _locations = ImmutableArray.Create(location);

            // What we want is to map all original type parameters to the corresponding new type parameters
            // (since the old ones have the wrong owners).  Unfortunately, we have a circular dependency:
            //   1) Each new type parameter requires the entire map in order to be able to construct its constraint list.
            //   2) The map cannot be constructed until all new type parameters exist.
            // Our solution is to pass each new type parameter a lazy reference to the type map.  We then 
            // initialize the map as soon as the new type parameters are available - and before they are 
            // handed out - so that there is never a period where they can require the type map and find
            // it uninitialized.

            var sourceMethodTypeParameters = sourceMethod.TypeParameters;
            var allSourceTypeParameters = container.SourceTypeParameters.Concat(sourceMethodTypeParameters);

            var getTypeMap = new Func<TypeMap>(() => this.TypeMap);
            _typeParameters = sourceMethodTypeParameters.SelectAsArray(
                (tp, i, arg) => (TypeParameterSymbol)new EETypeParameterSymbol(this, tp, i, getTypeMap),
                (object)null);
            _allTypeParameters = container.TypeParameters.Concat(_typeParameters);
            this.TypeMap = new TypeMap(allSourceTypeParameters, _allTypeParameters);

            EENamedTypeSymbol.VerifyTypeParameters(this, _typeParameters);

            var substitutedSourceType = container.SubstitutedSourceType;
            this.SubstitutedSourceMethod = sourceMethod.AsMember(substitutedSourceType);
            if (sourceMethod.Arity > 0)
            {
                this.SubstitutedSourceMethod = this.SubstitutedSourceMethod.Construct(_typeParameters.As<TypeSymbol>());
            }
            TypeParameterChecker.Check(this.SubstitutedSourceMethod, _allTypeParameters);

            // Create a map from original parameter to target parameter.
            var parameterBuilder = ArrayBuilder<ParameterSymbol>.GetInstance();

            var substitutedSourceThisParameter = this.SubstitutedSourceMethod.ThisParameter;
            var substitutedSourceHasThisParameter = (object)substitutedSourceThisParameter != null;
            if (substitutedSourceHasThisParameter)
            {
                _thisParameter = MakeParameterSymbol(0, GeneratedNames.ThisProxyFieldName(), substitutedSourceThisParameter);
                Debug.Assert(_thisParameter.Type == this.SubstitutedSourceMethod.ContainingType);
                parameterBuilder.Add(_thisParameter);
            }

            var ordinalOffset = (substitutedSourceHasThisParameter ? 1 : 0);
            foreach (var substitutedSourceParameter in this.SubstitutedSourceMethod.Parameters)
            {
                var ordinal = substitutedSourceParameter.Ordinal + ordinalOffset;
                Debug.Assert(ordinal == parameterBuilder.Count);
                var parameter = MakeParameterSymbol(ordinal, substitutedSourceParameter.Name, substitutedSourceParameter);
                parameterBuilder.Add(parameter);
            }

            _parameters = parameterBuilder.ToImmutableAndFree();

            var localsBuilder = ArrayBuilder<LocalSymbol>.GetInstance();
            var localsMap = PooledDictionary<LocalSymbol, LocalSymbol>.GetInstance();
            foreach (var sourceLocal in sourceLocals)
            {
                var local = sourceLocal.ToOtherMethod(this, this.TypeMap);
                localsMap.Add(sourceLocal, local);
                localsBuilder.Add(local);
            }
            this.Locals = localsBuilder.ToImmutableAndFree();
            localsBuilder = ArrayBuilder<LocalSymbol>.GetInstance();
            foreach (var sourceLocal in sourceLocalsForBinding)
            {
                LocalSymbol local;
                if (!localsMap.TryGetValue(sourceLocal, out local))
                {
                    local = sourceLocal.ToOtherMethod(this, this.TypeMap);
                    localsMap.Add(sourceLocal, local);
                }
                localsBuilder.Add(local);
            }
            this.LocalsForBinding = localsBuilder.ToImmutableAndFree();

            // Create a map from variable name to display class field.
            var displayClassVariables = PooledDictionary<string, DisplayClassVariable>.GetInstance();
            foreach (var pair in sourceDisplayClassVariables)
            {
                var variable = pair.Value;
                var displayClassInstanceFromLocal = variable.DisplayClassInstance as DisplayClassInstanceFromLocal;
                var displayClassInstance = (displayClassInstanceFromLocal == null) ?
                    (DisplayClassInstance)new DisplayClassInstanceFromThis(_parameters[0]) :
                    new DisplayClassInstanceFromLocal((EELocalSymbol)localsMap[displayClassInstanceFromLocal.Local]);
                variable = variable.SubstituteFields(displayClassInstance, this.TypeMap);
                displayClassVariables.Add(pair.Key, variable);
            }

            _displayClassVariables = displayClassVariables.ToImmutableDictionary();
            displayClassVariables.Free();
            localsMap.Free();

            _generateMethodBody = generateMethodBody;
        }
示例#26
0
        private static BoundExpression RewriteLocalInternal(CSharpCompilation compilation, EENamedTypeSymbol container, CSharpSyntaxNode syntax, LocalSymbol local)
        {
            var parameterType  = compilation.GetSpecialType(SpecialType.System_String);
            var getValueMethod = container.GetOrAddSynthesizedMethod(
                ExpressionCompilerConstants.GetVariableValueMethodName,
                (c, n, s) =>
            {
                var returnType = compilation.GetSpecialType(SpecialType.System_Object);
                return(new PlaceholderMethodSymbol(
                           c,
                           s,
                           n,
                           returnType,
                           m => ImmutableArray.Create <ParameterSymbol>(new SynthesizedParameterSymbol(m, parameterType, ordinal: 0, refKind: RefKind.None))));
            });
            var getAddressMethod = container.GetOrAddSynthesizedMethod(
                ExpressionCompilerConstants.GetVariableAddressMethodName,
                (c, n, s) =>
            {
                return(new PlaceholderMethodSymbol(
                           c,
                           s,
                           n,
                           m => ImmutableArray.Create <TypeParameterSymbol>(new SimpleTypeParameterSymbol(m, 0, "<>T")),
                           m => m.TypeParameters[0], // return type is <>T&
                           m => ImmutableArray.Create <ParameterSymbol>(new SynthesizedParameterSymbol(m, parameterType, ordinal: 0, refKind: RefKind.None)),
                           returnValueIsByRef: true));
            });

            return(new BoundPseudoVariable(
                       syntax,
                       local,
                       new ObjectIdExpressions(compilation, getValueMethod, getAddressMethod),
                       local.Type));
        }
示例#27
0
 private static void AppendLocalAndMethod(
     ArrayBuilder<LocalAndMethod> localBuilder,
     ArrayBuilder<MethodSymbol> methodBuilder,
     string name,
     Func<EENamedTypeSymbol, string, string, int, MethodSymbol> getMethod,
     EENamedTypeSymbol container,
     int localOrParameterIndex,
     DkmClrCompilationResultFlags resultFlags)
 {
     // Note: The native EE doesn't do this, but if we don't escape keyword identifiers,
     // the ResultProvider needs to be able to disambiguate cases like "this" and "@this",
     // which it can't do correctly without semantic information.
     name = SyntaxHelpers.EscapeKeywordIdentifiers(name);
     var methodName = GetNextMethodName(methodBuilder);
     var method = getMethod(container, methodName, name, localOrParameterIndex);
     localBuilder.Add(new CSharpLocalAndMethod(name, method, resultFlags));
     methodBuilder.Add(method);
 }
示例#28
0
 private EEMethodSymbol GetParameterMethod(EENamedTypeSymbol container, string methodName, string parameterName, int parameterIndex)
 {
     var syntax = SyntaxFactory.IdentifierName(parameterName);
     return this.CreateMethod(container, methodName, syntax, (EEMethodSymbol method, DiagnosticBag diagnostics, out ImmutableArray<LocalSymbol> declaredLocals) =>
     {
         declaredLocals = ImmutableArray<LocalSymbol>.Empty;
         var parameter = method.Parameters[parameterIndex];
         var expression = new BoundParameter(syntax, parameter);
         return new BoundReturnStatement(syntax, RefKind.None, expression) { WasCompilerGenerated = true };
     });
 }
示例#29
0
 /// <summary>
 /// Rewrite the local reference as a call to a synthesized method.
 /// </summary>
 internal abstract BoundExpression RewriteLocal(CSharpCompilation compilation, EENamedTypeSymbol container, CSharpSyntaxNode syntax);
示例#30
0
        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));
        }
示例#31
0
 internal EEMethodSymbol CreateMethod(
     EENamedTypeSymbol container,
     string methodName,
     CSharpSyntaxNode syntax,
     GenerateMethodBody generateMethodBody)
 {
     return new EEMethodSymbol(
         container,
         methodName,
         syntax.Location,
         _currentFrame,
         _locals,
         _localsForBinding,
         _displayClassVariables,
         generateMethodBody);
 }
示例#32
0
        private static EEAssemblyBuilder CreateModuleBuilder(
            CSharpCompilation compilation,
            ImmutableArray<MethodSymbol> methods,
            ImmutableArray<NamedTypeSymbol> additionalTypes,
            EENamedTypeSymbol synthesizedType,
            Microsoft.CodeAnalysis.CodeGen.CompilationTestData testData,
            DiagnosticBag diagnostics)
        {
            // Each assembly must have a unique name.
            var emitOptions = new EmitOptions(outputNameOverride: ExpressionCompilerUtilities.GenerateUniqueName());

            var dynamicOperationContextType = GetNonDisplayClassContainer(synthesizedType.SubstitutedSourceType);

            string runtimeMetadataVersion = compilation.GetRuntimeMetadataVersion(emitOptions, diagnostics);
            var serializationProperties = compilation.ConstructModuleSerializationProperties(emitOptions, runtimeMetadataVersion);
            return new EEAssemblyBuilder(compilation.SourceAssembly, emitOptions, methods, serializationProperties, additionalTypes, dynamicOperationContextType, testData);
        }
示例#33
0
 private void AppendParameterAndMethod(
     ArrayBuilder<LocalAndMethod> localBuilder,
     ArrayBuilder<MethodSymbol> methodBuilder,
     ParameterSymbol parameter,
     EENamedTypeSymbol container,
     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, parameterIndex);
     localBuilder.Add(new CSharpLocalAndMethod(name, name, method, DkmClrCompilationResultFlags.None));
     methodBuilder.Add(method);
 }
示例#34
0
 private void AppendLocalAndMethod(
     ArrayBuilder<LocalAndMethod> localBuilder,
     ArrayBuilder<MethodSymbol> methodBuilder,
     LocalSymbol local,
     EENamedTypeSymbol container,
     int localIndex,
     DkmClrCompilationResultFlags resultFlags)
 {
     var methodName = GetNextMethodName(methodBuilder);
     var method = this.GetLocalMethod(container, methodName, local.Name, localIndex);
     localBuilder.Add(MakeLocalAndMethod(local, method, resultFlags));
     methodBuilder.Add(method);
 }
示例#35
0
        /// <summary>
        /// Generate a class containing methods that represent
        /// the set of arguments and locals at the current scope.
        /// </summary>
        internal CommonPEModuleBuilder CompileGetLocals(
            string typeName,
            ArrayBuilder<LocalAndMethod> localBuilder,
            bool argumentsOnly,
            ImmutableArray<Alias> aliases,
            Microsoft.CodeAnalysis.CodeGen.CompilationTestData testData,
            DiagnosticBag diagnostics)
        {
            var objectType = this.Compilation.GetSpecialType(SpecialType.System_Object);
            var allTypeParameters = _currentFrame.GetAllTypeParameters();
            var additionalTypes = ArrayBuilder<NamedTypeSymbol>.GetInstance();

            EENamedTypeSymbol typeVariablesType = null;
            if (!argumentsOnly && (allTypeParameters.Length > 0))
            {
                // Generate a generic type with matching type parameters.
                // A null instance of the type will be used to represent the
                // "Type variables" local.
                typeVariablesType = new EENamedTypeSymbol(
                    this.Compilation.SourceModule.GlobalNamespace,
                    objectType,
                    _syntax,
                    _currentFrame,
                    ExpressionCompilerConstants.TypeVariablesClassName,
                    (m, t) => ImmutableArray.Create<MethodSymbol>(new EEConstructorSymbol(t)),
                    allTypeParameters,
                    (t1, t2) => allTypeParameters.SelectAsArray((tp, i, t) => (TypeParameterSymbol)new SimpleTypeParameterSymbol(t, i, tp.Name), t2));
                additionalTypes.Add(typeVariablesType);
            }

            var synthesizedType = new EENamedTypeSymbol(
                Compilation.SourceModule.GlobalNamespace,
                objectType,
                _syntax,
                _currentFrame,
                typeName,
                (m, container) =>
                {
                    var methodBuilder = ArrayBuilder<MethodSymbol>.GetInstance();

                    if (!argumentsOnly)
                    {
                        // Pseudo-variables: $exception, $ReturnValue, etc.
                        if (aliases.Length > 0)
                        {
                            var sourceAssembly = Compilation.SourceAssembly;
                            var typeNameDecoder = new EETypeNameDecoder(Compilation, (PEModuleSymbol)_currentFrame.ContainingModule);
                            foreach (var alias in aliases)
                            {
                                if (alias.IsReturnValueWithoutIndex())
                                {
                                    Debug.Assert(aliases.Count(a => a.Kind == DkmClrAliasKind.ReturnValue) > 1);
                                    continue;
                                }

                                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".
                        if (!m.IsStatic && (!IsDisplayClassType(m.ContainingType) || _displayClassVariables.ContainsKey(GeneratedNames.ThisProxyFieldName())))
                        {
                            var methodName = GetNextMethodName(methodBuilder);
                            var method = this.GetThisMethod(container, methodName);
                            localBuilder.Add(new CSharpLocalAndMethod("this", "this", method, DkmClrCompilationResultFlags.None)); // Note: writable in dev11.
                            methodBuilder.Add(method);
                        }
                    }

                    // Hoisted method parameters (represented as locals in the EE).
                    if (!_hoistedParameterNames.IsEmpty)
                    {
                        int localIndex = 0;
                        foreach (var local in _localsForBinding)
                        {
                            // Since we are showing hoisted method parameters first, the parameters may appear out of order
                            // in the Locals window if only some of the parameters are hoisted.  This is consistent with the
                            // behavior of the old EE.
                            if (_hoistedParameterNames.Contains(local.Name))
                            {
                                AppendLocalAndMethod(localBuilder, methodBuilder, local, container, localIndex, GetLocalResultFlags(local));
                            }

                            localIndex++;
                        }
                    }

                    // Method parameters (except those that have been hoisted).
                    int parameterIndex = m.IsStatic ? 0 : 1;
                    foreach (var parameter in m.Parameters)
                    {
                        var parameterName = parameter.Name;
                        if (!_hoistedParameterNames.Contains(parameterName) && GeneratedNames.GetKind(parameterName) == GeneratedNameKind.None)
                        {
                            AppendParameterAndMethod(localBuilder, methodBuilder, parameter, container, parameterIndex);
                        }

                        parameterIndex++;
                    }

                    if (!argumentsOnly)
                    {
                        // Locals.
                        int localIndex = 0;
                        foreach (var local in _localsForBinding)
                        {
                            if (!_hoistedParameterNames.Contains(local.Name))
                            {
                                AppendLocalAndMethod(localBuilder, methodBuilder, local, container, localIndex, GetLocalResultFlags(local));
                            }

                            localIndex++;
                        }

                        // "Type variables".
                        if ((object)typeVariablesType != null)
                        {
                            var methodName = GetNextMethodName(methodBuilder);
                            var returnType = typeVariablesType.Construct(allTypeParameters.Cast<TypeParameterSymbol, TypeSymbol>());
                            var method = this.GetTypeVariablesMethod(container, methodName, returnType);
                            localBuilder.Add(new CSharpLocalAndMethod(
                                ExpressionCompilerConstants.TypeVariablesLocalName,
                                ExpressionCompilerConstants.TypeVariablesLocalName,
                                method,
                                DkmClrCompilationResultFlags.ReadOnlyResult));
                            methodBuilder.Add(method);
                        }
                    }

                    return methodBuilder.ToImmutableAndFree();
                });

            additionalTypes.Add(synthesizedType);

            var module = CreateModuleBuilder(
                this.Compilation,
                synthesizedType.Methods,
                additionalTypes: additionalTypes.ToImmutableAndFree(),
                synthesizedType: synthesizedType,
                testData: testData,
                diagnostics: diagnostics);

            Debug.Assert(module != null);

            this.Compilation.Compile(
                module,
                win32Resources: null,
                xmlDocStream: null,
                emittingPdb: false,
                diagnostics: diagnostics,
                filterOpt: null,
                cancellationToken: CancellationToken.None);

            return diagnostics.HasAnyErrors() ? null : module;
        }
示例#36
0
        internal CommonPEModuleBuilder CompileAssignment(
            string typeName,
            string methodName,
            ImmutableArray<Alias> aliases,
            Microsoft.CodeAnalysis.CodeGen.CompilationTestData testData,
            DiagnosticBag diagnostics,
            out ResultProperties resultProperties)
        {
            var objectType = this.Compilation.GetSpecialType(SpecialType.System_Object);
            var synthesizedType = new EENamedTypeSymbol(
                Compilation.SourceModule.GlobalNamespace,
                objectType,
                _syntax,
                _currentFrame,
                typeName,
                methodName,
                this,
                (method, diags) =>
                {
                    var hasDisplayClassThis = _displayClassVariables.ContainsKey(GeneratedNames.ThisProxyFieldName());
                    var binder = ExtendBinderChain(
                        _syntax,
                        aliases,
                        method,
                        this.NamespaceBinder,
                        hasDisplayClassThis,
                        methodNotType: true);
                    return BindAssignment(binder, (ExpressionSyntax)_syntax, diags);
                });

            var module = CreateModuleBuilder(
                this.Compilation,
                synthesizedType.Methods,
                additionalTypes: ImmutableArray.Create((NamedTypeSymbol)synthesizedType),
                synthesizedType: synthesizedType,
                testData: testData,
                diagnostics: diagnostics);

            Debug.Assert(module != null);

            this.Compilation.Compile(
                module,
                win32Resources: null,
                xmlDocStream: null,
                emittingPdb: false,
                diagnostics: diagnostics,
                filterOpt: null,
                cancellationToken: CancellationToken.None);

            if (diagnostics.HasAnyErrors())
            {
                resultProperties = default(ResultProperties);
                return null;
            }

            // Should be no name mangling since the caller provided explicit names.
            Debug.Assert(synthesizedType.MetadataName == typeName);
            Debug.Assert(synthesizedType.GetMembers()[0].MetadataName == methodName);

            resultProperties = new ResultProperties(DkmClrCompilationResultFlags.PotentialSideEffect);
            return module;
        }
示例#37
0
 /// <summary>
 /// Rewrite the local reference as a call to a synthesized method.
 /// </summary>
 internal abstract BoundExpression RewriteLocal(CSharpCompilation compilation, EENamedTypeSymbol container, SyntaxNode syntax, DiagnosticBag diagnostics);
 internal static BoundExpression RewriteLocal(CSharpCompilation compilation, EENamedTypeSymbol container, CSharpSyntaxNode syntax, LocalSymbol local)
 {
     return RewriteLocalInternal(compilation, container, syntax, local);
 }
示例#39
0
 internal static BoundNode Rewrite(CSharpCompilation compilation, EENamedTypeSymbol container, HashSet<LocalSymbol> declaredLocals, BoundNode node, DiagnosticBag diagnostics)
 {
     var rewriter = new PlaceholderLocalRewriter(compilation, container, declaredLocals, diagnostics);
     return rewriter.Visit(node);
 }
示例#40
0
 private EEMethodSymbol GetLocalMethod(EENamedTypeSymbol container, string methodName, string localName, int localIndex)
 {
     var syntax = SyntaxFactory.IdentifierName(localName);
     return this.CreateMethod(container, methodName, syntax, (method, diagnostics) =>
     {
         var local = method.LocalsForBinding[localIndex];
         var expression = new BoundLocal(syntax, local, constantValueOpt: local.GetConstantValue(null, null, diagnostics), type: local.Type);
         return new BoundReturnStatement(syntax, expression) { WasCompilerGenerated = true };
     });
 }
示例#41
0
        internal EEMethodSymbol(
            EENamedTypeSymbol container,
            string name,
            Location location,
            MethodSymbol sourceMethod,
            ImmutableArray <LocalSymbol> sourceLocals,
            ImmutableArray <LocalSymbol> sourceLocalsForBinding,
            ImmutableDictionary <string, DisplayClassVariable> sourceDisplayClassVariables,
            GenerateMethodBody generateMethodBody)
        {
            Debug.Assert(sourceMethod.IsDefinition);
            Debug.Assert(sourceMethod.ContainingSymbol == container.SubstitutedSourceType.OriginalDefinition);
            Debug.Assert(sourceLocals.All(l => l.ContainingSymbol == sourceMethod));

            _container = container;
            _name      = name;
            _locations = ImmutableArray.Create(location);

            // What we want is to map all original type parameters to the corresponding new type parameters
            // (since the old ones have the wrong owners).  Unfortunately, we have a circular dependency:
            //   1) Each new type parameter requires the entire map in order to be able to construct its constraint list.
            //   2) The map cannot be constructed until all new type parameters exist.
            // Our solution is to pass each new type parameter a lazy reference to the type map.  We then
            // initialize the map as soon as the new type parameters are available - and before they are
            // handed out - so that there is never a period where they can require the type map and find
            // it uninitialized.

            var sourceMethodTypeParameters = sourceMethod.TypeParameters;
            var allSourceTypeParameters    = container.SourceTypeParameters.Concat(sourceMethodTypeParameters);

            var getTypeMap = new Func <TypeMap>(() => this.TypeMap);

            _typeParameters = sourceMethodTypeParameters.SelectAsArray(
                (tp, i, arg) => (TypeParameterSymbol) new EETypeParameterSymbol(this, tp, i, getTypeMap),
                (object)null);
            _allTypeParameters = container.TypeParameters.Concat(_typeParameters);
            this.TypeMap       = new TypeMap(allSourceTypeParameters, _allTypeParameters);

            EENamedTypeSymbol.VerifyTypeParameters(this, _typeParameters);

            var substitutedSourceType = container.SubstitutedSourceType;

            this.SubstitutedSourceMethod = sourceMethod.AsMember(substitutedSourceType);
            if (sourceMethod.Arity > 0)
            {
                this.SubstitutedSourceMethod = this.SubstitutedSourceMethod.Construct(_typeParameters.As <TypeSymbol>());
            }
            TypeParameterChecker.Check(this.SubstitutedSourceMethod, _allTypeParameters);

            // Create a map from original parameter to target parameter.
            var parameterBuilder = ArrayBuilder <ParameterSymbol> .GetInstance();

            var substitutedSourceThisParameter    = this.SubstitutedSourceMethod.ThisParameter;
            var substitutedSourceHasThisParameter = (object)substitutedSourceThisParameter != null;

            if (substitutedSourceHasThisParameter)
            {
                _thisParameter = MakeParameterSymbol(0, GeneratedNames.ThisProxyFieldName(), substitutedSourceThisParameter);
                Debug.Assert(_thisParameter.Type == this.SubstitutedSourceMethod.ContainingType);
                parameterBuilder.Add(_thisParameter);
            }

            var ordinalOffset = (substitutedSourceHasThisParameter ? 1 : 0);

            foreach (var substitutedSourceParameter in this.SubstitutedSourceMethod.Parameters)
            {
                var ordinal = substitutedSourceParameter.Ordinal + ordinalOffset;
                Debug.Assert(ordinal == parameterBuilder.Count);
                var parameter = MakeParameterSymbol(ordinal, substitutedSourceParameter.Name, substitutedSourceParameter);
                parameterBuilder.Add(parameter);
            }

            _parameters = parameterBuilder.ToImmutableAndFree();

            var localsBuilder = ArrayBuilder <LocalSymbol> .GetInstance();

            var localsMap = PooledDictionary <LocalSymbol, LocalSymbol> .GetInstance();

            foreach (var sourceLocal in sourceLocals)
            {
                var local = sourceLocal.ToOtherMethod(this, this.TypeMap);
                localsMap.Add(sourceLocal, local);
                localsBuilder.Add(local);
            }
            this.Locals   = localsBuilder.ToImmutableAndFree();
            localsBuilder = ArrayBuilder <LocalSymbol> .GetInstance();

            foreach (var sourceLocal in sourceLocalsForBinding)
            {
                LocalSymbol local;
                if (!localsMap.TryGetValue(sourceLocal, out local))
                {
                    local = sourceLocal.ToOtherMethod(this, this.TypeMap);
                    localsMap.Add(sourceLocal, local);
                }
                localsBuilder.Add(local);
            }
            this.LocalsForBinding = localsBuilder.ToImmutableAndFree();

            // Create a map from variable name to display class field.
            var displayClassVariables = PooledDictionary <string, DisplayClassVariable> .GetInstance();

            foreach (var pair in sourceDisplayClassVariables)
            {
                var variable = pair.Value;
                var oldDisplayClassInstance = variable.DisplayClassInstance;

                // Note: we don't call ToOtherMethod in the local case because doing so would produce
                // a new LocalSymbol that would not be ReferenceEquals to the one in this.LocalsForBinding.
                var oldDisplayClassInstanceFromLocal = oldDisplayClassInstance as DisplayClassInstanceFromLocal;
                var newDisplayClassInstance          = (oldDisplayClassInstanceFromLocal == null) ?
                                                       oldDisplayClassInstance.ToOtherMethod(this, this.TypeMap) :
                                                       new DisplayClassInstanceFromLocal((EELocalSymbol)localsMap[oldDisplayClassInstanceFromLocal.Local]);

                variable = variable.SubstituteFields(newDisplayClassInstance, this.TypeMap);
                displayClassVariables.Add(pair.Key, variable);
            }

            _displayClassVariables = displayClassVariables.ToImmutableDictionary();
            displayClassVariables.Free();
            localsMap.Free();

            _generateMethodBody = generateMethodBody;
        }
示例#42
0
 private EEMethodSymbol GetParameterMethod(EENamedTypeSymbol container, string methodName, string parameterName, int parameterIndex)
 {
     var syntax = SyntaxFactory.IdentifierName(parameterName);
     return this.CreateMethod(container, methodName, syntax, (method, diagnostics) =>
     {
         var parameter = method.Parameters[parameterIndex];
         var expression = new BoundParameter(syntax, parameter);
         return new BoundReturnStatement(syntax, expression) { WasCompilerGenerated = true };
     });
 }
示例#43
0
 private EEMethodSymbol GetThisMethod(EENamedTypeSymbol container, string methodName)
 {
     var syntax = SyntaxFactory.ThisExpression();
     return this.CreateMethod(container, methodName, syntax, (EEMethodSymbol method, DiagnosticBag diagnostics, out ImmutableArray<LocalSymbol> declaredLocals) =>
     {
         declaredLocals = ImmutableArray<LocalSymbol>.Empty;
         var expression = new BoundThisReference(syntax, GetNonDisplayClassContainer(container.SubstitutedSourceType));
         return new BoundReturnStatement(syntax, RefKind.None, expression) { WasCompilerGenerated = true };
     });
 }
示例#44
0
 private EEMethodSymbol GetThisMethod(EENamedTypeSymbol container, string methodName)
 {
     var syntax = SyntaxFactory.ThisExpression();
     return this.CreateMethod(container, methodName, syntax, (method, diagnostics) =>
     {
         var expression = new BoundThisReference(syntax, GetNonDisplayClassContainer(container.SubstitutedSourceType));
         return new BoundReturnStatement(syntax, expression) { WasCompilerGenerated = true };
     });
 }
示例#45
0
 private EEMethodSymbol GetPseudoVariableMethod(
     TypeNameDecoder<PEModuleSymbol, TypeSymbol> typeNameDecoder,
     EENamedTypeSymbol container,
     string methodName,
     Alias alias)
 {
     var syntax = SyntaxFactory.IdentifierName(SyntaxFactory.MissingToken(SyntaxKind.IdentifierToken));
     return this.CreateMethod(container, methodName, syntax, (method, diagnostics) =>
     {
         var local = PlaceholderLocalBinder.CreatePlaceholderLocal(typeNameDecoder, method, alias);
         var expression = new BoundLocal(syntax, local, constantValueOpt: null, type: local.Type);
         return new BoundReturnStatement(syntax, expression) { WasCompilerGenerated = true };
     });
 }
示例#46
0
 private EEMethodSymbol GetTypeVariablesMethod(EENamedTypeSymbol container, string methodName, NamedTypeSymbol typeVariablesType)
 {
     var syntax = SyntaxFactory.IdentifierName(SyntaxFactory.MissingToken(SyntaxKind.IdentifierToken));
     return this.CreateMethod(container, methodName, syntax, (method, diagnostics) =>
     {
         var type = method.TypeMap.SubstituteNamedType(typeVariablesType);
         var expression = new BoundObjectCreationExpression(syntax, type.InstanceConstructors[0]);
         var statement = new BoundReturnStatement(syntax, expression) { WasCompilerGenerated = true };
         return statement;
     });
 }
示例#47
0
 /// <summary>
 /// Rewrite the local reference as a call to a synthesized method.
 /// </summary>
 internal abstract BoundExpression RewriteLocal(CSharpCompilation compilation, EENamedTypeSymbol container, SyntaxNode syntax, DiagnosticBag diagnostics);
示例#48
0
        internal override BoundExpression RewriteLocal(CSharpCompilation compilation, EENamedTypeSymbol container, CSharpSyntaxNode syntax)
        {
            var method = container.GetOrAddSynthesizedMethod(
                ExpressionCompilerConstants.GetReturnValueMethodName,
                (c, n, s) =>
            {
                var parameterType = compilation.GetSpecialType(SpecialType.System_Int32);
                var returnType    = compilation.GetSpecialType(SpecialType.System_Object);
                return(new PlaceholderMethodSymbol(
                           c,
                           s,
                           n,
                           returnType,
                           m => ImmutableArray.Create <ParameterSymbol>(new SynthesizedParameterSymbol(m, parameterType, ordinal: 0, refKind: RefKind.None))));
            });
            var argument = new BoundLiteral(
                syntax,
                Microsoft.CodeAnalysis.ConstantValue.Create(_index),
                method.Parameters[0].Type);
            var call = BoundCall.Synthesized(
                syntax,
                receiverOpt: null,
                method: method,
                arguments: ImmutableArray.Create <BoundExpression>(argument));

            return(ConvertToLocalType(compilation, call, this.Type));
        }