Пример #1
0
        private IEnumerable <string> HandleFieldDeclaration(MemberDeclarationSyntax node, VariableDeclarationSyntax variableDeclarationSyntax, SyntaxTokenList modifiers, BaseTypeDeclarationSyntax declaringType)
        {
            var declaringTypeVar = Context.DefinitionVariables.GetLastOf(MemberKind.Type).VariableName;

            var fieldDefVars = new List <string>(variableDeclarationSyntax.Variables.Count);

            var type            = ResolveType(variableDeclarationSyntax.Type);
            var fieldType       = ProcessRequiredModifiers(modifiers, type) ?? type;
            var fieldAttributes = MapAttributes(modifiers);

            foreach (var field in variableDeclarationSyntax.Variables)
            {
                var fieldVar = MethodExtensions.LocalVariableNameFor("fld", declaringType.Identifier.ValueText, field.Identifier.ValueText.CamelCase());
                fieldDefVars.Add(fieldVar);

                var exps = CecilDefinitionsFactory.Field(declaringTypeVar, fieldVar, field.Identifier.ValueText, fieldType, fieldAttributes);
                AddCecilExpressions(exps);

                HandleAttributesInMemberDeclaration(node.AttributeLists, fieldVar);

                Context.DefinitionVariables.RegisterNonMethod(declaringType.Identifier.Text, field.Identifier.ValueText, MemberKind.Field, fieldVar);
            }

            return(fieldDefVars);
        }
Пример #2
0
        protected void ProcessMethodDeclaration <T>(T node, string simpleName, string fqName, string returnType, Action <string> runWithCurrent, IList <TypeParameterSyntax> typeParameters = null) where T : BaseMethodDeclarationSyntax
        {
            typeParameters = typeParameters ?? Array.Empty <TypeParameterSyntax>();
            var declaringTypeName = DeclaringTypeNameFor(node);

            var methodVar = MethodExtensions.LocalVariableNameFor(declaringTypeName, simpleName, node.MangleName(Context.SemanticModel));

            AddOrUpdateMethodDefinition(methodVar, fqName, node.Modifiers.MethodModifiersToCecil(ModifiersToCecil, GetSpecificModifiers(), DeclaredSymbolFor(node)), returnType, typeParameters);
            AddCecilExpression("{0}.Methods.Add({1});", Context.DefinitionVariables.GetLastOf(MemberKind.Type).VariableName, methodVar);

            HandleAttributesInMemberDeclaration(node.AttributeLists, TargetDoesNotMatch, SyntaxKind.ReturnKeyword, methodVar);                  // Normal method attrs.
            HandleAttributesInMemberDeclaration(node.AttributeLists, TargetMatches, SyntaxKind.ReturnKeyword, $"{methodVar}.MethodReturnType"); // [return:Attr]

            var isAbstract = DeclaredSymbolFor(node).IsAbstract;

            if (!isAbstract)
            {
                ilVar = MethodExtensions.LocalVariableNameFor("il", declaringTypeName, simpleName, node.MangleName(Context.SemanticModel));
                AddCecilExpression(@"var {0} = {1}.Body.GetILProcessor();", ilVar, methodVar);
            }

            WithCurrentMethod(declaringTypeName, methodVar, fqName, node.ParameterList.Parameters.Select(p => Context.GetTypeInfo(p.Type).Type.Name).ToArray(), runWithCurrent);

            //TODO: Move this to default ctor handling and rely on VisitReturnStatement here instead
            if (!isAbstract && !node.DescendantNodes().Any(n => n.Kind() == SyntaxKind.ReturnStatement))
            {
                AddCilInstruction(ilVar, OpCodes.Ret);
            }
        }
Пример #3
0
        public override void VisitEnumDeclaration(EnumDeclarationSyntax node)
        {
            _memberCollector = new EnumMemberValueCollector();
            node.Accept(_memberCollector);

            var enumType = TempLocalVar(node.Identifier.ValueText);
            var attrs    = ModifiersToCecil("TypeAttributes", node.Modifiers, "Private");
            var typeDef  = CecilDefinitionsFactory.Type(Context, enumType, node.Identifier.ValueText, attrs + " | TypeAttributes.Sealed", Context.TypeResolver.Resolve("System.Enum"), false, Array.Empty <string>());

            AddCecilExpressions(typeDef);

            using (Context.DefinitionVariables.WithCurrent(node.Parent.IsKind(SyntaxKind.CompilationUnit) ? "" : node.Parent.ResolveDeclaringType().Identifier.ValueText, node.Identifier.ValueText, MemberKind.Type,
                                                           enumType))
            {
                //.class private auto ansi MyEnum
                //TODO: introduce TypeSystem.CoreLib.Enum/Action/etc...

                var fieldVar      = MethodExtensions.LocalVariableNameFor("valueField", node.Identifier.ValueText);
                var valueFieldExp = CecilDefinitionsFactory.Field(enumType, fieldVar, "value__", "assembly.MainModule.TypeSystem.Int32",
                                                                  "FieldAttributes.SpecialName | FieldAttributes.RTSpecialName | FieldAttributes.Public");
                AddCecilExpressions(valueFieldExp);

                HandleAttributesInMemberDeclaration(node.AttributeLists, enumType);

                base.VisitEnumDeclaration(node);
            }
        }
Пример #4
0
        private void ProcessPrefixPostfixOperators(ExpressionSyntax operand, OpCode opCode, bool isPrefix)
        {
            Visit(operand);
            InjectRequiredConversions(operand);

            var assignmentVisitor = new AssignmentVisitor(Context, ilVar);

            var operandInfo = Context.SemanticModel.GetSymbolInfo(operand);

            if (operandInfo.Symbol != null && operandInfo.Symbol.Kind != SymbolKind.Field && operandInfo.Symbol.Kind != SymbolKind.Property) // Fields / Properties requires more complex handling to load the owning reference.
            {
                if (!isPrefix)                                                                                                               // For *postfix* operators we duplicate the value *before* applying the operator...
                {
                    AddCilInstruction(ilVar, OpCodes.Dup);
                }

                AddCilInstruction(ilVar, OpCodes.Ldc_I4_1);
                AddCilInstruction(ilVar, opCode);

                if (isPrefix) // For prefix operators we duplicate the value *after* applying the operator...
                {
                    AddCilInstruction(ilVar, OpCodes.Dup);
                }

                //assign (top of stack to the operand)
                assignmentVisitor.InstructionPrecedingValueToLoad = Context.CurrentLine;
                operand.Accept(assignmentVisitor);
                return;
            }

            var tempLocalName = MethodExtensions.LocalVariableNameFor("tmp_", "tmp_".UniqueId().ToString());

            AddCecilExpression($"var {tempLocalName} = new VariableDefinition({Context.TypeResolver.Resolve(Context.SemanticModel.GetTypeInfo(operand).Type)});");
            AddCecilExpression($"{Context.DefinitionVariables.GetLastOf(MemberKind.Method).VariableName}.Body.Variables.Add({tempLocalName});");

            if (isPrefix)
            {
                AddCilInstruction(ilVar, OpCodes.Ldc_I4_1);
                AddCilInstruction(ilVar, opCode);
            }

            AddCilInstruction(ilVar, OpCodes.Stloc, tempLocalName);
            AddCilInstruction(ilVar, OpCodes.Ldloc, tempLocalName);
            assignmentVisitor.InstructionPrecedingValueToLoad = Context.CurrentLine;
            AddCilInstruction(ilVar, OpCodes.Ldloc, tempLocalName);

            if (!isPrefix)
            {
                AddCilInstruction(ilVar, OpCodes.Ldc_I4_1);
                AddCilInstruction(ilVar, opCode);
            }

            // assign (top of stack to the operand)
            operand.Accept(assignmentVisitor);
        }
Пример #5
0
        private void DeclareAndInitializeValueTypeLocalVariable()
        {
            var resolvedVarType = Context.TypeResolver.Resolve(ctorInfo.Symbol.ContainingType);
            var tempLocalName   = MethodExtensions.LocalVariableNameFor("tmp_", "tmp_".UniqueId().ToString());

            AddCecilExpression("var {0} = new VariableDefinition({1});", tempLocalName, resolvedVarType);

            AddCecilExpression("{0}.Body.Variables.Add({1});", Context.DefinitionVariables.GetLastOf(MemberKind.Method).VariableName, tempLocalName);

            AddCilInstruction(ilVar, OpCodes.Ldloca_S, tempLocalName);
            AddCilInstruction(ilVar, OpCodes.Initobj, ctorInfo.Symbol.ContainingType.ResolveExpression(Context));
            AddCilInstruction(ilVar, OpCodes.Ldloc, tempLocalName);
        }
Пример #6
0
        public static string Constructor(IVisitorContext context, out string ctorLocalVar, string typeName, string methodAccessibility, string[] paramTypes, string methodDefinitionPropertyValues = null)
        {
            ctorLocalVar = MethodExtensions.LocalVariableNameFor(typeName, "ctor", "");
            context.DefinitionVariables.RegisterMethod(typeName, ".ctor", paramTypes, ctorLocalVar);

            var exp = $@"var {ctorLocalVar} = new MethodDefinition("".ctor"", {methodAccessibility} | MethodAttributes.HideBySig | {ConstructorDeclarationVisitor.CtorFlags}, assembly.MainModule.TypeSystem.Void)";

            if (methodDefinitionPropertyValues != null)
            {
                exp = exp + $"{{ {methodDefinitionPropertyValues} }}";
            }

            return(exp + ";");
        }
Пример #7
0
        public override void VisitParenthesizedExpression(ParenthesizedExpressionSyntax node)
        {
            base.VisitParenthesizedExpression(node);

            var localVarParent = (CSharpSyntaxNode)node.Parent;

            if (localVarParent.Accept(new UsageVisitor()) == UsageKind.CallTarget)
            {
                var tempLocalName = MethodExtensions.LocalVariableNameFor("tmp_", "tmp_".UniqueId().ToString());
                AddCecilExpression("var {0} = new VariableDefinition(assembly.MainModule.TypeSystem.Int32);", tempLocalName);
                AddCecilExpression("{0}.Body.Variables.Add({1});", Context.DefinitionVariables.GetLastOf(MemberKind.Method).VariableName, tempLocalName);

                AddCilInstruction(ilVar, OpCodes.Stloc, tempLocalName);
                AddCilInstruction(ilVar, OpCodes.Ldloca_S, tempLocalName);
            }
        }
Пример #8
0
        public override void VisitEnumMemberDeclaration(EnumMemberDeclarationSyntax node)
        {
            // Adds a field like:
            // .field public static literal valuetype xxx.MyEnum Second = int32(1)
            var enumMemberValue = _memberCollector[node];
            var enumVarDef      = Context.DefinitionVariables.GetLastOf(MemberKind.Type);

            var fieldVar = MethodExtensions.LocalVariableNameFor($"em_{enumVarDef.MemberName}_{NextLocalVariableId()}", node.Identifier.ValueText);
            var exp      = CecilDefinitionsFactory.Field(enumVarDef.VariableName, fieldVar, node.Identifier.ValueText, enumVarDef.VariableName,
                                                         "FieldAttributes.Static | FieldAttributes.Literal | FieldAttributes.Public | FieldAttributes.HasDefault", $"Constant = {enumMemberValue}");

            AddCecilExpressions(exp);

            HandleAttributesInMemberDeclaration(node.AttributeLists, fieldVar);

            base.VisitEnumMemberDeclaration(node);
        }
Пример #9
0
        public override void VisitLiteralExpression(LiteralExpressionSyntax node)
        {
            switch (node.Kind())
            {
            case SyntaxKind.NullLiteralExpression:
                AddCilInstruction(ilVar, OpCodes.Ldnull);
                break;

            case SyntaxKind.StringLiteralExpression:
                AddCilInstruction(ilVar, OpCodes.Ldstr, node.ToFullString());
                break;

            case SyntaxKind.CharacterLiteralExpression:
            case SyntaxKind.NumericLiteralExpression:
                AddLocalVariableAndHandleCallOnValueTypeLiterals(node, "assembly.MainModule.TypeSystem.Int32", node.ToString());
                break;

            case SyntaxKind.TrueLiteralExpression:
            case SyntaxKind.FalseLiteralExpression:
                AddLocalVariableAndHandleCallOnValueTypeLiterals(node, "assembly.MainModule.TypeSystem.Boolean", bool.Parse(node.ToString()) ? 1 : 0);
                break;

            default:
                throw new ArgumentException($"Literal ( {node}) of type {node.Kind()} not supported yet.");
            }

            void AddLocalVariableAndHandleCallOnValueTypeLiterals(LiteralExpressionSyntax literalNode, string cecilTypeSystemReference, object literalValue)
            {
                AddCilInstruction(ilVar, LoadOpCodeFor(literalNode), literalValue);
                var localVarParent = (CSharpSyntaxNode)literalNode.Parent;

                if (localVarParent.Accept(new UsageVisitor()) == UsageKind.CallTarget)
                {
                    var tempLocalName = MethodExtensions.LocalVariableNameFor("tmp_", "tmp_".UniqueId().ToString());
                    AddCecilExpression("var {0} = new VariableDefinition({1});", tempLocalName, cecilTypeSystemReference);
                    AddCecilExpression("{0}.Body.Variables.Add({1});", Context.DefinitionVariables.GetLastOf(MemberKind.Method).VariableName, tempLocalName);

                    AddCilInstruction(ilVar, OpCodes.Stloc, $"{tempLocalName}");
                    AddCilInstruction(ilVar, OpCodes.Ldloca_S, $"{tempLocalName}");
                }
            }
        }