private void GenerateSpecialNameCall(Table table, HardwireCodeGenerationContext generator, bool isVoid, bool isCtor, bool isStatic, bool isExtension, CodeExpression[] arguments, CodeExpression paramThis, string declaringType, string specialName, CodeStatementCollection coll) { ReflectionSpecialName special = new ReflectionSpecialName(specialName); CodeExpression exp = null; CodeStatement stat = null; switch (special.Type) { case ReflectionSpecialNameType.IndexGetter: if (isStatic) EmitInvalid(generator, coll, "Static indexers are not supported by hardwired descriptors."); else exp = new CodeIndexerExpression(paramThis, arguments); break; case ReflectionSpecialNameType.IndexSetter: if (isStatic) EmitInvalid(generator, coll, "Static indexers are not supported by hardwired descriptors."); else { coll.Add(new CodeVariableDeclarationStatement(declaringType, "tmp", paramThis)); stat = new CodeAssignStatement(new CodeIndexerExpression(new CodeVariableReferenceExpression("tmp"), arguments.Take(arguments.Length - 1).ToArray()), arguments.Last()); } break; case ReflectionSpecialNameType.ImplicitCast: case ReflectionSpecialNameType.ExplicitCast: exp = paramThis; break; case ReflectionSpecialNameType.OperatorTrue: GenerateBooleanOperator(paramThis, coll, true); break; case ReflectionSpecialNameType.OperatorFalse: generator.Minor("'false' operator is implemented in terms of 'true' operator."); GenerateBooleanOperator(paramThis, coll, false); break; case ReflectionSpecialNameType.PropertyGetter: exp = new CodePropertyReferenceExpression(paramThis, special.Argument); break; case ReflectionSpecialNameType.PropertySetter: { if (isStatic) { var memberExp = new CodePropertyReferenceExpression(new CodeTypeReferenceExpression(declaringType), special.Argument); coll.Add(new CodeAssignStatement(memberExp, arguments[0])); } else { coll.Add(new CodeVariableDeclarationStatement(declaringType, "tmp", paramThis)); var memberExp = new CodePropertyReferenceExpression(new CodeVariableReferenceExpression("tmp"), special.Argument); coll.Add(new CodeAssignStatement(memberExp, arguments[0])); } coll.Add(new CodeMethodReturnStatement(new CodePrimitiveExpression(null))); } break; case ReflectionSpecialNameType.OperatorAdd: exp = BinaryOperator(CodeBinaryOperatorType.Add, paramThis, arguments); break; case ReflectionSpecialNameType.OperatorAnd: exp = BinaryOperator(CodeBinaryOperatorType.BitwiseAnd, paramThis, arguments); break; case ReflectionSpecialNameType.OperatorOr: exp = BinaryOperator(CodeBinaryOperatorType.BitwiseOr, paramThis, arguments); break; case ReflectionSpecialNameType.OperatorDec: exp = generator.TargetLanguage.UnaryDecrement(arguments[0]); if (exp == null) EmitInvalid(generator, coll, string.Format("Language {0} does not support decrement operators.", generator.TargetLanguage.Name)); break; case ReflectionSpecialNameType.OperatorDiv: exp = BinaryOperator(CodeBinaryOperatorType.Divide, paramThis, arguments); break; case ReflectionSpecialNameType.OperatorEq: exp = BinaryOperator(CodeBinaryOperatorType.ValueEquality, paramThis, arguments); break; case ReflectionSpecialNameType.OperatorXor: exp = generator.TargetLanguage.BinaryXor(arguments[0], arguments[1]); if (exp == null) EmitInvalid(generator, coll, string.Format("Language {0} does not support XOR operators.", generator.TargetLanguage.Name)); break; case ReflectionSpecialNameType.OperatorGt: exp = BinaryOperator(CodeBinaryOperatorType.GreaterThan, paramThis, arguments); break; case ReflectionSpecialNameType.OperatorGte: exp = BinaryOperator(CodeBinaryOperatorType.GreaterThanOrEqual, paramThis, arguments); break; case ReflectionSpecialNameType.OperatorInc: exp = generator.TargetLanguage.UnaryIncrement(arguments[0]); if (exp == null) EmitInvalid(generator, coll, string.Format("Language {0} does not support increment operators.", generator.TargetLanguage.Name)); break; case ReflectionSpecialNameType.OperatorNeq: exp = BinaryOperator(CodeBinaryOperatorType.IdentityInequality, paramThis, arguments); break; case ReflectionSpecialNameType.OperatorLt: exp = BinaryOperator(CodeBinaryOperatorType.LessThan, paramThis, arguments); break; case ReflectionSpecialNameType.OperatorLte: exp = BinaryOperator(CodeBinaryOperatorType.LessThanOrEqual, paramThis, arguments); break; case ReflectionSpecialNameType.OperatorNot: exp = generator.TargetLanguage.UnaryLogicalNot(arguments[0]); if (exp == null) EmitInvalid(generator, coll, string.Format("Language {0} does not support logical NOT operators.", generator.TargetLanguage.Name)); break; case ReflectionSpecialNameType.OperatorMod: exp = BinaryOperator(CodeBinaryOperatorType.Modulus, paramThis, arguments); break; case ReflectionSpecialNameType.OperatorMul: exp = BinaryOperator(CodeBinaryOperatorType.Multiply, paramThis, arguments); break; case ReflectionSpecialNameType.OperatorCompl: exp = generator.TargetLanguage.UnaryOneComplement(arguments[0]); if (exp == null) EmitInvalid(generator, coll, string.Format("Language {0} does not support bitwise NOT operators.", generator.TargetLanguage.Name)); break; case ReflectionSpecialNameType.OperatorSub: exp = BinaryOperator(CodeBinaryOperatorType.Subtract, paramThis, arguments); break; case ReflectionSpecialNameType.OperatorNeg: exp = generator.TargetLanguage.UnaryNegation(arguments[0]); if (exp == null) EmitInvalid(generator, coll, string.Format("Language {0} does not support negation operators.", generator.TargetLanguage.Name)); break; case ReflectionSpecialNameType.OperatorUnaryPlus: exp = generator.TargetLanguage.UnaryPlus(arguments[0]); if (exp == null) EmitInvalid(generator, coll, string.Format("Language {0} does not support unary + operators.", generator.TargetLanguage.Name)); break; case ReflectionSpecialNameType.AddEvent: case ReflectionSpecialNameType.RemoveEvent: coll.Add(new CodeThrowExceptionStatement(new CodeObjectCreateExpression(typeof(InvalidOperationException), new CodePrimitiveExpression("Access to event special methods is not supported by hardwired decriptors.")))); break; default: break; } if (stat != null) { coll.Add(stat); exp = exp ?? new CodePrimitiveExpression(null); } if (exp != null) coll.Add(new CodeMethodReturnStatement(exp)); }