[Runtime] Fixed typo

[Runtime] Fixed typo

//
// Copyright (c) XSharp B.V.  All Rights Reserved.
// Licensed under the Apache License, Version 2.0.
// See License.txt in the project root for license information.
//

USING System
USING System.Collections.Generic
USING System.Text
USING System.Reflection
USING System.Diagnostics
BEGIN NAMESPACE XSharp
  /// XSharp Runtime base Error class
  CLASS Error INHERIT Exception
    /// A string representing the name of the subsystem generating the error.
    VIRTUAL PROPERTY SubSystem AS STRING AUTO  := "BASE"
    /// An integer numeric value representing a Visual Objects generic error code.
    /// <Seealso cref="Gencode"/>
    VIRTUAL PROPERTY Gencode AS DWORD AUTO    := EG_UNKNOWN
    /// An string containing the description of the Gencode.
    VIRTUAL PROPERTY GenCodeText AS STRING GET IIF (Gencode != 0, ErrString(Gencode), "Unknown GenCode")
    /// An integer numeric value representing a subsystem-specific error code.
    VIRTUAL PROPERTY SubCode AS DWORD AUTO    := 0
    /// An string containing the description of the SubCode.
    VIRTUAL PROPERTY SubCodeText AS STRING GET IIF(!String.IsNullOrEmpty(_Subcode), _Subcode, IIF (SubCode != 0, __CavoStr(SubCode), "Unknown SubCode")) SET _Subcode := value
    PRIVATE _Subcode as STRING
    /// A string representing the name of the function or method in which the error occurred.
    VIRTUAL PROPERTY FuncSym AS STRING AUTO   := ""
    /// A string representing the name used to open the file associated with the error condition.
    VIRTUAL PROPERTY FileName AS STRING AUTO  := ""
    /// A constant indicating the severity of the error condition.
    /// <Seealso cref="Severity"/>
    VIRTUAL PROPERTY Severity AS DWORD AUTO   := ES_ERROR
    /// A string that describes the error condition.
    VIRTUAL PROPERTY Description		AS STRING AUTO := ""
    /// A string representing the argument supplied to an operator or function when an argument error occurs.
    VIRTUAL PROPERTY Arg				AS STRING AUTO := ""
    PRIVATE  _ArgType			AS DWORD
    /// A numeric value representing the data type of the argument that raised the error.
    VIRTUAL PROPERTY ArgType			AS DWORD
      GET
        RETURN _ArgType
      END GET
      SET
        _ArgType := value
        _ArgTypeType := UsualTypeToType(value)
      END SET
    END PROPERTY
    PRIVATE  _ArgTypeType 		:= NULL AS System.Type
    /// The system type representing the data type of the argument that raised the error.
    VIRTUAL PROPERTY ArgTypeType		AS System.Type
      GET
        RETURN _ArgTypeType
      END GET
      SET
        _ArgTypeType := value
        _ArgType 	 := TypeToUsualType(value)
      END SET
    END PROPERTY

    PRIVATE _ArgTypeReq		AS DWORD
    /// A numeric value representing the expected type of the argument that raised the error.
    VIRTUAL PROPERTY ArgTypeReq			AS DWORD
      GET
        RETURN _ArgTypeReq
      END GET
      SET
        _ArgTypeReq := value
        _ArgTypeReqType := UsualTypeToType(value)
      END SET
    END PROPERTY
    PRIVATE  _ArgTypeReqType := NULL	AS System.Type
    /// The system type representing the expected type of the argument that raised the error.
    VIRTUAL PROPERTY ArgTypeReqType		AS System.Type
      GET
        RETURN _ArgTypeReqType
      END GET
      SET
        _ArgTypeReqType := value
        _ArgTypeReq 	 := TypeToUsualType(value)
      END SET
    END PROPERTY
    /// A numeric value representing the type of the new result that the error handler substitutes for the operation that produced the error condition.
    VIRTUAL PROPERTY SubstituteType     AS DWORD AUTO
    /// A numeric value representing the number of the argument supplied to an operator or function when an argument error occurs.
    VIRTUAL PROPERTY ArgNum				AS DWORD AUTO
    /// An object representing the SELF of the method in which the error occurred.
    VIRTUAL PROPERTY MethodSelf			AS OBJECT AUTO
    /// A symbol representing the calling function of the function in which the error occurred.
    VIRTUAL PROPERTY CallFuncSym		AS STRING AUTO
    /// An array of the arguments supplied to an operator or function when an argument error occurs.
    VIRTUAL PROPERTY Args				AS OBJECT[] AUTO
    /// An integer numeric value representing the number of times the failed operation has been attempted.
    VIRTUAL PROPERTY Tries				AS INT AUTO := 0
    /// A logical value indicating whether the subsystem can perform default error recovery for the error condition.
    VIRTUAL PROPERTY CanDefault         AS LOGIC AUTO
    /// A logical value indicating whether the subsystem can retry the operation that caused the error condition.
    VIRTUAL PROPERTY CanRetry           AS LOGIC AUTO
    /// A logical value indicating whether a new result can be substituted for the operation that produced the error condition.
    VIRTUAL PROPERTY CanSubstitute      AS LOGIC AUTO
    /// A string that describes the operation being attempted when the error occurred.
    VIRTUAL PROPERTY Operation          AS STRING AUTO := ""
    /// A value of 0 indicates that the error condition was not caused by an error from the operating system.
    VIRTUAL PROPERTY OSCode				AS DWORD AUTO := 0
    /// Descripion of the OSCode
    VIRTUAL PROPERTY OSCodeText			AS STRING GET IIF(OSCode == 0, "", DosErrString(OSCode))
    /// A numeric value representing the file handle supplied to a function when an file error occurs.
    VIRTUAL PROPERTY FileHandle         AS DWORD AUTO
    /// A numeric value representing a boundary condition for an operation (such as string overflow or array bound error).
    VIRTUAL PROPERTY MaxSize			AS DWORD AUTO
    /// A pointer to the function in which the error occurred.
    /// <remarks>Note This property is for compatibility only. It is not being used in the X# runtime.</remarks>
    VIRTUAL PROPERTY FuncPtr            AS IntPtr AUTO := IntPtr.Zero

    /// A value of any data type unused by the Error system.  It is provided as a user-definable slot, allowing arbitrary information to be attached to an Error object and retrieved later
    VIRTUAL PROPERTY Cargo              AS OBJECT AUTO
    /// Call stack from the moment where the error object was created
    VIRTUAL PROPERTY Stack              AS STRING GET SELF:StackTrace SET SELF:StackTrace := Value

	PRIVATE _StackTrace AS STRING
    OVERRIDE PROPERTY StackTrace         AS STRING
    	GET
    		IF String.IsNullOrEmpty(SELF:_StackTrace)
    			RETURN SUPER:StackTrace
    		END IF
    		RETURN SELF:_StackTrace
    	END GET
    	SET
    		SELF:_StackTrace := value
    	END SET
    END PROPERTY

    PRIVATE METHOD setDefaultValues() AS VOID
        SELF:FuncSym := ProcName(2)
        SELF:Args    := <OBJECT>{}
        IF String.IsNullOrEmpty(SELF:StackTrace)
            SELF:_StackTrace  := ErrorStack(2)
        ENDIF
        RETURN

    /// Create an Error Object
    CONSTRUCTOR()
    SELF:setDefaultValues()
    RETURN

    /// Create an Error Object with the specified Description
    CONSTRUCTOR (msg AS STRING)
    SUPER(msg)
    SELF:setDefaultValues()
    SELF:Description := msg
    SELF:Gencode     := EG_EXCEPTION
    RETURN

    /// Create an Error Object with the Innner Exception
    CONSTRUCTOR (ex AS Exception)
    SUPER(ex.Message,ex)
    SELF:setDefaultValues()
    IF ex IS Error
        // Clone Error properties from Inner Exception
        LOCAL e := (Error) ex AS Error
        VAR props := typeof(Error):GetProperties()
        FOREACH oProp AS PropertyInfo IN props
            IF oProp:CanWrite
                oProp:SetValue(SELF, oProp:GetValue(e))
            ENDIF
         NEXT
         IF SELF:SubCode == 0
            SELF:SubCodeText := ""
         ENDIF
    ELSE
        SELF:Description := ex:Message
        SELF:GetGenCodeFromException(ex)
        IF ! String.IsNullOrEmpty(ex:Source)
            SELF:SubSystem := ex:Source
        ENDIF
        VAR sStack       := ErrorStack( StackTrace{ex,TRUE},UInt32.MaxValue)
        IF !sStack:StartsWith("*EmptyCallStack*")
            SELF:_StackTrace := sStack + SELF:_StackTrace
        ENDIF
    ENDIF

    IF String.IsNullOrEmpty(SELF:StackTrace)
        SELF:StackTrace  := ErrorStack(2)
    ENDIF
    PRIVATE METHOD GetGenCodeFromException(ex as Exception) AS VOID
        if ex IS DivideByZeroException
            SELF:Gencode := EG_ZERODIV
        ELSEIF ex IS OverflowException
            SELF:Gencode := EG_NUMOVERFLOW
        ELSEIF ex IS OutOfMemoryException
            SELF:Gencode := EG_MEM
        ELSEIF ex IS RankException
            SELF:Gencode := EG_BOUND
        ELSEIF ex IS IndexOutOfRangeException
            SELF:Gencode := EG_BOUND
        ELSEIF ex IS ArgumentException
            SELF:Gencode := EG_ARG
        ELSEIF ex IS InvalidCastException
            SELF:Gencode := EG_WRONGCLASS
        ELSEIF ex IS NullReferenceException
            SELF:Gencode := EG_NULLVAR
        ELSEIF ex IS StackOverflowException
            SELF:Gencode := EG_STACK
        ELSEIF ex IS AccessViolationException
            SELF:Gencode := EG_CORRUPTION
        ELSE
            SELF:Gencode     := EG_EXCEPTION
        ENDIF

    /// Create an Error Object with the Innner Exception and other parameters
    CONSTRUCTOR (ex AS Exception, cFuncName AS STRING, cArgName AS STRING, iArgNum AS DWORD, aArgs PARAMS OBJECT[])
    SUPER(ex.Message,ex)
    SELF:setDefaultValues()
    SELF:GetGenCodeFromException(ex)
    SELF:FuncSym     := cFuncName
    SELF:Arg         := cArgName
    SELF:ArgNum      := iArgNum
    SELF:Args		 := aArgs

    /// Create an Error Object for a Gencode and Argument Name.
    CONSTRUCTOR (dwGenCode AS DWORD, cArg AS STRING)
    SUPER(ErrString( dwGenCode ))
    SELF:setDefaultValues()
    SELF:Gencode := dwGenCode
    SELF:Arg	 := cArg
    SELF:Description := ErrString( dwGenCode )

    /// Create an Error Object for a Gencode, Argument Name and Description.
    CONSTRUCTOR (dwGenCode AS DWORD, cArg AS STRING, cDescription AS STRING)
    SUPER(cDescription)
    SELF:setDefaultValues()
    SELF:Gencode		:= dwGenCode
    SELF:Arg			:= cArg
    SELF:Description	:= cDescription

    /// Create an Error Object.
    CONSTRUCTOR (dwGenCode AS DWORD, dwSubCode AS DWORD, cFuncName AS STRING, cArgName AS STRING, iArgNum AS DWORD)
    SUPER(ErrString( dwGenCode ))
    SELF:setDefaultValues()
    SELF:Gencode := dwGenCode
    SELF:SubCode := dwSubCode
    SELF:FuncSym     := cFuncName
    SELF:Arg         := cArgName
    SELF:ArgNum      := iArgNum
    SELF:Description := ErrString( dwGenCode )

    /// Create an Error Object.
    CONSTRUCTOR (dwGenCode AS DWORD, dwSubCode := 0 AS DWORD)
    SELF:setDefaultValues()
    SELF:Gencode := dwGenCode
    SELF:SubCode := dwSubCode
    SELF:Description := ErrString( dwGenCode )

    PRIVATE STATIC METHOD LangString(e as VOErrors) AS STRING
        local cString := __CavoStr(e):Trim() as string
        IF cString:EndsWith(":")
            cString := cString:Substring(0, cString:Length-1):Trim()
        endif
        return cString+e" :\t"

    /// <inheritdoc />
    OVERRIDE METHOD ToString() AS STRING
      LOCAL sb AS StringBuilder
      LOCAL nGenCode AS Gencode
      nGenCode := (Gencode) SELF:Gencode
      sb := StringBuilder{}
      sb:AppendLine( LangString(VOErrors.ERROR_DESCRIPTION) + SELF:Description)
      sb:AppendLine( LangString(VOErrors.ERROR_SUBSYSTEM) + SELF:SubSystem )
      sb:AppendLine( LangString(VOErrors.ERROR_GENCODE) + nGenCode:ToString()  +" " +SELF:GenCodeText  )
      IF SELF:SubCode != 0
        sb:AppendLine( LangString(VOErrors.ERROR_SUBCODE) + SELF:SubCode:ToString() +" "+SELF:SubCodeText)
      ENDIF
      IF SELF:OSCode != 0
        sb:AppendLine( LangString(VOErrors.ERROR_OSCODE)  + SELF:OSCode:ToString() +" " +SELF:OSCodeText )
      ENDIF
      IF !String.IsNullOrEmpty(SELF:FuncSym)
        sb:AppendLine(LangString(VOErrors.ERROR_FUNCSYM) + SELF:FuncSym   )
      ENDIF
      LOCAL sev := (Severity) SELF:Severity AS Severity
      sb:AppendLine(LangString(VOErrors.ERROR_SEVERITY)     + sev:ToString() )
      sb:AppendLine(LangString(VOErrors.ERROR_CANDEFAULT)   + SELF:CanDefault:ToString())
      sb:AppendLine(LangString(VOErrors.ERROR_CANRETRY)     +SELF:CanRetry:ToString() )
      sb:AppendLine(LangString(VOErrors.ERROR_CANSUBSTITUTE) +SELF:CanSubstitute:ToString())
      IF ! String.IsNullOrEmpty(SELF:Operation)
        sb:AppendLine(LangString(VOErrors.ERROR_OPERATION) + SELF:Operation)
      ENDIF
      IF ! String.IsNullOrEmpty(SELF:FileName)
        sb:AppendLine(LangString(VOErrors.ERROR_FILENAME) + SELF:FileName )
      ENDIF
      IF SELF:Tries != 0
          sb:AppendLine(LangString(VOErrors.ERROR_TRIES) + SELF:Tries:ToString()    )
     ENDIF
      IF SELF:ArgType != 0
        sb:AppendLine(LangString(VOErrors.ERROR_ARGTYPE) 	+ TypeString(SELF:ArgType    ) )
      ENDIF
      IF SELF:ArgNum != 0
        sb:AppendLine(LangString(VOErrors.ERROR_ARGNUM) 	+ SELF:ArgNum:ToString()    )
      ENDIF
      IF ! String.IsNullOrEmpty(SELF:Arg)
        sb:AppendLine(LangString(VOErrors.ERROR_ARG)	+ SELF:Arg)
      ENDIF
      LOCAL cArgs AS STRING
      IF SELF:Args != NULL .AND. SELF:Args:Length > 0
            cArgs := "{"
            LOCAL lFirst := TRUE AS LOGIC
            FOREACH VAR oArg IN SELF:Args
                IF ! lFirst
                    cArgs += ","
                ENDIF
                IF oArg == NULL
                    cArgs += "(NULL)"
                ELSE
                    cArgs += oArg:ToString()
                ENDIF
                lFirst := FALSE
            NEXT
            cArgs += "}"
            sb:AppendLine(LangString(VOErrors.ERROR_ARGS)+ cArgs)
      ENDIF
      IF SELF:ArgTypeReqType != NULL
        sb:AppendLine(LangString(VOErrors.ERROR_ARGTYPE_REQ) + SELF:ArgTypeReqType:FullName)
      ENDIF
      IF ! String.IsNullOrEmpty(SELF:CallFuncSym)
        sb:AppendLine(LangString(VOErrors.ERROR_CALLEDFROM) + SELF:CallFuncSym  )
      ENDIF
      sb:AppendLine(LangString(VOErrors.ERROR_STACK))
      sb:AppendLine(SELF:StackTrace  )
      RETURN sb:ToString()

    /// Throw the error.
    VIRTUAL METHOD Throw AS VOID STRICT
        THROW SELF

    #region STATIC methods TO construct an error
    /// <exclude/>
    STATIC METHOD ArgumentError(cFuncName AS STRING, name AS STRING, description AS STRING) AS Error
    RETURN ArgumentError(cFuncName, name, description, 0)

    /// <exclude/>
    STATIC METHOD ArgumentError(cFuncName AS STRING, name AS STRING, iArgnum  AS DWORD, aArgs PARAMS OBJECT[]) AS Error
    VAR err			:= Error{XSharp.Gencode.EG_ARG, name, ErrString( EG_ARG )}
    err:FuncSym     := cFuncName
    err:Description := err:Message
    err:ArgNum		:= iArgnum
    err:Args		:= aArgs
    RETURN err

    /// <exclude/>
    STATIC METHOD ArgumentError(cFuncName AS STRING, name AS STRING, description AS STRING, iArgnum AS DWORD) AS Error
    VAR err			:= Error{XSharp.Gencode.EG_ARG, name, description}
    err:FuncSym     := cFuncName
    err:Description := err:Message
    err:ArgNum		:= iArgnum
    RETURN err

    STATIC METHOD ArgumentError(cFuncName AS STRING, name AS STRING, description AS STRING, iArgnum AS DWORD, aArgs AS OBJECT[]) AS Error
        VAR err := ArgumentError(cFuncName, name, description, iArgnum)
        err:Args := aArgs
    RETURN err

    /// <exclude/>
    STATIC METHOD WrapRawException( ex AS Exception ) AS Error
    LOCAL e AS Error
    if ex != null
        e			  := Error{ ex }
        e:Description := ErrString( EG_EXCEPTION ) + ": " + ex:Message
    else
        e			  := Error{  }
        e:Description := ErrString( EG_SEQUENCE )
    endif
    RETURN e

    /// <exclude/>
    STATIC METHOD VOError( dwGenCode AS DWORD, cFuncName AS STRING, cArgName AS STRING, iArgNum AS DWORD, aArgs AS OBJECT[] ) AS Error
        LOCAL e AS Error
        e:= Error{dwGenCode,cArgName}
        e:FuncSym := cFuncName
        e:ArgNum := iArgNum
        e:Args := aArgs
        e:Description := ErrString( dwGenCode )
        RETURN e

    /// <exclude/>
    STATIC METHOD VOError( ex AS Exception, dwGenCode AS DWORD, cFuncName AS STRING, cArgName AS STRING, iArgNum AS DWORD, aArgs AS OBJECT[]  ) AS Error
    LOCAL e AS Error
    e			  := Error{ ex, cFuncName, cArgName, iArgNum, aArgs }
    e:Gencode     := dwGenCode
    e:Description := ErrString( dwGenCode )
    RETURN e

    /// <exclude/>
    STATIC METHOD VoDbError( dwGenCode AS DWORD, dwSubCode AS DWORD, cFuncName AS STRING ) AS Error
    LOCAL e AS Error
    e := Error{dwGenCode, dwSubCode}
    e:SubSystem   := "DBCMD"
    e:FuncSym     := cFuncName
    e:Description := ErrString( dwGenCode )
    RETURN e

    /// <exclude/>
    STATIC METHOD VoDbError( dwGenCode AS DWORD, dwSubCode AS DWORD, cFuncName AS STRING, aArgs PARAMS OBJECT[] ) AS Error
    LOCAL e AS Error
    e := Error{dwGenCode, dwSubCode}
    e:SubSystem   := "DBCMD"
    e:FuncSym     := cFuncName
    e:Description := ErrString( dwGenCode )
    e:Args        := aArgs
    IF aArgs:Length > 0
        e:Arg := aArgs[0]:ToString()
    ENDIF
    RETURN e

    /// <exclude/>
    STATIC METHOD VoDbError( dwGenCode AS DWORD, dwSubCode AS DWORD, aArgs PARAMS OBJECT[] ) AS Error
    LOCAL e AS Error
    e			  := Error{dwGenCode, dwSubCode}
    e:SubSystem   := "DBCMD"
    e:Description := __CavoStr( dwSubCode)
    e:Args        := aArgs
    IF aArgs:Length > 0
        e:Arg := aArgs[0]:ToString()
    ENDIF
    RETURN e

    /// <exclude/>
    STATIC METHOD VoDbError( dwGenCode AS DWORD, dwSubCode AS DWORD, cFuncName AS STRING, cArgName AS STRING, iArgNum AS DWORD, aArgs PARAMS OBJECT[] ) AS Error
    LOCAL e AS Error
    e := Error{dwGenCode, dwSubCode, cFuncName, cArgName, iArgNum}
    e:SubSystem   := "DBCMD"
    IF dwSubCode != 0
        e:Description := __CavoStr( dwSubCode)
    ELSE
        e:Description := ErrString(dwGenCode)
    ENDIF
    e:Args        := aArgs
    RETURN e

    /// <exclude/>
    STATIC METHOD DataTypeError( cFuncName AS STRING, cArgName AS STRING, iArgNum AS DWORD, aArgs PARAMS OBJECT[] ) AS Error
    LOCAL e AS Error
    e			  := Error{ ArgumentException{} , cFuncName, cArgName, iArgNum, aArgs}
    e:Gencode     := EG_DATATYPE
    e:Description := __CavoStr( VOErrors.DATATYPEERROR )
    RETURN e

    /// <exclude/>
    STATIC METHOD ArgumentError( cFuncName AS STRING, cArgName AS STRING, iArgNum AS DWORD, cDescription AS STRING, aArgs PARAMS OBJECT[]) AS Error
    LOCAL e AS Error
    e				:= Error{ ArgumentException{} , cFuncName, cArgName, iArgNum, aArgs}
    e:Gencode     := EG_ARG
    e:Description := cDescription
    RETURN e

    /// <exclude/>
    STATIC METHOD NullArgumentError( cFuncName AS STRING, cArgName AS STRING, iArgNum AS DWORD ) AS Error
    LOCAL e AS Error
    e := Error{ ArgumentNullException{} ,cFuncName, cArgName, iArgNum}
    e:Gencode     := EG_ARG
    e:Description := __CavoStr( VOErrors.ARGISNULL )
    RETURN e

    /// <exclude/>
    STATIC METHOD BoundError( cFuncName AS STRING, cArgName AS STRING, iArgNum AS DWORD, aArgs PARAMS OBJECT[] ) AS Error
    LOCAL e AS Error
    e := Error{ ArgumentException{ErrString( EG_BOUND) } }
    e:Severity    := ES_ERROR
    e:Gencode     := EG_BOUND
    e:SubSystem   := "BASE"
    e:FuncSym     := cFuncName
    e:Arg         := cArgName
    e:ArgNum      := iArgNum
    e:Args        := aArgs
    RETURN e

    #endregion
    /// <exclude />
    STATIC METHOD TypeToUsualType(oType AS System.Type) AS DWORD
    SWITCH Type.GetTypeCode(oType)
    CASE TypeCode.Boolean
      RETURN __UsualType.Logic
    CASE TypeCode.Byte
      RETURN __UsualType.Byte
    CASE TypeCode.Char
      RETURN __UsualType.Char
    CASE TypeCode.DateTime
      RETURN __UsualType.DateTime
    CASE TypeCode.DBNull
      RETURN __UsualType.Object
    CASE TypeCode.Decimal
      RETURN __UsualType.Decimal
    CASE TypeCode.Double
      RETURN __UsualType.Real8
    CASE TypeCode.Empty
      RETURN __UsualType.Void
    CASE TypeCode.Int16
      RETURN __UsualType.ShortInt
    CASE TypeCode.Int32
      RETURN __UsualType.Long
    CASE TypeCode.Int64
      RETURN __UsualType.Int64
    CASE TypeCode.SByte
      RETURN __UsualType.Byte
    CASE TypeCode.Single
      RETURN __UsualType.Real4
    CASE TypeCode.UInt16
      RETURN __UsualType.Word
    CASE TypeCode.UInt32
      RETURN __UsualType.DWord
    CASE TypeCode.UInt64
      RETURN __UsualType.UInt64
    OTHERWISE
        SWITCH oType:FullName:ToLower()
        CASE "xsharp.__array"
          RETURN __UsualType.Array
        CASE "xsharp.__binary"
          RETURN __UsualType.Binary
        CASE "xsharp.__codeblock"
          RETURN __UsualType.Codeblock
        CASE "xsharp.__currency"
          RETURN __UsualType.Currency
        CASE "xsharp.__date"
          RETURN __UsualType.Date
        CASE "xsharp.__float"
          RETURN __UsualType.Float
        CASE "xsharp.__psz"
          RETURN __UsualType.Psz
        CASE "xsharp.__symbol"
          RETURN __UsualType.Symbol
        CASE "xsharp.__usual"
          RETURN __UsualType.Usual
        CASE "system.intptr"
          RETURN __UsualType.Ptr

      END SWITCH
    END SWITCH
    RETURN __UsualType.Void

    /// <exclude />
    STATIC METHOD UsualTypeToType(dwType AS DWORD) AS System.Type
    LOCAL typeName := NULL AS STRING
    SWITCH dwType
    CASE __UsualType.Array
      typeName := "XSharp.__Array"
    CASE __UsualType.Byte
      RETURN typeof(System.Byte)
    CASE __UsualType.Binary
       typeName := "XSharp.__Binary"
    CASE __UsualType.Char
      RETURN typeof(System.Char)
    CASE __UsualType.Codeblock
      typeName := "XSharp.__CodeBlock"
    CASE __UsualType.Currency
      typeName := "XSharp.__Currency"
    CASE __UsualType.Date
      typeName := "XSharp.__Date"
    CASE __UsualType.DWord
      RETURN typeof(System.UInt32)
    CASE __UsualType.Int64
      RETURN typeof(System.Int64)
    CASE __UsualType.Float
      typeName := "XSharp.__Float"
    CASE __UsualType.Logic
      RETURN typeof(System.Boolean)
    CASE __UsualType.Long
      RETURN typeof(System.Int32)
    CASE __UsualType.Object
      RETURN typeof(System.Object)
    CASE __UsualType.Psz
      typeName := "XSharp.__Psz"
    CASE __UsualType.Ptr
      RETURN typeof(System.IntPtr)
    CASE __UsualType.Real4
      RETURN typeof(System.Single)
    CASE __UsualType.Real8
      RETURN typeof(System.Double)
    CASE __UsualType.ShortInt
      RETURN typeof(System.Int16)
    CASE __UsualType.String
      RETURN typeof(System.String)
    CASE __UsualType.Symbol
      typeName := "XSharp.__Symbol"
    CASE __UsualType.UInt64
      RETURN typeof(System.Int64)
    CASE __UsualType.Usual
      typeName := "XSharp.__Usual"
    CASE __UsualType.Void
      RETURN typeof(System.Void)
    CASE __UsualType.Word
      RETURN typeof(System.UInt16)
    END SWITCH
    // lookup types in XSharp.VO
    IF typeName != NULL
        FOREACH asm AS Assembly IN AppDomain.CurrentDomain:GetAssemblies()
          IF asm:GetName():Name:ToLower() == "xsharp.vo"
            VAR type := asm:GetType(typeName, FALSE, TRUE)
            IF type != NULL
              RETURN type
            ENDIF
          ENDIF
        NEXT
    ENDIF
    RETURN NULL

  STATIC METHOD GetInnerException( SELF e as Exception) AS Exception
     IF e:InnerException != NULL
        DO WHILE e:InnerException != NULL
            e := e:InnerException
            IF e IS XSharp.Error
                EXIT
            ENDIF
        ENDDO
     ENDIF
     RETURN e
END CLASS
END NAMESPACE

/// <include file="VoFunctionDocs.xml" path="Runtimefunctions/errorbuild/*" />
FUNCTION ErrorBuild(pErrInfo AS Exception) AS XSharp.Error
	RETURN  XSharp.Error{pErrInfo}

//
// Copyright (c) XSharp B.V.  All Rights Reserved.
// Licensed under the Apache License, Version 2.0.
// See License.txt in the project root for license information.
//

USING System
USING System.Collections.Generic
USING System.Text
USING System.Reflection
USING System.Diagnostics
BEGIN NAMESPACE XSharp
  /// XSharp Runtime base Error class
  CLASS Error INHERIT Exception
    /// A string representing the name of the subsystem generating the error.
    VIRTUAL PROPERTY SubSystem AS STRING AUTO  := "BASE"
    /// An integer numeric value representing a Visual Objects generic error code.
    /// <Seealso cref="Gencode"/>
    VIRTUAL PROPERTY Gencode AS DWORD AUTO    := EG_UNKNOWN
    /// An string containing the description of the Gencode.
    VIRTUAL PROPERTY GenCodeText AS STRING GET IIF (Gencode != 0, ErrString(Gencode), "Unknown GenCode")
    /// An integer numeric value representing a subsystem-specific error code.
    VIRTUAL PROPERTY SubCode AS DWORD AUTO    := 0
    /// An string containing the description of the SubCode.
    VIRTUAL PROPERTY SubCodeText AS STRING GET IIF(!String.IsNullOrEmpty(_Subcode), _Subcode, IIF (SubCode != 0, __CavoStr(SubCode), "Unknown SubCode")) SET _Subcode := value
    PRIVATE _Subcode as STRING
    /// A string representing the name of the function or method in which the error occurred.
    VIRTUAL PROPERTY FuncSym AS STRING AUTO   := ""
    /// A string representing the name used to open the file associated with the error condition.
    VIRTUAL PROPERTY FileName AS STRING AUTO  := ""
    /// A constant indicating the severity of the error condition.
    /// <Seealso cref="Severity"/>
    VIRTUAL PROPERTY Severity AS DWORD AUTO   := ES_ERROR
    /// A string that describes the error condition.
    VIRTUAL PROPERTY Description		AS STRING AUTO := ""
    /// A string representing the argument supplied to an operator or function when an argument error occurs.
    VIRTUAL PROPERTY Arg				AS STRING AUTO := ""
    PRIVATE  _ArgType			AS DWORD
    /// A numeric value representing the data type of the argument that raised the error.
    VIRTUAL PROPERTY ArgType			AS DWORD
      GET
        RETURN _ArgType
      END GET
      SET
        _ArgType := value
        _ArgTypeType := UsualTypeToType(value)
      END SET
    END PROPERTY
    PRIVATE  _ArgTypeType 		:= NULL AS System.Type
    /// The system type representing the data type of the argument that raised the error.
    VIRTUAL PROPERTY ArgTypeType		AS System.Type
      GET
        RETURN _ArgTypeType
      END GET
      SET
        _ArgTypeType := value
        _ArgType 	 := TypeToUsualType(value)
      END SET
    END PROPERTY

    PRIVATE _ArgTypeReq		AS DWORD
    /// A numeric value representing the expected type of the argument that raised the error.
    VIRTUAL PROPERTY ArgTypeReq			AS DWORD
      GET
        RETURN _ArgTypeReq
      END GET
      SET
        _ArgTypeReq := value
        _ArgTypeReqType := UsualTypeToType(value)
      END SET
    END PROPERTY
    PRIVATE  _ArgTypeReqType := NULL	AS System.Type
    /// The system type representing the expected type of the argument that raised the error.
    VIRTUAL PROPERTY ArgTypeReqType		AS System.Type
      GET
        RETURN _ArgTypeReqType
      END GET
      SET
        _ArgTypeReqType := value
        _ArgTypeReq 	 := TypeToUsualType(value)
      END SET
    END PROPERTY
    /// A numeric value representing the type of the new result that the error handler substitutes for the operation that produced the error condition.
    VIRTUAL PROPERTY SubstituteType     AS DWORD AUTO
    /// A numeric value representing the number of the argument supplied to an operator or function when an argument error occurs.
    VIRTUAL PROPERTY ArgNum				AS DWORD AUTO
    /// An object representing the SELF of the method in which the error occurred.
    VIRTUAL PROPERTY MethodSelf			AS OBJECT AUTO
    /// A symbol representing the calling function of the function in which the error occurred.
    VIRTUAL PROPERTY CallFuncSym		AS STRING AUTO
    /// An array of the arguments supplied to an operator or function when an argument error occurs.
    VIRTUAL PROPERTY Args				AS OBJECT[] AUTO
    /// An integer numeric value representing the number of times the failed operation has been attempted.
    VIRTUAL PROPERTY Tries				AS INT AUTO := 0
    /// A logical value indicating whether the subsystem can perform default error recovery for the error condition.
    VIRTUAL PROPERTY CanDefault         AS LOGIC AUTO
    /// A logical value indicating whether the subsystem can retry the operation that caused the error condition.
    VIRTUAL PROPERTY CanRetry           AS LOGIC AUTO
    /// A logical value indicating whether a new result can be substituted for the operation that produced the error condition.
    VIRTUAL PROPERTY CanSubstitute      AS LOGIC AUTO
    /// A string that describes the operation being attempted when the error occurred.
    VIRTUAL PROPERTY Operation          AS STRING AUTO := ""
    /// A value of 0 indicates that the error condition was not caused by an error from the operating system.
    VIRTUAL PROPERTY OSCode				AS DWORD AUTO := 0
    /// Descripion of the OSCode
    VIRTUAL PROPERTY OSCodeText			AS STRING GET IIF(OSCode == 0, "", DosErrString(OSCode))
    /// A numeric value representing the file handle supplied to a function when an file error occurs.
    VIRTUAL PROPERTY FileHandle         AS DWORD AUTO
    /// A numeric value representing a boundary condition for an operation (such as string overflow or array bound error).
    VIRTUAL PROPERTY MaxSize			AS DWORD AUTO
    /// A pointer to the function in which the error occurred.
    /// <remarks>Note This property is for compatibility only. It is not being used in the X# runtime.</remarks>
    VIRTUAL PROPERTY FuncPtr            AS IntPtr AUTO := IntPtr.Zero

    /// A value of any data type unused by the Error system.  It is provided as a user-definable slot, allowing arbitrary information to be attached to an Error object and retrieved later
    VIRTUAL PROPERTY Cargo              AS OBJECT AUTO
    /// Call stack from the moment where the error object was created
    VIRTUAL PROPERTY Stack              AS STRING GET SELF:StackTrace SET SELF:StackTrace := Value

	PRIVATE _StackTrace AS STRING
    OVERRIDE PROPERTY StackTrace         AS STRING
    	GET
    		IF String.IsNullOrEmpty(SELF:_StackTrace)
    			RETURN SUPER:StackTrace
    		END IF
    		RETURN SELF:_StackTrace
    	END GET
    	SET
    		SELF:_StackTrace := value
    	END SET
    END PROPERTY

    PRIVATE METHOD setDefaultValues() AS VOID
        SELF:FuncSym := ProcName(2)
        SELF:Args    := <OBJECT>{}
        IF String.IsNullOrEmpty(SELF:StackTrace)
            SELF:_StackTrace  := ErrorStack(2)
        ENDIF
        RETURN

    /// Create an Error Object
    CONSTRUCTOR()
    SELF:setDefaultValues()
    RETURN

    /// Create an Error Object with the specified Description
    CONSTRUCTOR (msg AS STRING)
    SUPER(msg)
    SELF:setDefaultValues()
    SELF:Description := msg
    SELF:Gencode     := EG_EXCEPTION
    RETURN

    /// Create an Error Object with the Innner Exception
    CONSTRUCTOR (ex AS Exception)
    SUPER(ex.Message,ex)
    SELF:setDefaultValues()
    IF ex IS Error
        // Clone Error properties from Inner Exception
        LOCAL e := (Error) ex AS Error
        VAR props := typeof(Error):GetProperties()
        FOREACH oProp AS PropertyInfo IN props
            IF oProp:CanWrite
                oProp:SetValue(SELF, oProp:GetValue(e))
            ENDIF
         NEXT
         IF SELF:SubCode == 0
            SELF:SubCodeText := ""
         ENDIF
    ELSE
        SELF:Description := ex:Message
        SELF:GetGenCodeFromException(ex)
        IF ! String.IsNullOrEmpty(ex:Source)
            SELF:SubSystem := ex:Source
        ENDIF
        VAR sStack       := ErrorStack( StackTrace{ex,TRUE},UInt32.MaxValue)
        IF !sStack:StartsWith("*EmptyCallStack*")
            SELF:_StackTrace := sStack + SELF:_StackTrace
        ENDIF
    ENDIF

    IF String.IsNullOrEmpty(SELF:StackTrace)
        SELF:StackTrace  := ErrorStack(2)
    ENDIF
    PRIVATE METHOD GetGenCodeFromException(ex as Exception) AS VOID
        if ex IS DivideByZeroException
            SELF:Gencode := EG_ZERODIV
        ELSEIF ex IS OverflowException
            SELF:Gencode := EG_NUMOVERFLOW
        ELSEIF ex IS OutOfMemoryException
            SELF:Gencode := EG_MEM
        ELSEIF ex IS RankException
            SELF:Gencode := EG_BOUND
        ELSEIF ex IS IndexOutOfRangeExeption
            SELF:Gencode := EG_BOUND
        ELSEIF ex IS ArgumentException
            SELF:Gencode := EG_ARG
        ELSEIF ex IS InvalidCastException
            SELF:Gencode := EG_WRONGCLASS
        ELSEIF ex IS NullReferenceException
            SELF:Gencode := EG_NULLVAR
        ELSEIF ex IS StackOverflowException
            SELF:Gencode := EG_STACK
        ELSEIF ex IS AccessViolationException
            SELF:Gencode := EG_CORRUPTION
        ELSE
            SELF:Gencode     := EG_EXCEPTION
        ENDIF

    /// Create an Error Object with the Innner Exception and other parameters
    CONSTRUCTOR (ex AS Exception, cFuncName AS STRING, cArgName AS STRING, iArgNum AS DWORD, aArgs PARAMS OBJECT[])
    SUPER(ex.Message,ex)
    SELF:setDefaultValues()
    SELF:GetGenCodeFromException(ex)
    SELF:FuncSym     := cFuncName
    SELF:Arg         := cArgName
    SELF:ArgNum      := iArgNum
    SELF:Args		 := aArgs

    /// Create an Error Object for a Gencode and Argument Name.
    CONSTRUCTOR (dwGenCode AS DWORD, cArg AS STRING)
    SUPER(ErrString( dwGenCode ))
    SELF:setDefaultValues()
    SELF:Gencode := dwGenCode
    SELF:Arg	 := cArg
    SELF:Description := ErrString( dwGenCode )

    /// Create an Error Object for a Gencode, Argument Name and Description.
    CONSTRUCTOR (dwGenCode AS DWORD, cArg AS STRING, cDescription AS STRING)
    SUPER(cDescription)
    SELF:setDefaultValues()
    SELF:Gencode		:= dwGenCode
    SELF:Arg			:= cArg
    SELF:Description	:= cDescription

    /// Create an Error Object.
    CONSTRUCTOR (dwGenCode AS DWORD, dwSubCode AS DWORD, cFuncName AS STRING, cArgName AS STRING, iArgNum AS DWORD)
    SUPER(ErrString( dwGenCode ))
    SELF:setDefaultValues()
    SELF:Gencode := dwGenCode
    SELF:SubCode := dwSubCode
    SELF:FuncSym     := cFuncName
    SELF:Arg         := cArgName
    SELF:ArgNum      := iArgNum
    SELF:Description := ErrString( dwGenCode )

    /// Create an Error Object.
    CONSTRUCTOR (dwGenCode AS DWORD, dwSubCode := 0 AS DWORD)
    SELF:setDefaultValues()
    SELF:Gencode := dwGenCode
    SELF:SubCode := dwSubCode
    SELF:Description := ErrString( dwGenCode )

    PRIVATE STATIC METHOD LangString(e as VOErrors) AS STRING
        local cString := __CavoStr(e):Trim() as string
        IF cString:EndsWith(":")
            cString := cString:Substring(0, cString:Length-1):Trim()
        endif
        return cString+e" :\t"

    /// <inheritdoc />
    OVERRIDE METHOD ToString() AS STRING
      LOCAL sb AS StringBuilder
      LOCAL nGenCode AS Gencode
      nGenCode := (Gencode) SELF:Gencode
      sb := StringBuilder{}
      sb:AppendLine( LangString(VOErrors.ERROR_DESCRIPTION) + SELF:Description)
      sb:AppendLine( LangString(VOErrors.ERROR_SUBSYSTEM) + SELF:SubSystem )
      sb:AppendLine( LangString(VOErrors.ERROR_GENCODE) + nGenCode:ToString()  +" " +SELF:GenCodeText  )
      IF SELF:SubCode != 0
        sb:AppendLine( LangString(VOErrors.ERROR_SUBCODE) + SELF:SubCode:ToString() +" "+SELF:SubCodeText)
      ENDIF
      IF SELF:OSCode != 0
        sb:AppendLine( LangString(VOErrors.ERROR_OSCODE)  + SELF:OSCode:ToString() +" " +SELF:OSCodeText )
      ENDIF
      IF !String.IsNullOrEmpty(SELF:FuncSym)
        sb:AppendLine(LangString(VOErrors.ERROR_FUNCSYM) + SELF:FuncSym   )
      ENDIF
      LOCAL sev := (Severity) SELF:Severity AS Severity
      sb:AppendLine(LangString(VOErrors.ERROR_SEVERITY)     + sev:ToString() )
      sb:AppendLine(LangString(VOErrors.ERROR_CANDEFAULT)   + SELF:CanDefault:ToString())
      sb:AppendLine(LangString(VOErrors.ERROR_CANRETRY)     +SELF:CanRetry:ToString() )
      sb:AppendLine(LangString(VOErrors.ERROR_CANSUBSTITUTE) +SELF:CanSubstitute:ToString())
      IF ! String.IsNullOrEmpty(SELF:Operation)
        sb:AppendLine(LangString(VOErrors.ERROR_OPERATION) + SELF:Operation)
      ENDIF
      IF ! String.IsNullOrEmpty(SELF:FileName)
        sb:AppendLine(LangString(VOErrors.ERROR_FILENAME) + SELF:FileName )
      ENDIF
      IF SELF:Tries != 0
          sb:AppendLine(LangString(VOErrors.ERROR_TRIES) + SELF:Tries:ToString()    )
     ENDIF
      IF SELF:ArgType != 0
        sb:AppendLine(LangString(VOErrors.ERROR_ARGTYPE) 	+ TypeString(SELF:ArgType    ) )
      ENDIF
      IF SELF:ArgNum != 0
        sb:AppendLine(LangString(VOErrors.ERROR_ARGNUM) 	+ SELF:ArgNum:ToString()    )
      ENDIF
      IF ! String.IsNullOrEmpty(SELF:Arg)
        sb:AppendLine(LangString(VOErrors.ERROR_ARG)	+ SELF:Arg)
      ENDIF
      LOCAL cArgs AS STRING
      IF SELF:Args != NULL .AND. SELF:Args:Length > 0
            cArgs := "{"
            LOCAL lFirst := TRUE AS LOGIC
            FOREACH VAR oArg IN SELF:Args
                IF ! lFirst
                    cArgs += ","
                ENDIF
                IF oArg == NULL
                    cArgs += "(NULL)"
                ELSE
                    cArgs += oArg:ToString()
                ENDIF
                lFirst := FALSE
            NEXT
            cArgs += "}"
            sb:AppendLine(LangString(VOErrors.ERROR_ARGS)+ cArgs)
      ENDIF
      IF SELF:ArgTypeReqType != NULL
        sb:AppendLine(LangString(VOErrors.ERROR_ARGTYPE_REQ) + SELF:ArgTypeReqType:FullName)
      ENDIF
      IF ! String.IsNullOrEmpty(SELF:CallFuncSym)
        sb:AppendLine(LangString(VOErrors.ERROR_CALLEDFROM) + SELF:CallFuncSym  )
      ENDIF
      sb:AppendLine(LangString(VOErrors.ERROR_STACK))
      sb:AppendLine(SELF:StackTrace  )
      RETURN sb:ToString()

    /// Throw the error.
    VIRTUAL METHOD Throw AS VOID STRICT
        THROW SELF

    #region STATIC methods TO construct an error
    /// <exclude/>
    STATIC METHOD ArgumentError(cFuncName AS STRING, name AS STRING, description AS STRING) AS Error
    RETURN ArgumentError(cFuncName, name, description, 0)

    /// <exclude/>
    STATIC METHOD ArgumentError(cFuncName AS STRING, name AS STRING, iArgnum  AS DWORD, aArgs PARAMS OBJECT[]) AS Error
    VAR err			:= Error{XSharp.Gencode.EG_ARG, name, ErrString( EG_ARG )}
    err:FuncSym     := cFuncName
    err:Description := err:Message
    err:ArgNum		:= iArgnum
    err:Args		:= aArgs
    RETURN err

    /// <exclude/>
    STATIC METHOD ArgumentError(cFuncName AS STRING, name AS STRING, description AS STRING, iArgnum AS DWORD) AS Error
    VAR err			:= Error{XSharp.Gencode.EG_ARG, name, description}
    err:FuncSym     := cFuncName
    err:Description := err:Message
    err:ArgNum		:= iArgnum
    RETURN err

    STATIC METHOD ArgumentError(cFuncName AS STRING, name AS STRING, description AS STRING, iArgnum AS DWORD, aArgs AS OBJECT[]) AS Error
        VAR err := ArgumentError(cFuncName, name, description, iArgnum)
        err:Args := aArgs
    RETURN err

    /// <exclude/>
    STATIC METHOD WrapRawException( ex AS Exception ) AS Error
    LOCAL e AS Error
    if ex != null
        e			  := Error{ ex }
        e:Description := ErrString( EG_EXCEPTION ) + ": " + ex:Message
    else
        e			  := Error{  }
        e:Description := ErrString( EG_SEQUENCE )
    endif
    RETURN e

    /// <exclude/>
    STATIC METHOD VOError( dwGenCode AS DWORD, cFuncName AS STRING, cArgName AS STRING, iArgNum AS DWORD, aArgs AS OBJECT[] ) AS Error
        LOCAL e AS Error
        e:= Error{dwGenCode,cArgName}
        e:FuncSym := cFuncName
        e:ArgNum := iArgNum
        e:Args := aArgs
        e:Description := ErrString( dwGenCode )
        RETURN e

    /// <exclude/>
    STATIC METHOD VOError( ex AS Exception, dwGenCode AS DWORD, cFuncName AS STRING, cArgName AS STRING, iArgNum AS DWORD, aArgs AS OBJECT[]  ) AS Error
    LOCAL e AS Error
    e			  := Error{ ex, cFuncName, cArgName, iArgNum, aArgs }
    e:Gencode     := dwGenCode
    e:Description := ErrString( dwGenCode )
    RETURN e

    /// <exclude/>
    STATIC METHOD VoDbError( dwGenCode AS DWORD, dwSubCode AS DWORD, cFuncName AS STRING ) AS Error
    LOCAL e AS Error
    e := Error{dwGenCode, dwSubCode}
    e:SubSystem   := "DBCMD"
    e:FuncSym     := cFuncName
    e:Description := ErrString( dwGenCode )
    RETURN e

    /// <exclude/>
    STATIC METHOD VoDbError( dwGenCode AS DWORD, dwSubCode AS DWORD, cFuncName AS STRING, aArgs PARAMS OBJECT[] ) AS Error
    LOCAL e AS Error
    e := Error{dwGenCode, dwSubCode}
    e:SubSystem   := "DBCMD"
    e:FuncSym     := cFuncName
    e:Description := ErrString( dwGenCode )
    e:Args        := aArgs
    IF aArgs:Length > 0
        e:Arg := aArgs[0]:ToString()
    ENDIF
    RETURN e

    /// <exclude/>
    STATIC METHOD VoDbError( dwGenCode AS DWORD, dwSubCode AS DWORD, aArgs PARAMS OBJECT[] ) AS Error
    LOCAL e AS Error
    e			  := Error{dwGenCode, dwSubCode}
    e:SubSystem   := "DBCMD"
    e:Description := __CavoStr( dwSubCode)
    e:Args        := aArgs
    IF aArgs:Length > 0
        e:Arg := aArgs[0]:ToString()
    ENDIF
    RETURN e

    /// <exclude/>
    STATIC METHOD VoDbError( dwGenCode AS DWORD, dwSubCode AS DWORD, cFuncName AS STRING, cArgName AS STRING, iArgNum AS DWORD, aArgs PARAMS OBJECT[] ) AS Error
    LOCAL e AS Error
    e := Error{dwGenCode, dwSubCode, cFuncName, cArgName, iArgNum}
    e:SubSystem   := "DBCMD"
    IF dwSubCode != 0
        e:Description := __CavoStr( dwSubCode)
    ELSE
        e:Description := ErrString(dwGenCode)
    ENDIF
    e:Args        := aArgs
    RETURN e

    /// <exclude/>
    STATIC METHOD DataTypeError( cFuncName AS STRING, cArgName AS STRING, iArgNum AS DWORD, aArgs PARAMS OBJECT[] ) AS Error
    LOCAL e AS Error
    e			  := Error{ ArgumentException{} , cFuncName, cArgName, iArgNum, aArgs}
    e:Gencode     := EG_DATATYPE
    e:Description := __CavoStr( VOErrors.DATATYPEERROR )
    RETURN e

    /// <exclude/>
    STATIC METHOD ArgumentError( cFuncName AS STRING, cArgName AS STRING, iArgNum AS DWORD, cDescription AS STRING, aArgs PARAMS OBJECT[]) AS Error
    LOCAL e AS Error
    e				:= Error{ ArgumentException{} , cFuncName, cArgName, iArgNum, aArgs}
    e:Gencode     := EG_ARG
    e:Description := cDescription
    RETURN e

    /// <exclude/>
    STATIC METHOD NullArgumentError( cFuncName AS STRING, cArgName AS STRING, iArgNum AS DWORD ) AS Error
    LOCAL e AS Error
    e := Error{ ArgumentNullException{} ,cFuncName, cArgName, iArgNum}
    e:Gencode     := EG_ARG
    e:Description := __CavoStr( VOErrors.ARGISNULL )
    RETURN e

    /// <exclude/>
    STATIC METHOD BoundError( cFuncName AS STRING, cArgName AS STRING, iArgNum AS DWORD, aArgs PARAMS OBJECT[] ) AS Error
    LOCAL e AS Error
    e := Error{ ArgumentException{ErrString( EG_BOUND) } }
    e:Severity    := ES_ERROR
    e:Gencode     := EG_BOUND
    e:SubSystem   := "BASE"
    e:FuncSym     := cFuncName
    e:Arg         := cArgName
    e:ArgNum      := iArgNum
    e:Args        := aArgs
    RETURN e

    #endregion
    /// <exclude />
    STATIC METHOD TypeToUsualType(oType AS System.Type) AS DWORD
    SWITCH Type.GetTypeCode(oType)
    CASE TypeCode.Boolean
      RETURN __UsualType.Logic
    CASE TypeCode.Byte
      RETURN __UsualType.Byte
    CASE TypeCode.Char
      RETURN __UsualType.Char
    CASE TypeCode.DateTime
      RETURN __UsualType.DateTime
    CASE TypeCode.DBNull
      RETURN __UsualType.Object
    CASE TypeCode.Decimal
      RETURN __UsualType.Decimal
    CASE TypeCode.Double
      RETURN __UsualType.Real8
    CASE TypeCode.Empty
      RETURN __UsualType.Void
    CASE TypeCode.Int16
      RETURN __UsualType.ShortInt
    CASE TypeCode.Int32
      RETURN __UsualType.Long
    CASE TypeCode.Int64
      RETURN __UsualType.Int64
    CASE TypeCode.SByte
      RETURN __UsualType.Byte
    CASE TypeCode.Single
      RETURN __UsualType.Real4
    CASE TypeCode.UInt16
      RETURN __UsualType.Word
    CASE TypeCode.UInt32
      RETURN __UsualType.DWord
    CASE TypeCode.UInt64
      RETURN __UsualType.UInt64
    OTHERWISE
        SWITCH oType:FullName:ToLower()
        CASE "xsharp.__array"
          RETURN __UsualType.Array
        CASE "xsharp.__binary"
          RETURN __UsualType.Binary
        CASE "xsharp.__codeblock"
          RETURN __UsualType.Codeblock
        CASE "xsharp.__currency"
          RETURN __UsualType.Currency
        CASE "xsharp.__date"
          RETURN __UsualType.Date
        CASE "xsharp.__float"
          RETURN __UsualType.Float
        CASE "xsharp.__psz"
          RETURN __UsualType.Psz
        CASE "xsharp.__symbol"
          RETURN __UsualType.Symbol
        CASE "xsharp.__usual"
          RETURN __UsualType.Usual
        CASE "system.intptr"
          RETURN __UsualType.Ptr

      END SWITCH
    END SWITCH
    RETURN __UsualType.Void

    /// <exclude />
    STATIC METHOD UsualTypeToType(dwType AS DWORD) AS System.Type
    LOCAL typeName := NULL AS STRING
    SWITCH dwType
    CASE __UsualType.Array
      typeName := "XSharp.__Array"
    CASE __UsualType.Byte
      RETURN typeof(System.Byte)
    CASE __UsualType.Binary
       typeName := "XSharp.__Binary"
    CASE __UsualType.Char
      RETURN typeof(System.Char)
    CASE __UsualType.Codeblock
      typeName := "XSharp.__CodeBlock"
    CASE __UsualType.Currency
      typeName := "XSharp.__Currency"
    CASE __UsualType.Date
      typeName := "XSharp.__Date"
    CASE __UsualType.DWord
      RETURN typeof(System.UInt32)
    CASE __UsualType.Int64
      RETURN typeof(System.Int64)
    CASE __UsualType.Float
      typeName := "XSharp.__Float"
    CASE __UsualType.Logic
      RETURN typeof(System.Boolean)
    CASE __UsualType.Long
      RETURN typeof(System.Int32)
    CASE __UsualType.Object
      RETURN typeof(System.Object)
    CASE __UsualType.Psz
      typeName := "XSharp.__Psz"
    CASE __UsualType.Ptr
      RETURN typeof(System.IntPtr)
    CASE __UsualType.Real4
      RETURN typeof(System.Single)
    CASE __UsualType.Real8
      RETURN typeof(System.Double)
    CASE __UsualType.ShortInt
      RETURN typeof(System.Int16)
    CASE __UsualType.String
      RETURN typeof(System.String)
    CASE __UsualType.Symbol
      typeName := "XSharp.__Symbol"
    CASE __UsualType.UInt64
      RETURN typeof(System.Int64)
    CASE __UsualType.Usual
      typeName := "XSharp.__Usual"
    CASE __UsualType.Void
      RETURN typeof(System.Void)
    CASE __UsualType.Word
      RETURN typeof(System.UInt16)
    END SWITCH
    // lookup types in XSharp.VO
    IF typeName != NULL
        FOREACH asm AS Assembly IN AppDomain.CurrentDomain:GetAssemblies()
          IF asm:GetName():Name:ToLower() == "xsharp.vo"
            VAR type := asm:GetType(typeName, FALSE, TRUE)
            IF type != NULL
              RETURN type
            ENDIF
          ENDIF
        NEXT
    ENDIF
    RETURN NULL

  STATIC METHOD GetInnerException( SELF e as Exception) AS Exception
     IF e:InnerException != NULL
        DO WHILE e:InnerException != NULL
            e := e:InnerException
            IF e IS XSharp.Error
                EXIT
            ENDIF
        ENDDO
     ENDIF
     RETURN e
END CLASS
END NAMESPACE

/// <include file="VoFunctionDocs.xml" path="Runtimefunctions/errorbuild/*" />
FUNCTION ErrorBuild(pErrInfo AS Exception) AS XSharp.Error
	RETURN  XSharp.Error{pErrInfo}


[Runtime tests] Added test for uninitialized strings in usual (https://github.com/X-Sharp/XSharpPublic/issues/297)

//
// Copyright (c) XSharp B.V.  All Rights Reserved.
// Licensed under the Apache License, Version 2.0.
// See License.txt in the project root for license information.
//
USING System
USING System.Collections.Generic
USING System.Linq
USING System.Text
USING XUnit

BEGIN NAMESPACE XSharp.VO.Tests

	CLASS UsualTests

		[Fact, Trait("Category", "Usual")];
		METHOD UsualDateTimeTest() AS VOID
			LOCAL now AS DateTime
			LOCAL u   AS USUAL
		    now := System.DateTime.Now
			u := now
			// cannot call u:ToString directly because of late binding in other tests
			VAR s := u:ToString()
			Assert.Equal(now:ToString(),u:ToString())
			LOCAL check AS DateTime
			check := u
			Assert.Equal(now, check)
		RETURN

		[Fact, Trait("Category", "Usual")];
		METHOD UsualDecimalTests() AS VOID
			LOCAL u AS USUAL
			LOCAL l AS Decimal
			l := 1
			u := l
			Assert.Equal(UsualType(u), (DWORD) 27)
			l := u
			Assert.Equal(l,1)
			Assert.Equal(l,  (Decimal) u)
			u += 1
			Assert.Equal(2,  (Decimal) u)
			u++
			Assert.Equal(3,  (Decimal) u)
			u += 1U
			Assert.Equal(4,  (Decimal) u)
			// Note: adding a float to a usual results in a usual of type FLOAT
			// Therefore we must add the m suffix here
			u += 1.0m
			Assert.Equal(5, (Decimal) u)
			u := Decimal.MaxValue
			RETURN

		[Fact, Trait("Category", "Usual")];
		METHOD UsualInt64Tests() AS VOID
			LOCAL u AS USUAL
			LOCAL l AS INT64
			u :=  1
			Assert.Equal(UsualType(u), (DWORD) LONG)
			l := u
			Assert.Equal(l,1)
			Assert.Equal(l,  (INT64) u)
			u := UInt64.MaxValue
			l := u	// NO Overflow Error
			u := "a text"
			Assert.Throws(TYPEOF(Error), { => l := u})	// Conversion Error
			RETURN

		[Fact, Trait("Category", "Usual")];
		METHOD UsualLongTests() AS VOID
			LOCAL u AS USUAL
			LOCAL l AS LONG
			u := 1
			Assert.Equal(UsualType(u), (DWORD) LONG)
			l := u
			Assert.Equal(l,1)
			Assert.Equal(l,  (LONG) u)
			u := UInt32.MaxValue
            VAR previous := RuntimeState.CompilerOptionOVF
            RuntimeState.CompilerOptionOVF := TRUE
			Assert.Throws(TYPEOF(Error), { => l := (LONG) u})	// Overflow Error
            RuntimeState.CompilerOptionOVF := previous
			u := "a text"
			Assert.Throws(TYPEOF(Error), { => l := (LONG) u})	// Conversion Error

			RETURN

		[Fact, Trait("Category", "Usual")];
		METHOD UsualReal4Tests() AS VOID
			LOCAL u AS USUAL
			LOCAL r AS REAL4
			r := 1.0
            u:= r
			Assert.Equal(UsualType(u), (DWORD) FLOAT)
			r := u
			Assert.Equal(r,(REAL4) 1.0)
			Assert.Equal(r,  (REAL4) u)
			r := System.Single.MaxValue
            u:= r
			Assert.Equal(UsualType(u), (DWORD) FLOAT)
			r := u
			Assert.Equal(r,System.Single.MaxValue)
			Assert.Equal(r,  (REAL4) u)

			RETURN

        [Fact, Trait("Category", "Usual")];
		METHOD UsualReal8Tests() AS VOID
			LOCAL u AS USUAL
			LOCAL r AS REAL8
			r := 1.0
            u:= r
			Assert.Equal(UsualType(u), (DWORD) FLOAT)
			r := u
			Assert.Equal(r,(REAL8) 1.0)
			Assert.Equal(r,  (REAL8) u)
			r := System.Double.MaxValue
            u:= r
			Assert.Equal(UsualType(u), (DWORD) FLOAT)
			r := u
			Assert.Equal(r,System.Double.MaxValue)
			Assert.Equal(r,  (REAL8) u)

			RETURN

		[Fact, Trait("Category", "Usual")];
		METHOD UsualShortTests() AS VOID
			LOCAL u AS USUAL
			LOCAL l AS LONG
			u := (USUAL) (SHORT)1
			Assert.Equal(UsualType(u), (DWORD) LONG)
			l := u
			Assert.Equal(l,1)
			Assert.Equal(l,  (SHORT) u)
			u := UInt16.MaxValue
			//Assert.Throws(TYPEOF(Error), { => l := (SHORT) u})	// Overflow Error
			u := "a text"
			Assert.Throws(TYPEOF(Error), { => l := (SHORT) u})	// Conversion Error

			RETURN

		[Fact, Trait("Category", "Usual")];
		METHOD UsualSByteTests() AS VOID
			LOCAL u AS USUAL
			LOCAL l AS SByte
			u := (SByte)1
			Assert.Equal(UsualType(u), (DWORD) LONG)
			l := u
			Assert.Equal(l,1)
			Assert.Equal(l,  (SByte) u)
			u := Byte.MaxValue
			//Assert.Throws(TYPEOF(Error), { => l := (SByte) u})	// Overflow Error
			u := "a text"
			Assert.Throws(TYPEOF(Error), { => l := (SByte) u})	// Conversion Error
			RETURN

		[Fact, Trait("Category", "Usual")];
		METHOD UsualUInt64Tests() AS VOID
			LOCAL u AS USUAL
			LOCAL d AS UINT64
			u := (UINT64) 1
			Assert.Equal(UsualType(u), (DWORD) INT64)
			d := u
			Assert.Equal(d,1U)
			Assert.Equal(d,  (UINT64) u)
			u := -1
			d := u	// NO Overflow Error
            Assert.Equal(d,  UInt64.MaxValue)
			u := "a text"
			Assert.Throws(TYPEOF(Error), { => d :=  u})	// Conversion Error
			RETURN

		[Fact, Trait("Category", "Usual")];
		METHOD UsualDwordTests() AS VOID
			LOCAL u AS USUAL
			LOCAL d AS DWORD
			u := (DWORD) 1
			Assert.Equal(UsualType(u), (DWORD) LONG)
			d := u
			Assert.Equal(d,1U)
			Assert.Equal(d,  (DWORD) u)
			u := -1
			d := u	// USUAL -> DWORD gives NO overflow error
            Assert.Equal(d,  UInt32.MaxValue)
			u := "a text"
			Assert.Throws(TYPEOF(Error), { => d :=  u})	// Conversion Error
			RETURN

		[Fact, Trait("Category", "Usual")];
		METHOD UsualwordTests() AS VOID
			LOCAL u AS USUAL
			LOCAL w AS WORD
			u :=  (WORD) 1
			Assert.Equal(UsualType(u), (DWORD) LONG)
			w := u
			Assert.Equal(w,1)
			Assert.Equal(w,  (WORD) u)
			u := -1
			//Assert.Throws(TYPEOF(Error), { => w := u})	// Overflow Error
			u := "a text"
			Assert.Throws(TYPEOF(Error), { => w := u})	// Conversion Error
			RETURN

		[Fact, Trait("Category", "Usual")];
		METHOD UsualByteTests() AS VOID
			LOCAL u AS USUAL
			LOCAL b AS BYTE
			b := 1
			u :=  b
			Assert.Equal(UsualType(u), (DWORD) LONG)
			b := u
			Assert.Equal(b,1U)
			Assert.Equal(b,  (BYTE) u)
			u :=  -1
			//Assert.Throws(TYPEOF(Error), { => b :=  u})	// Overflow Error
			u := "a text"
			Assert.Throws(TYPEOF(Error), { => b :=  u})	// Conversion Error
			RETURN

		[Fact, Trait("Category", "Usual")];
		METHOD UsualAddOperatorTests() AS VOID
			LOCAL u AS USUAL
			u :=  1
			u += 1
			Assert.Equal((INT) u, 2)
			u += (INT64) 1
			Assert.Equal((INT) u, 3)
			u += 1.0
			Assert.Equal((INT) u, 4)
			u++
			Assert.Equal((INT) u, 5)
			Assert.Throws(TYPEOF(Error), { => u += "a"})

			u := (INT64) 1
			u += (INT) 1
			Assert.Equal((INT64) u, 2)
			u += (INT64) 1
			Assert.Equal((INT64) u, 3)
			u += 1.0
			Assert.Equal((INT64) u, 4)
			u++
			Assert.Equal((INT64) u, 5)
			Assert.Throws(TYPEOF(Error), { => u += "a"})

			u :=   1.0
			u += 1
			Assert.Equal((FLOAT) u, 2.0)
			u += (INT64) 1
			Assert.Equal((FLOAT) u, 3.0)
			u += 1.0
			Assert.Equal((FLOAT) u, 4.0)
			u ++
			Assert.Equal((FLOAT) u, 5.0)
			Assert.Throws(TYPEOF(Error), { => u += "a"})

			u := "abc"
			u += "def"
			Assert.Equal((STRING) u, "abcdef")
			Assert.Throws(TYPEOF(Error), { => u += 1})

			VAR d := (DATE) datetime.Now
			u := d
			u += 1
			d += 1
			Assert.Equal((DATE) u,  d)

		[Fact, Trait("Category", "Usual")];
		METHOD UsualSubOperatorTests() AS VOID
			LOCAL u AS USUAL
			u := 100
			u -= 1
			Assert.Equal((INT) u, 99)
			u -= (INT64) 1
			Assert.Equal((INT) u, 98)
			u -= 1.0
			Assert.Equal((INT) u, 97)
			u--
			Assert.Equal((INT) u, 96)
			Assert.Throws(TYPEOF(Error), { => u -= "a"})

			u := (INT64) 1000
			u -= (INT) 1
			Assert.Equal((INT64) u, 999)
			u -= (INT64) 1
			Assert.Equal((INT64) u, 998)
			u -= 1.0
			Assert.Equal((INT64) u, 997)
			u--
			Assert.Equal((INT64) u, 996)
			Assert.Throws(TYPEOF(Error), { => u -= "a"})

			u := 111.1
			u -= 1
			Assert.Equal((FLOAT) u, 110.1)
			u -= (INT64) 1
			Assert.Equal((FLOAT) u, 109.1)
			u -= 1.0
			Assert.Equal((FLOAT) u, 108.1)
			u--
			Assert.Equal((FLOAT) u, 107.1)
			Assert.Throws(TYPEOF(Error), { => u -= "a"})

			u := "abc"
			u -= "def"
			Assert.Equal((STRING) u, "abcdef")
			Assert.Throws(TYPEOF(Error), { => u -= 1})

		[Fact, Trait("Category", "Usual string comparisons")];
		METHOD UsualStringComparisons() AS VOID
			LOCAL lExact := SetExact() AS LOGIC
			LOCAL u AS USUAL

			FOR LOCAL n := 1 AS INT UPTO 2
				SetExact(n == 1)
				u := "ABC"
				// do not chnage to Assert.Equal(), we need to test the operators
				Assert.False(u = "123456")
				Assert.False(u == "123456")
				Assert.True(u != "123456")
				Assert.True(u <> "123456")

				u := "123456"
				Assert.False(u = "ABC")
				Assert.False(u == "ABC")
				Assert.True(u != "ABC")
				Assert.True(u <> "ABC")
			NEXT

			SetExact(lExact)

		[Fact, Trait("Category", "Usual conversion tests")];
		METHOD UsualConversionTests() AS VOID
			LOCAL u AS USUAL
			LOCAL d AS DWORD
			u := UInt32.MaxValue
			d := UsualConversionTests_helper(u)
			Assert.Equal(UInt32.MaxValue - 1 , d)

		METHOD UsualConversionTests_helper(d AS DWORD) AS DWORD
			d --
		RETURN d

        [Fact, Trait("Category", "Usual conversion tests")];
		METHOD UsualIsTests() AS VOID
			LOCAL u AS USUAL
            u := Today()
            Assert.Equal(TRUE, IsDate(u))
            Assert.Equal(FALSE, IsDateTime(u))
            u := DateTime.Now
            Assert.Equal(TRUE, IsDate(u))
            Assert.Equal(TRUE, IsDateTime(u))
            u := 1L
            Assert.Equal(TRUE, IsLong(u))
            Assert.Equal(FALSE, IsInt64(u))
            Assert.Equal(TRUE, IsInteger(u))
            Assert.Equal(TRUE, IsNumeric(u))
            Assert.Equal(FALSE, IsFloat(u))
            Assert.Equal(FALSE, IsFractional(u))
            Assert.Equal(FALSE, IsDecimal(u))
            u := Int64.MaxValue
            Assert.Equal(FALSE, IsLong(u))
            Assert.Equal(TRUE, IsInt64(u))
            Assert.Equal(TRUE, IsInteger(u))
            Assert.Equal(TRUE, IsNumeric(u))
            Assert.Equal(FALSE, IsFloat(u))
            Assert.Equal(FALSE, IsFractional(u))
            Assert.Equal(FALSE, IsDecimal(u))
            u := FLOAT{1,1,0}
            Assert.Equal(FALSE, IsLong(u))
            Assert.Equal(FALSE, IsInt64(u))
            Assert.Equal(FALSE, IsInteger(u))
            Assert.Equal(TRUE, IsNumeric(u))
            Assert.Equal(TRUE, IsFloat(u))
            Assert.Equal(TRUE, IsFractional(u))
            Assert.Equal(FALSE, IsDecimal(u))
            u := 1m
            Assert.Equal(FALSE, IsLong(u))
            Assert.Equal(FALSE, IsInt64(u))
            Assert.Equal(FALSE, IsInteger(u))
            Assert.Equal(TRUE, IsNumeric(u))
            Assert.Equal(FALSE, IsFloat(u))
            Assert.Equal(TRUE, IsFractional(u))
            Assert.Equal(TRUE, IsDecimal(u))
            u := "abc"
            Assert.Equal(FALSE, IsLong(u))
            Assert.Equal(TRUE, IsString(u))
            Assert.Equal(FALSE, IsSymbol(u))
            u := #abc
            Assert.Equal(FALSE, IsLong(u))
            Assert.Equal(FALSE, IsString(u))
            Assert.Equal(TRUE, IsSymbol(u))
            u := {}
            Assert.Equal(FALSE, IsLong(u))
            Assert.Equal(FALSE, IsString(u))
            Assert.Equal(TRUE, IsArray(u))
            u := NIL
            Assert.Equal(FALSE, IsLong(u))
            Assert.Equal(FALSE, IsString(u))
            Assert.Equal(TRUE, IsNil(u))
            u := {|e|e+1}
            Assert.Equal(FALSE, IsLong(u))
            Assert.Equal(FALSE, IsString(u))
            Assert.Equal(TRUE, IsCodeBlock(u))
            u := MemAlloc(1)
            Assert.Equal(FALSE, IsLong(u))
            Assert.Equal(FALSE, IsString(u))
            Assert.Equal(TRUE, IsPtr(u))
            MemFree(u)

            u := Exception{}
            Assert.Equal(FALSE, IsLong(u))
            Assert.Equal(FALSE, IsString(u))
            Assert.Equal(TRUE, IsObject(u))

            RETURN
        [Fact, Trait("Category", "Usual pointer conversion tests")];
		METHOD UsualPtrConversionTests() AS VOID
            LOCAL u1 AS USUAL
            LOCAL u2 AS USUAL
            u1 := -1
            u2 := (IntPtr) -2
            Assert.Equal(FALSE, u1 == u2)
            Assert.Equal(TRUE, u1 != u2)
            Assert.Equal(TRUE, u1 > u2)
            Assert.Equal(TRUE, u1 >= u2)
            Assert.Equal(FALSE, u1 < u2)
            Assert.Equal(FALSE, u1 <= u2)

            Assert.Equal(FALSE, u2 == u1)
            Assert.Equal(TRUE, u2 != u1)
            Assert.Equal(FALSE, u2 > u1)
            Assert.Equal(FALSE, u2 >= u1)
            Assert.Equal(TRUE, u2 < u1)
            Assert.Equal(TRUE, u2 <= u1)

            LOCAL  i64 := -1 AS INT64
            u1 := i64
            Assert.Equal(FALSE, u1 == u2)
            Assert.Equal(TRUE, u1 != u2)
            Assert.Equal(TRUE, u1 > u2)
            Assert.Equal(TRUE, u1 >= u2)
            Assert.Equal(FALSE, u1 < u2)
            Assert.Equal(FALSE, u1 <= u2)

            Assert.Equal(FALSE, u2 == u1)
            Assert.Equal(TRUE, u2 != u1)
            Assert.Equal(FALSE, u2 > u1)
            Assert.Equal(FALSE, u2 >= u1)
            Assert.Equal(TRUE, u2 < u1)
            Assert.Equal(TRUE, u2 <= u1)

        [Fact, Trait("Category", "usual to string tests")];
		METHOD UsualToStringTests() AS VOID
			LOCAL cVal AS STRING
			cVal := GetNullStringInUsual()
			Assert.True(Empty(cVal))
			Assert.True(cVal == "")

		PRIVATE METHOD GetNullStringInUsual() AS USUAL
			LOCAL cRet AS STRING
		RETURN cRet

	END CLASS
END NAMESPACE // XSharp.Runtime.Tests

//
// Copyright (c) XSharp B.V.  All Rights Reserved.
// Licensed under the Apache License, Version 2.0.
// See License.txt in the project root for license information.
//
USING System
USING System.Collections.Generic
USING System.Linq
USING System.Text
USING XUnit

BEGIN NAMESPACE XSharp.VO.Tests

	CLASS UsualTests

		[Fact, Trait("Category", "Usual")];
		METHOD UsualDateTimeTest() AS VOID
			LOCAL now AS DateTime
			LOCAL u   AS USUAL
		    now := System.DateTime.Now
			u := now
			// cannot call u:ToString directly because of late binding in other tests
			VAR s := u:ToString()
			Assert.Equal(now:ToString(),u:ToString())
			LOCAL check AS DateTime
			check := u
			Assert.Equal(now, check)
		RETURN

		[Fact, Trait("Category", "Usual")];
		METHOD UsualDecimalTests() AS VOID
			LOCAL u AS USUAL
			LOCAL l AS Decimal
			l := 1
			u := l
			Assert.Equal(UsualType(u), (DWORD) 27)
			l := u
			Assert.Equal(l,1)
			Assert.Equal(l,  (Decimal) u)
			u += 1
			Assert.Equal(2,  (Decimal) u)
			u++
			Assert.Equal(3,  (Decimal) u)
			u += 1U
			Assert.Equal(4,  (Decimal) u)
			// Note: adding a float to a usual results in a usual of type FLOAT
			// Therefore we must add the m suffix here
			u += 1.0m
			Assert.Equal(5, (Decimal) u)
			u := Decimal.MaxValue
			RETURN

		[Fact, Trait("Category", "Usual")];
		METHOD UsualInt64Tests() AS VOID
			LOCAL u AS USUAL
			LOCAL l AS INT64
			u :=  1
			Assert.Equal(UsualType(u), (DWORD) LONG)
			l := u
			Assert.Equal(l,1)
			Assert.Equal(l,  (INT64) u)
			u := UInt64.MaxValue
			l := u	// NO Overflow Error
			u := "a text"
			Assert.Throws(TYPEOF(Error), { => l := u})	// Conversion Error
			RETURN

		[Fact, Trait("Category", "Usual")];
		METHOD UsualLongTests() AS VOID
			LOCAL u AS USUAL
			LOCAL l AS LONG
			u := 1
			Assert.Equal(UsualType(u), (DWORD) LONG)
			l := u
			Assert.Equal(l,1)
			Assert.Equal(l,  (LONG) u)
			u := UInt32.MaxValue
            var previous := RuntimeState.CompilerOptionOVF
            RuntimeState.CompilerOptionOVF := TRUE
			Assert.Throws(TYPEOF(Error), { => l := (LONG) u})	// Overflow Error
            RuntimeState.CompilerOptionOVF := previous
			u := "a text"
			Assert.Throws(TYPEOF(Error), { => l := (LONG) u})	// Conversion Error

			RETURN

		[Fact, Trait("Category", "Usual")];
		METHOD UsualReal4Tests() AS VOID
			LOCAL u AS USUAL
			LOCAL r AS REAL4
			r := 1.0
            u:= r
			Assert.Equal(UsualType(u), (DWORD) FLOAT)
			r := u
			Assert.Equal(r,(REAL4) 1.0)
			Assert.Equal(r,  (REAL4) u)
			r := System.Single.MaxValue
            u:= r
			Assert.Equal(UsualType(u), (DWORD) FLOAT)
			r := u
			Assert.Equal(r,System.Single.MaxValue)
			Assert.Equal(r,  (REAL4) u)

			RETURN

        [Fact, Trait("Category", "Usual")];
		METHOD UsualReal8Tests() AS VOID
			LOCAL u AS USUAL
			LOCAL r AS REAL8
			r := 1.0
            u:= r
			Assert.Equal(UsualType(u), (DWORD) FLOAT)
			r := u
			Assert.Equal(r,(REAL8) 1.0)
			Assert.Equal(r,  (REAL8) u)
			r := System.Double.MaxValue
            u:= r
			Assert.Equal(UsualType(u), (DWORD) FLOAT)
			r := u
			Assert.Equal(r,System.Double.MaxValue)
			Assert.Equal(r,  (REAL8) u)

			RETURN

		[Fact, Trait("Category", "Usual")];
		METHOD UsualShortTests() AS VOID
			LOCAL u AS USUAL
			LOCAL l AS LONG
			u := (USUAL) (SHORT)1
			Assert.Equal(UsualType(u), (DWORD) LONG)
			l := u
			Assert.Equal(l,1)
			Assert.Equal(l,  (SHORT) u)
			u := UInt16.MaxValue
			//Assert.Throws(TYPEOF(Error), { => l := (SHORT) u})	// Overflow Error
			u := "a text"
			Assert.Throws(TYPEOF(Error), { => l := (SHORT) u})	// Conversion Error

			RETURN

		[Fact, Trait("Category", "Usual")];
		METHOD UsualSByteTests() AS VOID
			LOCAL u AS USUAL
			LOCAL l AS SByte
			u := (SByte)1
			Assert.Equal(UsualType(u), (DWORD) LONG)
			l := u
			Assert.Equal(l,1)
			Assert.Equal(l,  (SByte) u)
			u := Byte.MaxValue
			//Assert.Throws(TYPEOF(Error), { => l := (SByte) u})	// Overflow Error
			u := "a text"
			Assert.Throws(TYPEOF(Error), { => l := (SByte) u})	// Conversion Error
			RETURN

		[Fact, Trait("Category", "Usual")];
		METHOD UsualUInt64Tests() AS VOID
			LOCAL u AS USUAL
			LOCAL d AS UINT64
			u := (UINT64) 1
			Assert.Equal(UsualType(u), (DWORD) INT64)
			d := u
			Assert.Equal(d,1U)
			Assert.Equal(d,  (UINT64) u)
			u := -1
			d := u	// NO Overflow Error
            Assert.Equal(d,  UInt64.MaxValue)
			u := "a text"
			Assert.Throws(TYPEOF(Error), { => d :=  u})	// Conversion Error
			RETURN

		[Fact, Trait("Category", "Usual")];
		METHOD UsualDwordTests() AS VOID
			LOCAL u AS USUAL
			LOCAL d AS DWORD
			u := (DWORD) 1
			Assert.Equal(UsualType(u), (DWORD) LONG)
			d := u
			Assert.Equal(d,1U)
			Assert.Equal(d,  (DWORD) u)
			u := -1
			d := u	// USUAL -> DWORD gives NO overflow error
            Assert.Equal(d,  UInt32.MaxValue)
			u := "a text"
			Assert.Throws(TYPEOF(Error), { => d :=  u})	// Conversion Error
			RETURN

		[Fact, Trait("Category", "Usual")];
		METHOD UsualwordTests() AS VOID
			LOCAL u AS USUAL
			LOCAL w AS WORD
			u :=  (WORD) 1
			Assert.Equal(UsualType(u), (DWORD) LONG)
			w := u
			Assert.Equal(w,1)
			Assert.Equal(w,  (WORD) u)
			u := -1
			//Assert.Throws(TYPEOF(Error), { => w := u})	// Overflow Error
			u := "a text"
			Assert.Throws(TYPEOF(Error), { => w := u})	// Conversion Error
			RETURN

		[Fact, Trait("Category", "Usual")];
		METHOD UsualByteTests() AS VOID
			LOCAL u AS USUAL
			LOCAL b AS BYTE
			b := 1
			u :=  b
			Assert.Equal(UsualType(u), (DWORD) LONG)
			b := u
			Assert.Equal(b,1U)
			Assert.Equal(b,  (BYTE) u)
			u :=  -1
			//Assert.Throws(TYPEOF(Error), { => b :=  u})	// Overflow Error
			u := "a text"
			Assert.Throws(TYPEOF(Error), { => b :=  u})	// Conversion Error
			RETURN

		[Fact, Trait("Category", "Usual")];
		METHOD UsualAddOperatorTests() AS VOID
			LOCAL u AS USUAL
			u :=  1
			u += 1
			Assert.Equal((INT) u, 2)
			u += (INT64) 1
			Assert.Equal((INT) u, 3)
			u += 1.0
			Assert.Equal((INT) u, 4)
			u++
			Assert.Equal((INT) u, 5)
			Assert.Throws(TYPEOF(Error), { => u += "a"})

			u := (INT64) 1
			u += (INT) 1
			Assert.Equal((INT64) u, 2)
			u += (INT64) 1
			Assert.Equal((INT64) u, 3)
			u += 1.0
			Assert.Equal((INT64) u, 4)
			u++
			Assert.Equal((INT64) u, 5)
			Assert.Throws(TYPEOF(Error), { => u += "a"})

			u :=   1.0
			u += 1
			Assert.Equal((FLOAT) u, 2.0)
			u += (INT64) 1
			Assert.Equal((FLOAT) u, 3.0)
			u += 1.0
			Assert.Equal((FLOAT) u, 4.0)
			u ++
			Assert.Equal((FLOAT) u, 5.0)
			Assert.Throws(TYPEOF(Error), { => u += "a"})

			u := "abc"
			u += "def"
			Assert.Equal((STRING) u, "abcdef")
			Assert.Throws(TYPEOF(Error), { => u += 1})

			VAR d := (DATE) datetime.Now
			u := d
			u += 1
			d += 1
			Assert.Equal((DATE) u,  d)

		[Fact, Trait("Category", "Usual")];
		METHOD UsualSubOperatorTests() AS VOID
			LOCAL u AS USUAL
			u := 100
			u -= 1
			Assert.Equal((INT) u, 99)
			u -= (INT64) 1
			Assert.Equal((INT) u, 98)
			u -= 1.0
			Assert.Equal((INT) u, 97)
			u--
			Assert.Equal((INT) u, 96)
			Assert.Throws(TYPEOF(Error), { => u -= "a"})

			u := (INT64) 1000
			u -= (INT) 1
			Assert.Equal((INT64) u, 999)
			u -= (INT64) 1
			Assert.Equal((INT64) u, 998)
			u -= 1.0
			Assert.Equal((INT64) u, 997)
			u--
			Assert.Equal((INT64) u, 996)
			Assert.Throws(TYPEOF(Error), { => u -= "a"})

			u := 111.1
			u -= 1
			Assert.Equal((FLOAT) u, 110.1)
			u -= (INT64) 1
			Assert.Equal((FLOAT) u, 109.1)
			u -= 1.0
			Assert.Equal((FLOAT) u, 108.1)
			u--
			Assert.Equal((FLOAT) u, 107.1)
			Assert.Throws(TYPEOF(Error), { => u -= "a"})

			u := "abc"
			u -= "def"
			Assert.Equal((STRING) u, "abcdef")
			Assert.Throws(TYPEOF(Error), { => u -= 1})

		[Fact, Trait("Category", "Usual string comparisons")];
		METHOD UsualStringComparisons() AS VOID
			LOCAL lExact := SetExact() AS LOGIC
			LOCAL u AS USUAL

			FOR LOCAL n := 1 AS INT UPTO 2
				SetExact(n == 1)
				u := "ABC"
				// do not chnage to Assert.Equal(), we need to test the operators
				Assert.False(u = "123456")
				Assert.False(u == "123456")
				Assert.True(u != "123456")
				Assert.True(u <> "123456")

				u := "123456"
				Assert.False(u = "ABC")
				Assert.False(u == "ABC")
				Assert.True(u != "ABC")
				Assert.True(u <> "ABC")
			NEXT

			SetExact(lExact)

		[Fact, Trait("Category", "Usual conversion tests")];
		METHOD UsualConversionTests() AS VOID
			LOCAL u AS USUAL
			LOCAL d AS DWORD
			u := UInt32.MaxValue
			d := UsualConversionTests_helper(u)
			Assert.Equal(UInt32.MaxValue - 1 , d)

		METHOD UsualConversionTests_helper(d AS DWORD) AS DWORD
			d --
		RETURN d

        [Fact, Trait("Category", "Usual conversion tests")];
		METHOD UsualIsTests() AS VOID
			LOCAL u AS USUAL
            u := Today()
            Assert.Equal(TRUE, IsDate(u))
            Assert.Equal(FALSE, IsDateTime(u))
            u := DateTime.Now
            Assert.Equal(TRUE, IsDate(u))
            Assert.Equal(TRUE, IsDateTime(u))
            u := 1L
            Assert.Equal(TRUE, IsLong(u))
            Assert.Equal(FALSE, IsInt64(u))
            Assert.Equal(TRUE, IsInteger(u))
            Assert.Equal(TRUE, IsNumeric(u))
            Assert.Equal(FALSE, IsFLoat(u))
            Assert.Equal(FALSE, IsFractional(u))
            Assert.Equal(FALSE, IsDecimal(u))
            u := Int64.MaxValue
            Assert.Equal(FALSE, IsLong(u))
            Assert.Equal(TRUE, IsInt64(u))
            Assert.Equal(TRUE, IsInteger(u))
            Assert.Equal(TRUE, IsNumeric(u))
            Assert.Equal(FALSE, IsFLoat(u))
            Assert.Equal(FALSE, IsFractional(u))
            Assert.Equal(FALSE, IsDecimal(u))
            u := FLOAT{1,1,0}
            Assert.Equal(FALSE, IsLong(u))
            Assert.Equal(FALSE, IsInt64(u))
            Assert.Equal(FALSE, IsInteger(u))
            Assert.Equal(TRUE, IsNumeric(u))
            Assert.Equal(TRUE, IsFLoat(u))
            Assert.Equal(TRUE, IsFractional(u))
            Assert.Equal(FALSE, IsDecimal(u))
            u := 1m
            Assert.Equal(FALSE, IsLong(u))
            Assert.Equal(FALSE, IsInt64(u))
            Assert.Equal(FALSE, IsInteger(u))
            Assert.Equal(TRUE, IsNumeric(u))
            Assert.Equal(FALSE, IsFLoat(u))
            Assert.Equal(TRUE, IsFractional(u))
            Assert.Equal(TRUE, IsDecimal(u))
            u := "abc"
            Assert.Equal(FALSE, IsLong(u))
            Assert.Equal(TRUE, IsString(u))
            Assert.Equal(FALSE, IsSymbol(u))
            u := #abc
            Assert.Equal(FALSE, IsLong(u))
            Assert.Equal(FALSE, IsString(u))
            Assert.Equal(TRUE, IsSymbol(u))
            u := {}
            Assert.Equal(FALSE, IsLong(u))
            Assert.Equal(FALSE, IsString(u))
            Assert.Equal(TRUE, IsArray(u))
            u := NIL
            Assert.Equal(FALSE, IsLong(u))
            Assert.Equal(FALSE, IsString(u))
            Assert.Equal(TRUE, IsNil(u))
            u := {|e|e+1}
            Assert.Equal(FALSE, IsLong(u))
            Assert.Equal(FALSE, IsString(u))
            Assert.Equal(TRUE, IsCodeBlock(u))
            u := MemAlloc(1)
            Assert.Equal(FALSE, IsLong(u))
            Assert.Equal(FALSE, IsString(u))
            Assert.Equal(TRUE, IsPtr(u))
            MemFree(u)

            u := Exception{}
            Assert.Equal(FALSE, IsLong(u))
            Assert.Equal(FALSE, IsString(u))
            Assert.Equal(TRUE, IsObject(u))

            RETURN
        [Fact, Trait("Category", "Usual pointer conversion tests")];
		METHOD UsualPtrConversionTests() AS VOID
            LOCAL u1 AS USUAL
            LOCAL u2 AS USUAL
            u1 := -1
            u2 := (IntPtr) -2
            Assert.Equal(FALSE, u1 == u2)
            Assert.Equal(TRUE, u1 != u2)
            Assert.Equal(TRUE, u1 > u2)
            Assert.Equal(TRUE, u1 >= u2)
            Assert.Equal(FALSE, u1 < u2)
            Assert.Equal(FALSE, u1 <= u2)

            Assert.Equal(FALSE, u2 == u1)
            Assert.Equal(TRUE, u2 != u1)
            Assert.Equal(FALSE, u2 > u1)
            Assert.Equal(FALSE, u2 >= u1)
            Assert.Equal(TRUE, u2 < u1)
            Assert.Equal(TRUE, u2 <= u1)

            LOCAL  i64 := -1 AS INT64
            u1 := i64
            Assert.Equal(FALSE, u1 == u2)
            Assert.Equal(TRUE, u1 != u2)
            Assert.Equal(TRUE, u1 > u2)
            Assert.Equal(TRUE, u1 >= u2)
            Assert.Equal(FALSE, u1 < u2)
            Assert.Equal(FALSE, u1 <= u2)

            Assert.Equal(FALSE, u2 == u1)
            Assert.Equal(TRUE, u2 != u1)
            Assert.Equal(FALSE, u2 > u1)
            Assert.Equal(FALSE, u2 >= u1)
            Assert.Equal(TRUE, u2 < u1)
            Assert.Equal(TRUE, u2 <= u1)

	END CLASS
END NAMESPACE // XSharp.Runtime.Tests


QtQuickWidgets: data for code generation updated

Modified:
codegen/QtQuickWidgets/QQuickWidget.prg

%%
%% Qt5xHb - Bindings libraries for Harbour/xHarbour and Qt Framework 5
%%
%% Copyright (C) 2018 Marcos Antonio Gambeta <marcosgambeta AT outlook DOT com>
%%

$header

#include "hbclass.ch"

#ifndef QT5XHB_NO_REQUESTS
REQUEST QURL
REQUEST QQMLENGINE
REQUEST QQMLCONTEXT
REQUEST QQUICKITEM
REQUEST QQMLERROR
REQUEST QSIZE
REQUEST QSURFACEFORMAT
#endif

CLASS QQuickWidget INHERIT QWidget

   METHOD new
   METHOD delete
   METHOD source
   METHOD setSource
   METHOD engine
   METHOD rootContext
   METHOD rootObject
   METHOD resizeMode
   METHOD setResizeMode
   METHOD status
   METHOD errors
   METHOD sizeHint
   METHOD initialSize
   METHOD setContent
   METHOD format
   METHOD setFormat

   METHOD onStatusChanged
   METHOD onSceneGraphError

   DESTRUCTOR destroyObject

END CLASS

$destructor

#pragma BEGINDUMP

$includes=5,3,0

#include <QQmlError>
#include <QQmlEngine>
#include <QQmlContext>
#include <QQuickItem>

$prototype=explicit QQuickWidget(QWidget *parent = 0)
$internalConstructor=5,3,0|new1|QWidget *=0

$prototype=QQuickWidget(QQmlEngine* engine, QWidget *parent)
$internalConstructor=5,3,0|new2|QQmlEngine *,QWidget *

$prototype=QQuickWidget(const QUrl &source, QWidget *parent = 0)
$internalConstructor=5,3,0|new3|const QUrl &,QWidget *=0

//[1]explicit QQuickWidget(QWidget *parent = 0)
//[2]QQuickWidget(QQmlEngine* engine, QWidget *parent)
//[3]QQuickWidget(const QUrl &source, QWidget *parent = 0)

HB_FUNC_STATIC( QQUICKWIDGET_NEW )
{
#if (QT_VERSION >= QT_VERSION_CHECK(5,3,0))
  if( ISBETWEEN(0,1) && ISOPTQWIDGET(1) )
  {
    QQuickWidget_new1();
  }
  else if( ISNUMPAR(2) && ISQQMLENGINE(1) && ISQWIDGET(2) )
  {
    QQuickWidget_new2();
  }
  else if( ISBETWEEN(1,2) && ISQURL(1) && ISOPTQWIDGET(2) )
  {
    QQuickWidget_new3();
  }
  else
  {
    hb_errRT_BASE( EG_ARG, 3012, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
  }
#endif
}

$deleteMethod=5,3,0

$prototype=QUrl source() const
$method=5,3,0|QUrl|source|

$prototype=void setSource(const QUrl&)
$method=5,3,0|void|setSource|const QUrl &

$prototype=QQmlEngine* engine() const
$method=5,3,0|QQmlEngine *|engine|

$prototype=QQmlContext* rootContext() const
$method=5,3,0|QQmlContext *|rootContext|

$prototype=QQuickItem *rootObject() const
$method=5,3,0|QQuickItem *|rootObject|

$prototype=ResizeMode resizeMode() const
$method=5,3,0|QQuickWidget::ResizeMode|resizeMode|

$prototype=void setResizeMode(ResizeMode)
$method=5,3,0|void|setResizeMode|QQuickWidget::ResizeMode

$prototype=Status status() const
$method=5,3,0|QQuickWidget::Status|status|

$prototype=QList<QQmlError> errors() const
$method=5,3,0|QList<QQmlError>|errors|

$prototype=QSize sizeHint() const
$method=5,3,0|QSize|sizeHint|

$prototype=QSize initialSize() const
$method=5,3,0|QSize|initialSize|

$prototype=void setContent(const QUrl& url, QQmlComponent *component, QObject *item)
$method=5,3,0|void|setContent|const QUrl &,QQmlComponent *,QObject *

$prototype=QSurfaceFormat format() const
$method=5,3,0|QSurfaceFormat|format|

$prototype=void setFormat(const QSurfaceFormat &format)
$method=5,3,0|void|setFormat|const QSurfaceFormat &

$beginSignals
$signalMethod=5,3,0|statusChanged(QQuickWidget::Status)
$signalMethod=5,3,0|sceneGraphError(QQuickWindow::SceneGraphError,QString)
$endSignals

#pragma ENDDUMP

%%
%% Qt5xHb - Bindings libraries for Harbour/xHarbour and Qt Framework 5
%%
%% Copyright (C) 2018 Marcos Antonio Gambeta <marcosgambeta AT outlook DOT com>
%%

$header

#include "hbclass.ch"

#ifndef QT5XHB_NO_REQUESTS
REQUEST QURL
REQUEST QQMLENGINE
REQUEST QQMLCONTEXT
REQUEST QQUICKITEM
REQUEST QQMLERROR
REQUEST QSIZE
REQUEST QSURFACEFORMAT
#endif

CLASS QQuickWidget INHERIT QWidget

   METHOD new
   METHOD delete
   METHOD source
   METHOD setSource
   METHOD engine
   METHOD rootContext
   METHOD rootObject
   METHOD resizeMode
   METHOD setResizeMode
   METHOD status
   METHOD errors
   METHOD sizeHint
   METHOD initialSize
   METHOD setContent
   METHOD format
   METHOD setFormat

   METHOD onStatusChanged
   METHOD onSceneGraphError

   DESTRUCTOR destroyObject

END CLASS

$destructor

#pragma BEGINDUMP

$includes=5,3,0

#include <QQmlError>
#include <QQmlEngine>
#include <QQmlContext>
#include <QQuickItem>

$prototype=explicit QQuickWidget(QWidget *parent = 0)
$internalConstructor=5,3,0|new1|QWidget *=0

$prototype=QQuickWidget(QQmlEngine* engine, QWidget *parent)
$internalConstructor=5,3,0|new2|QQmlEngine *,QWidget *

$prototype=QQuickWidget(const QUrl &source, QWidget *parent = 0)
$internalConstructor=5,3,0|new3|const QUrl &,QWidget *=0

//[1]explicit QQuickWidget(QWidget *parent = 0)
//[2]QQuickWidget(QQmlEngine* engine, QWidget *parent)
//[3]QQuickWidget(const QUrl &source, QWidget *parent = 0)

HB_FUNC_STATIC( QQUICKWIDGET_NEW )
{
#if (QT_VERSION >= QT_VERSION_CHECK(5,3,0))
  if( ISBETWEEN(0,1) && ISOPTQWIDGET(1) )
  {
    QQuickWidget_new1();
  }
  else if( ISNUMPAR(2) && ISQQMLENGINE(1) && ISQWIDGET(2) )
  {
    QQuickWidget_new2();
  }
  else if( ISBETWEEN(1,2) && ISQURL(1) && ISOPTQWIDGET(2) )
  {
    QQuickWidget_new3();
  }
  else
  {
    hb_errRT_BASE( EG_ARG, 3012, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
  }
#endif
}

$deleteMethod=5,3,0

$prototype=QUrl source() const
$method=5,3,0|QUrl|source|

$prototype=void setSource(const QUrl&)
$method=5,3,0|void|setSource|const QUrl &

$prototype=QQmlEngine* engine() const
$method=5,3,0|QQmlEngine *|engine|

$prototype=QQmlContext* rootContext() const
$method=5,3,0|QQmlContext *|rootContext|

$prototype=QQuickItem *rootObject() const
$method=5,3,0|QQuickItem *|rootObject|

$prototype=ResizeMode resizeMode() const
$method=5,3,0|QQuickWidget::ResizeMode|resizeMode|

$prototype=void setResizeMode(ResizeMode)
$method=5,3,0|void|setResizeMode|QQuickWidget::ResizeMode

$prototype=Status status() const
$method=5,3,0|QQuickWidget::Status|status|

$prototype=QList<QQmlError> errors() const
$method=5,3,0|QList<QQmlError>|errors|

$prototype=QSize sizeHint() const
$method=5,3,0|QSize|sizeHint|

$prototype=QSize initialSize() const
$method=5,3,0|QSize|initialSize|

$prototype=void setContent(const QUrl& url, QQmlComponent *component, QObject *item)
$method=5,3,0|void|setContent|const QUrl &,QQmlComponent *,QObject *

$prototype=QSurfaceFormat format() const
$method=5,3,0|QSurfaceFormat|format|

$prototype=void setFormat(const QSurfaceFormat &format)
$method=5,3,0|void|setFormat|const QSurfaceFormat &

$connectSignalFunction

$signalMethod=5,3,0|statusChanged(QQuickWidget::Status)
$signalMethod=5,3,0|sceneGraphError(QQuickWindow::SceneGraphError,QString)

#pragma ENDDUMP


level variable may enter into a star

level variable may enter into a star

-- parametric HOAS (PHOAS) representation of terms
-- advocated by Chipala and B. Oliveira
--

data Ptm :: * ~> * ~> * where
  Var :: a -> Ptm a l
  Lam :: (a -> Ptm a l) -> Ptm a l
  Lev :: (l -> Ptm a l) -> Ptm a l
  App :: Ptm a l -> Ptm a l -> Ptm a l
  Star :: l -> Ptm a l

data Tm = Tm (forall a l . Ptm a (Nat' l))

-- illegal
--
##test "not parametric"
 ill = Tm (Lam (\a -> a + 2))

##test "not parametric: expr var in level context"
 ill = Tm (Lev (\a -> App (Var a) (Var a)))

-- this is parametric
--
leg = Tm (Lam (\a -> App (Var a) (Var a)))

-- parametric HOAS (PHOAS) representation of terms
-- advocated by Chipala and B. Oliveira
--

data Ptm :: * ~> * ~> * where
  Var :: a -> Ptm a l
  Lam :: (a -> Ptm a l) -> Ptm a l
  Lev :: (l -> Ptm  a l) -> Ptm a l
  App :: Ptm a l -> Ptm a l -> Ptm a l

data Tm = Tm (forall a l . Ptm a l)

-- illegal
--
##test "not parametric"
 ill = Tm (Lam (\a -> a + 2))

##test "not parametric: expr var in level context"
 ill = Tm (Lev (\a -> App (Var a) (Var a)))

-- this is parametric
--
leg = Tm (Lam (\a -> App (Var a) (Var a)))


[rdd/dbf] Shared input buffer instance (minor fix)

//
// Copyright (c) XSharp B.V.  All Rights Reserved.
// Licensed under the Apache License, Version 2.0.
// See License.txt in the project root for license information.
//

// Please note that this code code expects zero based arrays
#pragma options ("az", ON)

USING System
USING System.Collections.Generic
USING System.Text
USING System.IO
USING XSharp.RDD.Enums
USING XSharp.RDD.Support

BEGIN NAMESPACE XSharp.RDD

	CLASS InputBuffer
        CONST INBUFFER_MAX_SIZE := 16384 AS INT

        PROTECT _stream        AS Stream
        PROTECT _name          AS STRING
        PROTECT _recordLength  AS LONG
        PROTECT _headerLength  AS LONG
        PROTECT _shared        AS LOGIC

        PROTECT _look_ahead    AS INT
        PROTECT _look_behind   AS INT
        PROTECT _inBuffer      AS BYTE[]
        PROTECT _inBufferOfs   AS LONG
        PROTECT _inBufferLen   AS LONG
        PROTECT _inBufferTick  AS INT

        CLASS WeakBuffer
            INTERNAL RefCount := 1 AS WORD
            INTERNAL Buffer AS BYTE[]
            CONSTRUCTOR(size AS LONG)
                Buffer := BYTE[]{size}
            INTERNAL METHOD Resize(size AS LONG) AS VOID
                System.Array.Resize(REF Buffer, size)
        END CLASS

        PRIVATE STATIC BufferCache := Dictionary<STRING, WeakBuffer>{} AS Dictionary<STRING, WeakBuffer>

        CONSTRUCTOR(stream AS Stream, headerLength AS INT, recordLength AS INT, shared AS LOGIC) AS VOID
            _stream := stream
            _name := (stream ASTYPE FileStream)?:Name
            _recordLength := recordLength
            _headerLength := headerLength
            _shared := shared
            _inBufferOfs := 0
            _inBufferLen := 0

            VAR nRec := INBUFFER_MAX_SIZE / SELF:_recordLength
            _look_ahead := nRec - nRec/4
            _look_behind := nRec - _look_ahead - 1

            IF _look_ahead > 0 && _look_behind >= 0
                IF _name != NULL
                    BEGIN LOCK BufferCache
                        LOCAL t AS WeakBuffer
                        VAR size := (1+SELF:_look_ahead+SELF:_look_behind)*SELF:_recordLength
                        IF BufferCache:TryGetValue(_name, OUT t)
                            t:RefCount += 1
                            IF size != t:Buffer:Length
                                t:Resize(size)
                            ENDIF
                        ELSE
                            t := WeakBuffer{size}
                            BufferCache:Add(_name, t)
                        ENDIF
                        _inBuffer := t:Buffer
                    END LOCK
                ELSE
                    _inBuffer := BYTE[]{(1+SELF:_look_ahead+SELF:_look_behind)*SELF:_recordLength}
                ENDIF
            ELSE
                _inBuffer := NULL
            ENDIF

            RETURN

        DESTRUCTOR()
                IF _name != NULL
                    BEGIN LOCK BufferCache
                        LOCAL t AS WeakBuffer
                        IF BufferCache:TryGetValue(_name, OUT t)
                            t:RefCount -= 1
                            IF t:RefCount < 1
                                BufferCache:Remove(_name)
                            ENDIF
                        ENDIF
                    END LOCK
                ENDIF
            RETURN

        PRIVATE METHOD ReadAt(position AS LONG, buffer AS BYTE[], offset AS LONG, length AS LONG) AS LONG
            LOCAL result AS LONG
            TRY
                _stream:Position := position
                result := _stream:Read(buffer, offset, length)
            CATCH
                result := -1
            END TRY
            RETURN result

        PRIVATE METHOD WriteAt(position AS LONG, buffer AS BYTE[], offset AS LONG, length AS LONG) AS LOGIC
            LOCAL result AS LOGIC
            TRY
                _stream:Position := position
                _stream:Write(buffer, offset, length)
                result := TRUE
            CATCH
                result := FALSE
            END TRY
            RETURN result

        METHOD Read(offset AS LONG, buffer AS BYTE[], size AS LONG) AS LOGIC
            LOCAL tick := 0 AS INT
            IF _inBuffer == NULL
                RETURN SELF:ReadAt(offset, buffer, 0, size) == size
            ENDIF
            IF SELF:_shared
                VAR refresh := XSharp.RuntimeState.GetValue<REAL8>(Set.Refresh)
                IF refresh < 0
                    RETURN SELF:ReadAt(offset, buffer, 0, size) == size
                ENDIF
                tick := System.Environment.TickCount
                IF refresh > 0 .AND. (tick - _inBufferTick) >= 1000*refresh
                    _inBufferLen := 0
                ENDIF
            ENDIF
            IF _inBufferOfs > offset .OR. _inBufferOfs+_inBufferLen < offset+size
                LOCAL ofs AS LONG
                IF offset > _inBufferOfs
                    ofs := offset - SELF:_look_behind*SELF:_recordLength
                ELSE
                    ofs := offset - SELF:_look_ahead*SELF:_recordLength
                ENDIF
                IF ofs < SELF:_headerLength
                    ofs := SELF:_headerLength
                ENDIF
                VAR len := _inBuffer:Length
                VAR bwd := FALSE
                IF ofs > _inBufferOfs .AND. ofs < _inBufferOfs+_inBufferLen
                    VAR delta := ofs - _inBufferOfs
                    _inBufferLen -= delta
                    _inBufferOfs := ofs
                    ofs += _inBufferLen
                    len -= _inBufferLen
                    Array.Copy(_inBuffer, delta, _inBuffer, 0, _inBufferLen)
                ELSEIF ofs < _inBufferOfs .AND. ofs+len > _inBufferOfs .AND. _inBufferLen > 0
                    VAR delta := _inBufferOfs - ofs
                    IF _inBufferLen+delta > len
                        _inBufferLen -= _inBufferLen + delta - len
                    ENDIF
                    _inBufferOfs := ofs
                    len := delta
                    bwd := TRUE
                    Array.Copy(_inBuffer, 0, _inBuffer, delta, _inBufferLen)
                ELSE
                    _inBufferLen := 0
                    _inBufferOfs := ofs
                ENDIF

                _inBufferTick := tick
                VAR res := SELF:ReadAt(ofs, _inBuffer, ofs-_inBufferOfs, len)
                IF res > 0
                    _inBufferLen += res
                    IF bwd .AND. res != len
                        _inBufferLen := res
                    ENDIF
                ELSE
                    _inBufferLen := 0
                ENDIF

                IF _inBufferOfs+_inBufferLen < offset+size
                    RETURN FALSE
                ENDIF
            ENDIF
            Array.Copy( _inBuffer, offset - _inBufferOfs, buffer, 0, size )
            RETURN TRUE

        METHOD Write(offset AS LONG, buffer AS BYTE[], size AS LONG) AS LOGIC
            VAR res := SELF:WriteAt(offset, buffer, 0, size)
            IF res .AND. _inBuffer != NULL
                IF offset <= _inBufferOfs+_inBufferLen .AND. offset+size >= _inBufferOfs
                    VAR buffer_ofs := Math.Max( 0, _inBufferOfs - offset )
                    Array.Copy( buffer, buffer_ofs, _inBuffer, Math.Max( 0, offset - _inBufferOfs), size - buffer_ofs )
                ENDIF
            ENDIF
            RETURN res

        METHOD Invalidate() AS VOID
            _inBufferOfs := 0
            _inBufferLen := 0
            RETURN
    END CLASS

END NAMESPACE // XSharp.RDD

//
// Copyright (c) XSharp B.V.  All Rights Reserved.
// Licensed under the Apache License, Version 2.0.
// See License.txt in the project root for license information.
//

// Please note that this code code expects zero based arrays
#pragma options ("az", ON)

USING System
USING System.Collections.Generic
USING System.Text
USING System.IO
USING XSharp.RDD.Enums
USING XSharp.RDD.Support

BEGIN NAMESPACE XSharp.RDD

	CLASS InputBuffer
        CONST INBUFFER_MAX_SIZE := 16384 AS INT

        PROTECT _stream        AS Stream
        PROTECT _name          AS STRING
        PROTECT _recordLength  AS LONG
        PROTECT _headerLength  AS LONG
        PROTECT _shared        AS LOGIC

        PROTECT _look_ahead    AS INT
        PROTECT _look_behind   AS INT
        PROTECT _inBuffer      AS BYTE[]
        PROTECT _inBufferOfs   AS LONG
        PROTECT _inBufferLen   AS LONG
        PROTECT _inBufferTick  AS INT

        CLASS WeakBuffer
            INTERNAL RefCount := 1 AS WORD
            INTERNAL Buffer AS BYTE[]
            CONSTRUCTOR(size AS LONG)
                Buffer := BYTE[]{size}
            INTERNAL METHOD Resize(size AS LONG) AS VOID
                System.Array.Resize(REF Buffer, size)
        END CLASS

        PRIVATE STATIC BufferCache := Dictionary<STRING, WeakBuffer>{} AS Dictionary<STRING, WeakBuffer>

        CONSTRUCTOR(stream AS Stream, headerLength AS INT, recordLength AS INT, shared AS LOGIC) AS VOID
            _stream := stream
            _name := (stream ASTYPE FileStream)?:Name
            _recordLength := recordLength
            _headerLength := headerLength
            _shared := shared
            _inBufferOfs := 0
            _inBufferLen := 0

            VAR nRec := INBUFFER_MAX_SIZE / SELF:_recordLength
            _look_ahead := nRec - nRec/4
            _look_behind := nRec - _look_ahead - 1

            IF _look_ahead > 0 && _look_behind >= 0
                IF _name != NULL
                    BEGIN LOCK BufferCache
                        LOCAL t AS WeakBuffer
                        VAR size := (1+SELF:_look_ahead+SELF:_look_behind)*SELF:_recordLength
                        IF BufferCache:TryGetValue(_name, OUT t)
                            t:RefCount += 1
                            IF size != t:Buffer:Length
                                t:Resize(size)
                            ENDIF
                        ELSE
                            t := WeakBuffer{size}
                            BufferCache:Add(_name, t)
                        ENDIF
                        _inBuffer := t:Buffer
                    END LOCK
                ELSE
                    _inBuffer := BYTE[]{(1+SELF:_look_ahead+SELF:_look_behind)*SELF:_recordLength}
                ENDIF
            ELSE
                _inBuffer := NULL
            ENDIF

            RETURN

        DESTRUCTOR()
                VAR fs := _stream ASTYPE FileStream
                IF fs != NULL
                    BEGIN LOCK BufferCache
                        LOCAL t AS WeakBuffer
                        IF BufferCache:TryGetValue(_name, OUT t)
                            t:RefCount -= 1
                            IF t:RefCount < 1
                                BufferCache:Remove(_name)
                            ENDIF
                        ENDIF
                    END LOCK
                ENDIF
            RETURN

        PRIVATE METHOD ReadAt(position AS LONG, buffer AS BYTE[], offset AS LONG, length AS LONG) AS LONG
            LOCAL result AS LONG
            TRY
                _stream:Position := position
                result := _stream:Read(buffer, offset, length)
            CATCH
                result := -1
            END TRY
            RETURN result

        PRIVATE METHOD WriteAt(position AS LONG, buffer AS BYTE[], offset AS LONG, length AS LONG) AS LOGIC
            LOCAL result AS LOGIC
            TRY
                _stream:Position := position
                _stream:Write(buffer, offset, length)
                result := TRUE
            CATCH
                result := FALSE
            END TRY
            RETURN result

        METHOD Read(offset AS LONG, buffer AS BYTE[], size AS LONG) AS LOGIC
            LOCAL tick := 0 AS INT
            IF _inBuffer == NULL
                RETURN SELF:ReadAt(offset, buffer, 0, size) == size
            ENDIF
            IF SELF:_shared
                VAR refresh := XSharp.RuntimeState.GetValue<REAL8>(Set.Refresh)
                IF refresh < 0
                    RETURN SELF:ReadAt(offset, buffer, 0, size) == size
                ENDIF
                tick := System.Environment.TickCount
                IF refresh > 0 .AND. (tick - _inBufferTick) >= 1000*refresh
                    _inBufferLen := 0
                ENDIF
            ENDIF
            IF _inBufferOfs > offset .OR. _inBufferOfs+_inBufferLen < offset+size
                LOCAL ofs AS LONG
                IF offset > _inBufferOfs
                    ofs := offset - SELF:_look_behind*SELF:_recordLength
                ELSE
                    ofs := offset - SELF:_look_ahead*SELF:_recordLength
                ENDIF
                IF ofs < SELF:_headerLength
                    ofs := SELF:_headerLength
                ENDIF
                VAR len := _inBuffer:Length
                VAR bwd := FALSE
                IF ofs > _inBufferOfs .AND. ofs < _inBufferOfs+_inBufferLen
                    VAR delta := ofs - _inBufferOfs
                    _inBufferLen -= delta
                    _inBufferOfs := ofs
                    ofs += _inBufferLen
                    len -= _inBufferLen
                    Array.Copy(_inBuffer, delta, _inBuffer, 0, _inBufferLen)
                ELSEIF ofs < _inBufferOfs .AND. ofs+len > _inBufferOfs .AND. _inBufferLen > 0
                    VAR delta := _inBufferOfs - ofs
                    IF _inBufferLen+delta > len
                        _inBufferLen -= _inBufferLen + delta - len
                    ENDIF
                    _inBufferOfs := ofs
                    len := delta
                    bwd := TRUE
                    Array.Copy(_inBuffer, 0, _inBuffer, delta, _inBufferLen)
                ELSE
                    _inBufferLen := 0
                    _inBufferOfs := ofs
                ENDIF

                _inBufferTick := tick
                VAR res := SELF:ReadAt(ofs, _inBuffer, ofs-_inBufferOfs, len)
                IF res > 0
                    _inBufferLen += res
                    IF bwd .AND. res != len
                        _inBufferLen := res
                    ENDIF
                ELSE
                    _inBufferLen := 0
                ENDIF

                IF _inBufferOfs+_inBufferLen < offset+size
                    RETURN FALSE
                ENDIF
            ENDIF
            Array.Copy( _inBuffer, offset - _inBufferOfs, buffer, 0, size )
            RETURN TRUE

        METHOD Write(offset AS LONG, buffer AS BYTE[], size AS LONG) AS LOGIC
            VAR res := SELF:WriteAt(offset, buffer, 0, size)
            IF res .AND. _inBuffer != NULL
                IF offset <= _inBufferOfs+_inBufferLen .AND. offset+size >= _inBufferOfs
                    VAR buffer_ofs := Math.Max( 0, _inBufferOfs - offset )
                    Array.Copy( buffer, buffer_ofs, _inBuffer, Math.Max( 0, offset - _inBufferOfs), size - buffer_ofs )
                ENDIF
            ENDIF
            RETURN res

        METHOD Invalidate() AS VOID
            _inBufferOfs := 0
            _inBufferLen := 0
            RETURN
    END CLASS

END NAMESPACE // XSharp.RDD