static void setBoxing(CompilerContext context, TypeInfo targetType, ExpressionNode expression) {
     var info = expression.getUserData(typeof(ExpressionInfo));
     if (info == null || targetType == null) {
         return;
     }
     var type = getType(context, expression);
     if (type == targetType) {
         return;
     }
     if (isAssignable(context, targetType, expression)) {
         if (targetType.IsPrimitive) {
             if (!type.IsPrimitive) {
                 info.BoxingKind = BoxingKind.Unbox;
                 var unboxinMethod = context.TypeSystem.getUnboxingMethod(type);
                 info.BoxingMethod = unboxinMethod;
                 info.OriginalType = info.Type;
                 info.Type = unboxinMethod.ReturnType;
             }
         } else if (type.IsPrimitive) {
             info.BoxingKind = BoxingKind.Box;
             var boxingMethod = context.TypeSystem.getBoxingMethod((targetType.IsObject) ? type : targetType);
             info.BoxingMethod = boxingMethod;
             info.OriginalType = info.Type;
             info.Type = boxingMethod.ReturnType;
         } else if (targetType.IsNumeric && type.IsNumeric) {
             info.BoxingKind = BoxingKind.Unbox;
             info.BoxingMethod = context.TypeSystem.getUnboxingMethod(type);
         }
     }
 }
 static TypeInfo getVariableType(CompilerContext context, TypeInfo type) {
     switch (type.TypeKind) {
     case LowerBoundedWildcard:
     case UnboundedWildcard:
         return context.TypeSystem.ObjectType;
     default:
         return type;
     }
 }
 DocumentationBuilder(CompilerContext context, Element members) {
     this.context = context;
     this.members = members;
     this.document = members.getOwnerDocument();
 }
        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));
        }
		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 bool isAssignable(CompilerContext context, TypeInfo type, ExpressionNode expression) {
     var info = expression.getUserData(typeof(ExpressionInfo));
     if (info == null) {
         return !type.IsPrimitive;
     }
     var right = getType(context, expression);
     if (type.isAssignableFrom(right)) {
         return true;
     }
     if (expression.ExpressionKind == ExpressionKind.ArrayInitializer) {
         if (!type.IsArray) {
             return false;
         }
         foreach (var e in ((ArrayInitializerExpressionNode)expression).Values) {
             if (!isAssignable(context, type.ElementType, e)) {
                 return false;
             }
         }
         return true;
     }
     if (type.IsNumeric && info.IsConstant) {
         switch (type.NumericTypeKind) {
         case Byte: {
             long value;
             switch (right.TypeKind) {
             case Char:
                 value = ((Character)info.Value).charValue();
                 break;
             case Int:
             case Long:
             case Short:
                 value = ((Number)info.Value).longValue();
                 break;
             default:
                 return false;
             }
             return Byte.MIN_VALUE <= value && value <= Byte.MAX_VALUE;
         }
         case Char: {
             long value;
             switch (right.TypeKind) {
             case Byte:
             case Int:
             case Long:
             case Short:
                 value = ((Number)info.Value).longValue();
                 break;
             default:
                 return false;
             }
             return Character.MIN_VALUE <= value && value <= Character.MAX_VALUE;
         }
         case Short: {
             long value;
             switch (right.TypeKind) {
             case Byte:
                 return true;
             case Char:
                 value = ((Character)info.Value).charValue();
                 break;
             case Int:
             case Long:
                 value = ((Number)info.Value).longValue();
                 break;
             default:
                 return false;
             }
             return Short.MIN_VALUE <= value && value <= Short.MAX_VALUE;
         }
         case Int: {
             long value;
             switch (right.getTypeKind()) {
             case Char:
                 value = ((Character)info.Value).charValue();
                 break;
             case Byte:
             case Short:
                 return true;
             case Long:
                 value = ((Number)info.getValue()).longValue();
                 break;
             default:
                 return false;
             }
             return Integer.MIN_VALUE <= value && value <= Integer.MAX_VALUE;
         }
         }
     }
     return false;
 }
        static bool isAssignable(CompilerContext context, TypeInfo type, ExpressionNode expression)
        {
            var info = expression.getUserData(typeof(ExpressionInfo));

            if (info == null)
            {
                return(!type.IsPrimitive);
            }
            var right = getType(context, expression);

            if (type.isAssignableFrom(right))
            {
                return(true);
            }
            if (expression.ExpressionKind == ExpressionKind.ArrayInitializer)
            {
                if (!type.IsArray)
                {
                    return(false);
                }
                foreach (var e in ((ArrayInitializerExpressionNode)expression).Values)
                {
                    if (!isAssignable(context, type.ElementType, e))
                    {
                        return(false);
                    }
                }
                return(true);
            }
            if (type.IsNumeric && info.IsConstant)
            {
                switch (type.NumericTypeKind)
                {
                case Byte: {
                    long value;
                    switch (right.TypeKind)
                    {
                    case Char:
                        value = ((Character)info.Value).charValue();
                        break;

                    case Int:
                    case Long:
                    case Short:
                        value = ((Number)info.Value).longValue();
                        break;

                    default:
                        return(false);
                    }
                    return(Byte.MIN_VALUE <= value && value <= Byte.MAX_VALUE);
                }

                case Char: {
                    long value;
                    switch (right.TypeKind)
                    {
                    case Byte:
                    case Int:
                    case Long:
                    case Short:
                        value = ((Number)info.Value).longValue();
                        break;

                    default:
                        return(false);
                    }
                    return(Character.MIN_VALUE <= value && value <= Character.MAX_VALUE);
                }

                case Short: {
                    long value;
                    switch (right.TypeKind)
                    {
                    case Byte:
                        return(true);

                    case Char:
                        value = ((Character)info.Value).charValue();
                        break;

                    case Int:
                    case Long:
                        value = ((Number)info.Value).longValue();
                        break;

                    default:
                        return(false);
                    }
                    return(Short.MIN_VALUE <= value && value <= Short.MAX_VALUE);
                }

                case Int: {
                    long value;
                    switch (right.getTypeKind())
                    {
                    case Char:
                        value = ((Character)info.Value).charValue();
                        break;

                    case Byte:
                    case Short:
                        return(true);

                    case Long:
                        value = ((Number)info.getValue()).longValue();
                        break;

                    default:
                        return(false);
                    }
                    return(Integer.MIN_VALUE <= value && value <= Integer.MAX_VALUE);
                }
                }
            }
            return(false);
        }
        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));
        }
     : super(true)
 {
     this.context = context;
 }
 StatementValidator(CompilerContext context)
     : super(true)
 MethodResolver(ExpressionValidator expressionValidator, CompilerContext context) {
     this.expressionValidator = expressionValidator;
     this.context = context;
 }