private IEnumerable<ITypeSymbol> InferTypeInPostfixUnaryExpression(PostfixUnaryExpressionSyntax postfixUnaryExpressionSyntax, SyntaxToken? previousToken = null) { // If we're after a postfix ++ or -- then we can't infer anything. if (previousToken.HasValue) { return SpecializedCollections.EmptyEnumerable<ITypeSymbol>(); } switch (postfixUnaryExpressionSyntax.CSharpKind()) { case SyntaxKind.PostDecrementExpression: case SyntaxKind.PostIncrementExpression: return SpecializedCollections.SingletonEnumerable(this.Compilation.GetSpecialType(SpecialType.System_Int32)); } return SpecializedCollections.EmptyEnumerable<ITypeSymbol>(); }
public FlatOperand ResolveExpression(PostfixUnaryExpressionSyntax pues, TypeInfo result_type, FlatOperand into_lvalue, List<FlatStatement> instructions) { if (into_lvalue == null) { into_lvalue = this.AllocateRegister(""); into_lvalue = into_lvalue.GetLValue(this, instructions); } SymbolInfo si = Model.GetSymbolInfo(pues.Operand); FlatOperand fop_subject; switch (si.Symbol.Kind) { case SymbolKind.Parameter: { IParameterSymbol ps = (IParameterSymbol)si.Symbol; if (ps.RefKind == RefKind.None) { FlatOperand op = ResolveExpression(pues.Operand, null, instructions); instructions.Add(FlatStatement.DUPLICATE(into_lvalue, op)); FlatOperand new_lvalue = op.GetLValue(this,instructions); switch (pues.CSharpKind()) { case SyntaxKind.PostIncrementExpression: instructions.Add(FlatStatement.ADD(new_lvalue, op, FlatOperand.Immediate(FlatValue.Int32(1)))); instructions.Add(FlatStatement.ARRAYSET(FlatOperand.Inputs(), FlatOperand.Immediate(FlatValue.Int32(op.OperandIndex)), new_lvalue.AsRValue(FlatValue.FromType(result_type.ConvertedType)))); return into_lvalue.AsRValue(FlatValue.FromType(result_type.ConvertedType)); case SyntaxKind.PostDecrementExpression: instructions.Add(FlatStatement.SUB(new_lvalue, op, FlatOperand.Immediate(FlatValue.Int32(1)))); instructions.Add(FlatStatement.ARRAYSET(FlatOperand.Inputs(), FlatOperand.Immediate(FlatValue.Int32(op.OperandIndex)), new_lvalue.AsRValue(FlatValue.FromType(result_type.ConvertedType)))); return into_lvalue.AsRValue(FlatValue.FromType(result_type.ConvertedType)); } } else { int numParam = 0; FlatOperand fop_duplicate = ResolveParameter(pues.Operand, null, out numParam, instructions); FlatOperand new_lvalue = fop_duplicate.GetLValue(this, instructions); instructions.Add(FlatStatement.DUPLICATE(into_lvalue, fop_duplicate)); switch (pues.CSharpKind()) { case SyntaxKind.PostIncrementExpression: instructions.Add(FlatStatement.ADD(new_lvalue, fop_duplicate, FlatOperand.Immediate(FlatValue.Int32(1)))); instructions.Add(FlatStatement.REREFERENCE(FlatOperand.InputRef(numParam,fop_duplicate.ImmediateValue), fop_duplicate)); return into_lvalue.AsRValue(FlatValue.FromType(result_type.ConvertedType)); case SyntaxKind.PostDecrementExpression: instructions.Add(FlatStatement.SUB(new_lvalue, fop_duplicate, FlatOperand.Immediate(FlatValue.Int32(1)))); instructions.Add(FlatStatement.REREFERENCE(FlatOperand.InputRef(numParam, fop_duplicate.ImmediateValue), fop_duplicate)); return into_lvalue.AsRValue(FlatValue.FromType(result_type.ConvertedType)); } /* FlatOperand fop_duplicate = AllocateRegister("local_" + op.ToString()); FlatOperand new_lvalue = fop_duplicate.GetLValue(this, instructions); instructions.Add(FlatStatement.DEREFERENCE(new_lvalue, op)); instructions.Add(FlatStatement.DUPLICATE(into_lvalue, fop_duplicate)); switch (pues.CSharpKind()) { case SyntaxKind.PostIncrementExpression: instructions.Add(FlatStatement.ADD(new_lvalue, fop_duplicate, FlatOperand.Immediate(FlatValue.Int32(1)))); instructions.Add(FlatStatement.REREFERENCE(op, fop_duplicate)); return into_lvalue.AsRValue(FlatValue.FromType(result_type.ConvertedType)); case SyntaxKind.PostDecrementExpression: instructions.Add(FlatStatement.SUB(new_lvalue, fop_duplicate, FlatOperand.Immediate(FlatValue.Int32(1)))); instructions.Add(FlatStatement.REREFERENCE(op, fop_duplicate)); return into_lvalue.AsRValue(FlatValue.FromType(result_type.ConvertedType)); } * */ } // reference /* if (node.CSharpKind() == SyntaxKind.SimpleAssignmentExpression) { FlatOperand fop_right = ResolveExpression(node.Right, into_lvalue, instructions); instructions.Add(FlatStatement.REREFERENCE(fop_subject, fop_right)); return fop_right; } else { FlatOperand fop_right = ResolveExpression(node.Right, into_lvalue, instructions); FlatOperand fop_duplicate = AllocateRegister("local_" + fop_subject.ToString()); FlatOperand lvalue_final = fop_duplicate.GetLValue(this, instructions); instructions.Add(FlatStatement.DEREFERENCE(lvalue_final, fop_subject)); ResolveBinaryExpression(node.CSharpKind(), fop_duplicate, fop_right, lvalue_final, instructions); instructions.Add(FlatStatement.REREFERENCE(fop_subject, fop_duplicate)); return fop_subject; } */ } break; case SymbolKind.Event: { IEventSymbol fs = (IEventSymbol)si.Symbol; fop_subject = ResolveParentExpression(si, pues.Operand, null, null, instructions); //FlatOperand fop_type = TypeOf(fop_subject, null, null, instructions); FlatOperand fop_type = Resolve(si.Symbol.ContainingType, null, instructions); FlatOperand fop_Field; ITypeSymbol typeSymbol; { typeSymbol = fs.Type; fop_Field = Resolve(fs, fop_type, null, instructions); } FlatOperand fop_currentvalue = this.AllocateRegister(""); FlatOperand fop_currentlvalue = fop_currentvalue.GetLValue(this, instructions); if (fs.IsStatic) instructions.Add(FlatStatement.GETSTATICFIELD(fop_currentlvalue, fop_Field)); else instructions.Add(FlatStatement.GETFIELD(fop_currentlvalue, fop_Field, fop_subject)); instructions.Add(FlatStatement.DUPLICATE(into_lvalue, fop_currentvalue)); switch (pues.CSharpKind()) { case SyntaxKind.PostIncrementExpression: instructions.Add(FlatStatement.ADD(fop_currentlvalue, fop_currentvalue, FlatOperand.Immediate(FlatValue.Int32(1)))); break; case SyntaxKind.PostDecrementExpression: instructions.Add(FlatStatement.SUB(fop_currentlvalue, fop_currentvalue, FlatOperand.Immediate(FlatValue.Int32(1)))); break; } if (fs.IsStatic) instructions.Add(FlatStatement.SETSTATICFIELD(fop_Field, fop_currentvalue)); else instructions.Add(FlatStatement.SETFIELD(fop_Field, fop_subject, fop_currentvalue)); return into_lvalue.AsRValue(FlatValue.FromType(result_type.ConvertedType)); } break; case SymbolKind.Field: { IFieldSymbol fs = (IFieldSymbol)si.Symbol; fop_subject = ResolveParentExpression(si, pues.Operand, null, null, instructions); //FlatOperand fop_type = TypeOf(fop_subject, null, null, instructions); FlatOperand fop_type = Resolve(si.Symbol.ContainingType, null, instructions); FlatOperand fop_Field; ITypeSymbol typeSymbol; { typeSymbol = fs.Type; fop_Field = Resolve(fs, fop_type, null, instructions); } FlatOperand fop_currentvalue = this.AllocateRegister(""); FlatOperand fop_currentlvalue = fop_currentvalue.GetLValue(this, instructions); if (fs.IsStatic) instructions.Add(FlatStatement.GETSTATICFIELD(fop_currentlvalue, fop_Field)); else instructions.Add(FlatStatement.GETFIELD(fop_currentlvalue, fop_Field, fop_subject)); instructions.Add(FlatStatement.DUPLICATE(into_lvalue, fop_currentvalue)); switch (pues.CSharpKind()) { case SyntaxKind.PostIncrementExpression: instructions.Add(FlatStatement.ADD(fop_currentlvalue, fop_currentvalue, FlatOperand.Immediate(FlatValue.Int32(1)))); break; case SyntaxKind.PostDecrementExpression: instructions.Add(FlatStatement.SUB(fop_currentlvalue, fop_currentvalue, FlatOperand.Immediate(FlatValue.Int32(1)))); break; } if (fs.IsStatic) instructions.Add(FlatStatement.SETSTATICFIELD(fop_Field, fop_currentvalue)); else instructions.Add(FlatStatement.SETFIELD(fop_Field, fop_subject, fop_currentvalue)); return into_lvalue.AsRValue(FlatValue.FromType(result_type.ConvertedType)); } break; case SymbolKind.Property: { IPropertySymbol ps = (IPropertySymbol)si.Symbol; fop_subject = ResolveParentExpression(si, pues.Operand, null, null, instructions); FlatOperand fop_type; if (ps.IsStatic) fop_type = fop_subject; else fop_type = TypeOf(fop_subject, null, null, instructions); FlatOperand fop_property; ITypeSymbol typeSymbol; { // if (ps.IsStatic) // { // throw new NotImplementedException("static property postfix unary assignment"); // } typeSymbol = ps.Type; fop_property = Resolve(ps, fop_type, null, instructions); } FlatOperand fop_currentvalue = this.AllocateRegister(""); FlatOperand fop_currentlvalue = fop_currentvalue.GetLValue(this, instructions); if (ps.IsStatic) instructions.Add(FlatStatement.GETSTATICPROPERTY(fop_currentlvalue, fop_property)); else instructions.Add(FlatStatement.GETPROPERTY(fop_currentlvalue, fop_property, fop_subject)); instructions.Add(FlatStatement.DUPLICATE(into_lvalue, fop_currentvalue)); switch (pues.CSharpKind()) { case SyntaxKind.PostIncrementExpression: instructions.Add(FlatStatement.ADD(fop_currentlvalue, fop_currentvalue, FlatOperand.Immediate(FlatValue.Int32(1)))); break; case SyntaxKind.PostDecrementExpression: instructions.Add(FlatStatement.SUB(fop_currentlvalue, fop_currentvalue, FlatOperand.Immediate(FlatValue.Int32(1)))); break; } if (ps.IsStatic) instructions.Add(FlatStatement.SETSTATICPROPERTY(fop_property, fop_currentvalue)); else instructions.Add(FlatStatement.SETPROPERTY(fop_property, fop_subject, fop_currentvalue)); return into_lvalue.AsRValue(FlatValue.FromType(result_type.ConvertedType)); } break; case SymbolKind.Local: { FlatOperand op = ResolveExpression(pues.Operand, null, instructions); instructions.Add(FlatStatement.DUPLICATE(into_lvalue, op)); switch (pues.CSharpKind()) { case SyntaxKind.PostIncrementExpression: instructions.Add(FlatStatement.ADD(op.GetLValue(this, instructions), op, FlatOperand.Immediate(FlatValue.Int32(1)))); return into_lvalue.AsRValue(FlatValue.FromType(result_type.ConvertedType)); case SyntaxKind.PostDecrementExpression: instructions.Add(FlatStatement.SUB(op.GetLValue(this, instructions), op, FlatOperand.Immediate(FlatValue.Int32(1)))); return into_lvalue.AsRValue(FlatValue.FromType(result_type.ConvertedType)); } } break; } throw new NotImplementedException("postfix unary " + pues.CSharpKind().ToString() + " - " + si.Symbol.Kind.ToString()); }