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); }
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); } }
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); } }
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); }
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); }
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 + ";"); }
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); } }
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); }
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}"); } } }