private static bool isInDeprecatedContext(CompilerContext context)
 {
     if (!BytecodeHelper.isDeprecated(context.AnnotatedTypeSystem, context.CurrentType))
     {
         if (!context.CodeValidationContext.IsInMethod || !BytecodeHelper.isDeprecated(context.AnnotatedTypeSystem,
                                                                                       context.CodeValidationContext.RootMethod))
         {
             return(false);
         }
     }
     return(true);
 }
        static TypeInfo getType(CompilerContext context, ExpressionNode expression)
        {
            if (ValidationHelper.isMethod(expression))
            {
                throw context.error(CompileErrorId.UnexpectedMethodReference, expression);
            }
            var info = expression.getUserData(typeof(ExpressionInfo));

            if (info.Type != null)
            {
                return(info.Type);
            }
            else if (info.IsConstant)
            {
                context.ConstantBuilder.buildConstant(expression);
                return(info.Type);
            }
            else if (info.Members != null)
            {
                foreach (var member in info.Members)
                {
                    switch (member.MemberKind)
                    {
                    case Field:
                        var field = member.Field;
                        if (field.Value != null)
                        {
                            info.IsConstant = true;
                            info.Value      = field.Value;
                        }
                        info.Member = member;
                        info.Type   = member.Type;
                        if (!isInDeprecatedContext(context))
                        {
                            if (BytecodeHelper.isDeprecated(context.AnnotatedTypeSystem, field))
                            {
                                context.addWarning(CompileErrorId.DeprecatedField, expression,
                                                   BytecodeHelper.getDisplayName(field.DeclaringType), field.Name);
                            }
                        }
                        if (context.CodeValidationContext.IsInMethod && context.CodeValidationContext.IsInLambda)
                        {
                            if (!member.IsStatic && expression.ExpressionKind == ExpressionKind.SimpleName)
                            {
                                var typeBuilder = context.LambdaScopes[context.CodeValidationContext.RootMethod];
                                if (typeBuilder.getField("this$0") == null)
                                {
                                    typeBuilder.defineField("this$0", context.CurrentType);
                                }
                            }
                        }
                        return(member.Type);

                    case Type:
                        info.Member = member;
                        info.Type   = member.Type;
                        if (!isInDeprecatedContext(context))
                        {
                            if (BytecodeHelper.isDeprecated(context.AnnotatedTypeSystem, info.Type))
                            {
                                context.addWarning(CompileErrorId.DeprecatedType, expression,
                                                   BytecodeHelper.getDisplayName(info.Type));
                            }
                        }
                        return(member.Type);

                    case Indexer:
                    case Property:
                        info.Member = member;
                        info.Type   = member.Type;
                        if (!isInDeprecatedContext(context))
                        {
                            if (member.GetAccessor != null)
                            {
                                if (member.SetAccessor == null)
                                {
                                    if (BytecodeHelper.isDeprecated(context.AnnotatedTypeSystem, member.GetAccessor))
                                    {
                                        context.addWarning(CompileErrorId.DeprecatedProperty, expression,
                                                           BytecodeHelper.getDisplayName(member.DeclaringType), member.Name);
                                    }
                                }
                                else
                                {
                                    if (BytecodeHelper.isDeprecated(context.AnnotatedTypeSystem, member.GetAccessor) &&
                                        BytecodeHelper.isDeprecated(context.AnnotatedTypeSystem, member.SetAccessor))
                                    {
                                        context.addWarning(CompileErrorId.DeprecatedProperty, expression,
                                                           BytecodeHelper.getDisplayName(member.DeclaringType), member.Name);
                                    }
                                }
                            }
                            else if (member.SetAccessor != null)
                            {
                                if (BytecodeHelper.isDeprecated(context.AnnotatedTypeSystem, member.SetAccessor))
                                {
                                    context.addWarning(CompileErrorId.DeprecatedProperty, expression,
                                                       BytecodeHelper.getDisplayName(member.DeclaringType), member.Name);
                                }
                            }
                        }
                        if (context.CodeValidationContext.IsInMethod && context.CodeValidationContext.IsInLambda)
                        {
                            if (!member.IsStatic && expression.ExpressionKind == ExpressionKind.SimpleName)
                            {
                                var typeBuilder = context.LambdaScopes[context.CodeValidationContext.RootMethod];
                                if (typeBuilder.getField("this$0") == null)
                                {
                                    typeBuilder.defineField("this$0", context.CurrentType);
                                }
                            }
                        }
                        return(member.Type);

                    case Local:
                        if (context.CodeValidationContext.IsInMethod)
                        {
                            var currentMethod = context.CodeValidationContext.CurrentMethod;
                            var currentType   = (TypeBuilder)currentMethod.DeclaringType;
                            if (currentType.FullName.indexOf('#') == -1 && context.CodeValidationContext.IsInLambda)
                            {
                                if (currentMethod != member.Method)
                                {
                                    member.IsUsedFromLambda = true;
                                    var typeBuilder = context.LambdaScopes[context.CodeValidationContext.RootMethod];
                                    context.getLocalField(typeBuilder, (LocalMemberInfo)member);
                                }
                            }
                        }
                        info.Member = member;
                        info.Type   = member.Type;
                        return(member.Type);

                    default:
                        break;
                    }
                }
                if (info.ExtensionMethods != null && info.ExtensionMethods.any())
                {
                    return(info.Type = info.ExtensionMethods.first().Parameters.first().Type);
                }
            }
            throw new Exception("Internal error line " + (expression.getLine() + 1));
        }