Separate Visual Basic into VB.NET, VBA/VB6 and VBScript (#4725)

* Fix for #2418 (WIP)

* Fix for #2418 (WIP)

* Remove mistaken aliases

* Sort language names; add/move samples

* Fix language order; update VBScipt color

* Update colors

* Update VBA/VB6 color

* Reorder languages

* PR fixes

* Rename VBA to Visual Basic for Applications

* Update language IDs; go back to acronym

* Fixes for failing tests
This commit is contained in:
Zev Spitz 2019-12-05 11:50:39 +02:00 коммит произвёл Colin Seymour
Родитель 38a2219f41
Коммит 7fa8ca2836
12 изменённых файлов: 1301 добавлений и 13 удалений

Просмотреть файл

@ -462,7 +462,7 @@ disambiguations:
rules:
- language: Vim script
pattern: '^UseVimball'
- language: Visual Basic
- language: VBA
- extensions: ['.w']
rules:
- language: OpenEdge ABL

Просмотреть файл

@ -5492,6 +5492,34 @@ V:
codemirror_mode: go
codemirror_mime_type: text/x-go
language_id: 603371597
VBA:
type: programming
color: "#867db1"
extensions:
- ".bas"
- ".cls"
- ".frm"
- ".frx"
- ".vba"
tm_scope: source.vbnet
aliases:
- vb6
- visual basic 6
- visual basic for applications
ace_mode: text
codemirror_mode: vb
codemirror_mime_type: text/x-vb
language_id: 399230729
VBScript:
type: programming
color: "#15dcdc"
extensions:
- ".vbs"
tm_scope: source.vbnet
ace_mode: text
codemirror_mode: vbscript
codemirror_mime_type: text/vbscript
language_id: 408016005
VCL:
type: programming
color: "#148AA8"
@ -5573,22 +5601,18 @@ Vim script:
- vimrc
ace_mode: text
language_id: 388
Visual Basic:
Visual Basic .NET:
type: programming
color: "#945db7"
extensions:
- ".vb"
- ".bas"
- ".cls"
- ".frm"
- ".frx"
- ".vba"
- ".vbhtml"
- ".vbs"
tm_scope: source.vbnet
aliases:
- vb.net
- visual basic
- vbnet
- vb .net
- vb.net
tm_scope: source.vbnet
ace_mode: text
codemirror_mode: vb
codemirror_mime_type: text/x-vb

Просмотреть файл

474
samples/VBA/dictionary.cls Normal file
Просмотреть файл

@ -0,0 +1,474 @@
VERSION 1.0 CLASS
BEGIN
MultiUse = -1 'True
END
Attribute VB_Name = "Dictionary"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = False
Attribute VB_PredeclaredId = False
Attribute VB_Exposed = True
Attribute VB_Description = "Drop-in replacement for Scripting.Dictionary on Mac\r\n\r\nDictionary v1.4.0\r\n(c) Tim Hall - https://github.com/timhall/VBA-Dictionary\r\nAuthor: tim.hall.engr@gmail.com\r\nLicense: MIT (http://www.opensource.org/licenses/mit-license.php)\r\n"
''
' Dictionary v1.4.1
' (c) Tim Hall - https://github.com/timhall/VBA-Dictionary
'
' Drop-in replacement for Scripting.Dictionary on Mac
'
' @author: tim.hall.engr@gmail.com
' @license: MIT (http://www.opensource.org/licenses/mit-license.php
'
' ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ '
Option Explicit
' --------------------------------------------- '
' Constants and Private Variables
' --------------------------------------------- '
#Const UseScriptingDictionaryIfAvailable = True
#If Mac Or Not UseScriptingDictionaryIfAvailable Then
' dict_KeyValue 0: FormattedKey, 1: OriginalKey, 2: Value
Private dict_pKeyValues As Collection
Private dict_pKeys() As Variant
Private dict_pItems() As Variant
Private dict_pObjectKeys As Collection
Private dict_pCompareMode As CompareMethod
#Else
Private dict_pDictionary As Object
#End If
' --------------------------------------------- '
' Types
' --------------------------------------------- '
Public Enum CompareMethod
BinaryCompare = VBA.vbBinaryCompare
TextCompare = VBA.vbTextCompare
DatabaseCompare = VBA.vbDatabaseCompare
End Enum
' --------------------------------------------- '
' Properties
' --------------------------------------------- '
Public Property Get CompareMode() As CompareMethod
Attribute CompareMode.VB_Description = "Set or get the string comparison method."
#If Mac Or Not UseScriptingDictionaryIfAvailable Then
CompareMode = dict_pCompareMode
#Else
CompareMode = dict_pDictionary.CompareMode
#End If
End Property
Public Property Let CompareMode(Value As CompareMethod)
#If Mac Or Not UseScriptingDictionaryIfAvailable Then
If Me.Count > 0 Then
' Can't change CompareMode for Dictionary that contains data
' http://msdn.microsoft.com/en-us/library/office/gg278481(v=office.15).aspx
Err.Raise 5 ' Invalid procedure call or argument
End If
dict_pCompareMode = Value
#Else
dict_pDictionary.CompareMode = Value
#End If
End Property
Public Property Get Count() As Long
Attribute Count.VB_Description = "Get the number of items in the dictionary.\n"
#If Mac Or Not UseScriptingDictionaryIfAvailable Then
Count = dict_pKeyValues.Count
#Else
Count = dict_pDictionary.Count
#End If
End Property
Public Property Get Item(Key As Variant) As Variant
Attribute Item.VB_Description = "Set or get the item for a given key."
Attribute Item.VB_UserMemId = 0
#If Mac Or Not UseScriptingDictionaryIfAvailable Then
Dim dict_KeyValue As Variant
dict_KeyValue = dict_GetKeyValue(Key)
If Not IsEmpty(dict_KeyValue) Then
If VBA.IsObject(dict_KeyValue(2)) Then
Set Item = dict_KeyValue(2)
Else
Item = dict_KeyValue(2)
End If
Else
' Not found -> Returns Empty
End If
#Else
If VBA.IsObject(dict_pDictionary.Item(Key)) Then
Set Item = dict_pDictionary.Item(Key)
Else
Item = dict_pDictionary.Item(Key)
End If
#End If
End Property
Public Property Let Item(Key As Variant, Value As Variant)
#If Mac Or Not UseScriptingDictionaryIfAvailable Then
If Me.Exists(Key) Then
dict_ReplaceKeyValue dict_GetKeyValue(Key), Key, Value
Else
dict_AddKeyValue Key, Value
End If
#Else
dict_pDictionary.Item(Key) = Value
#End If
End Property
Public Property Set Item(Key As Variant, Value As Variant)
#If Mac Or Not UseScriptingDictionaryIfAvailable Then
If Me.Exists(Key) Then
dict_ReplaceKeyValue dict_GetKeyValue(Key), Key, Value
Else
dict_AddKeyValue Key, Value
End If
#Else
Set dict_pDictionary.Item(Key) = Value
#End If
End Property
Public Property Let Key(Previous As Variant, Updated As Variant)
Attribute Key.VB_Description = "Change a key to a different key."
#If Mac Or Not UseScriptingDictionaryIfAvailable Then
Dim dict_KeyValue As Variant
dict_KeyValue = dict_GetKeyValue(Previous)
If Not VBA.IsEmpty(dict_KeyValue) Then
dict_ReplaceKeyValue dict_KeyValue, Updated, dict_KeyValue(2)
End If
#Else
dict_pDictionary.Key(Previous) = Updated
#End If
End Property
' ============================================= '
' Public Methods
' ============================================= '
''
' Add an item with the given key
'
' @param {Variant} Key
' @param {Variant} Item
' --------------------------------------------- '
Public Sub Add(Key As Variant, Item As Variant)
Attribute Add.VB_Description = "Add a new key and item to the dictionary."
#If Mac Or Not UseScriptingDictionaryIfAvailable Then
If Not Me.Exists(Key) Then
dict_AddKeyValue Key, Item
Else
' This key is already associated with an element of this collection
Err.Raise 457
End If
#Else
dict_pDictionary.Add Key, Item
#End If
End Sub
''
' Check if an item exists for the given key
'
' @param {Variant} Key
' @return {Boolean}
' --------------------------------------------- '
Public Function Exists(Key As Variant) As Boolean
Attribute Exists.VB_Description = "Determine if a given key is in the dictionary."
#If Mac Or Not UseScriptingDictionaryIfAvailable Then
Exists = Not IsEmpty(dict_GetKeyValue(Key))
#Else
Exists = dict_pDictionary.Exists(Key)
#End If
End Function
''
' Get an array of all items
'
' @return {Variant}
' --------------------------------------------- '
Public Function Items() As Variant
Attribute Items.VB_Description = "Get an array containing all items in the dictionary."
#If Mac Or Not UseScriptingDictionaryIfAvailable Then
If Me.Count > 0 Then
Items = dict_pItems
Else
' Split("") creates initialized empty array that matches Dictionary Keys and Items
Items = VBA.Split("")
End If
#Else
Items = dict_pDictionary.Items
#End If
End Function
''
' Get an array of all keys
'
' @return {Variant}
' --------------------------------------------- '
Public Function Keys() As Variant
Attribute Keys.VB_Description = "Get an array containing all keys in the dictionary."
#If Mac Or Not UseScriptingDictionaryIfAvailable Then
If Me.Count > 0 Then
Keys = dict_pKeys
Else
' Split("") creates initialized empty array that matches Dictionary Keys and Items
Keys = VBA.Split("")
End If
#Else
Keys = dict_pDictionary.Keys
#End If
End Function
''
' Remove an item for the given key
'
' @param {Variant} Key
' --------------------------------------------- '
Public Sub Remove(Key As Variant)
Attribute Remove.VB_Description = "Remove a given key from the dictionary."
#If Mac Or Not UseScriptingDictionaryIfAvailable Then
Dim dict_KeyValue As Variant
dict_KeyValue = dict_GetKeyValue(Key)
If Not VBA.IsEmpty(dict_KeyValue) Then
dict_RemoveKeyValue dict_KeyValue
Else
' Application-defined or object-defined error
Err.Raise 32811
End If
#Else
dict_pDictionary.Remove Key
#End If
End Sub
''
' Remove all items
' --------------------------------------------- '
Public Sub RemoveAll()
Attribute RemoveAll.VB_Description = "Remove all information from the dictionary."
#If Mac Or Not UseScriptingDictionaryIfAvailable Then
Set dict_pKeyValues = New Collection
Erase dict_pKeys
Erase dict_pItems
#Else
dict_pDictionary.RemoveAll
#End If
End Sub
' ============================================= '
' Private Functions
' ============================================= '
#If Mac Or Not UseScriptingDictionaryIfAvailable Then
Private Function dict_GetKeyValue(dict_Key As Variant) As Variant
On Error Resume Next
dict_GetKeyValue = dict_pKeyValues(dict_GetFormattedKey(dict_Key))
Err.Clear
End Function
Private Sub dict_AddKeyValue(dict_Key As Variant, dict_Value As Variant, Optional dict_Index As Long = -1)
If Me.Count = 0 Then
ReDim dict_pKeys(0 To 0)
ReDim dict_pItems(0 To 0)
Else
ReDim Preserve dict_pKeys(0 To UBound(dict_pKeys) + 1)
ReDim Preserve dict_pItems(0 To UBound(dict_pItems) + 1)
End If
Dim dict_FormattedKey As String
dict_FormattedKey = dict_GetFormattedKey(dict_Key)
If dict_Index >= 0 And dict_Index < dict_pKeyValues.Count Then
' Shift keys/items after + including index into empty last slot
Dim dict_i As Long
For dict_i = UBound(dict_pKeys) To dict_Index + 1 Step -1
dict_pKeys(dict_i) = dict_pKeys(dict_i - 1)
If VBA.IsObject(dict_pItems(dict_i - 1)) Then
Set dict_pItems(dict_i) = dict_pItems(dict_i - 1)
Else
dict_pItems(dict_i) = dict_pItems(dict_i - 1)
End If
Next dict_i
' Add key/item at index
dict_pKeys(dict_Index) = dict_Key
If VBA.IsObject(dict_Value) Then
Set dict_pItems(dict_Index) = dict_Value
Else
dict_pItems(dict_Index) = dict_Value
End If
' Add key-value at proper index
dict_pKeyValues.Add Array(dict_FormattedKey, dict_Key, dict_Value), dict_FormattedKey, Before:=dict_Index + 1
Else
' Add key-value as last item
If VBA.IsObject(dict_Key) Then
Set dict_pKeys(UBound(dict_pKeys)) = dict_Key
Else
dict_pKeys(UBound(dict_pKeys)) = dict_Key
End If
If VBA.IsObject(dict_Value) Then
Set dict_pItems(UBound(dict_pItems)) = dict_Value
Else
dict_pItems(UBound(dict_pItems)) = dict_Value
End If
dict_pKeyValues.Add Array(dict_FormattedKey, dict_Key, dict_Value), dict_FormattedKey
End If
End Sub
Private Sub dict_ReplaceKeyValue(dict_KeyValue As Variant, dict_Key As Variant, dict_Value As Variant)
Dim dict_Index As Long
Dim dict_i As Integer
dict_Index = dict_GetKeyIndex(dict_KeyValue(1))
' Remove existing dict_Value
dict_RemoveKeyValue dict_KeyValue, dict_Index
' Add new dict_Key dict_Value back
dict_AddKeyValue dict_Key, dict_Value, dict_Index
End Sub
Private Sub dict_RemoveKeyValue(dict_KeyValue As Variant, Optional ByVal dict_Index As Long = -1)
Dim dict_i As Long
If dict_Index = -1 Then
dict_Index = dict_GetKeyIndex(dict_KeyValue(1))
End If
If dict_Index >= 0 And dict_Index <= UBound(dict_pKeys) Then
' Shift keys/items after index down
For dict_i = dict_Index To UBound(dict_pKeys) - 1
dict_pKeys(dict_i) = dict_pKeys(dict_i + 1)
If VBA.IsObject(dict_pItems(dict_i + 1)) Then
Set dict_pItems(dict_i) = dict_pItems(dict_i + 1)
Else
dict_pItems(dict_i) = dict_pItems(dict_i + 1)
End If
Next dict_i
' Resize keys/items to remove empty slot
If UBound(dict_pKeys) = 0 Then
Erase dict_pKeys
Erase dict_pItems
Else
ReDim Preserve dict_pKeys(0 To UBound(dict_pKeys) - 1)
ReDim Preserve dict_pItems(0 To UBound(dict_pItems) - 1)
End If
End If
dict_pKeyValues.Remove dict_KeyValue(0)
dict_RemoveObjectKey dict_KeyValue(1)
End Sub
Private Function dict_GetFormattedKey(dict_Key As Variant) As String
If VBA.IsObject(dict_Key) Then
dict_GetFormattedKey = dict_GetObjectKey(dict_Key)
ElseIf VarType(dict_Key) = VBA.vbBoolean Then
dict_GetFormattedKey = IIf(dict_Key, "-1__-1", "0__0")
ElseIf VarType(dict_Key) = VBA.vbString Then
dict_GetFormattedKey = dict_Key
If Me.CompareMode = CompareMethod.BinaryCompare Then
' Collection does not have method of setting key comparison
' So case-sensitive keys aren't supported by default
' -> Approach: Append lowercase characters to original key
' AbC -> AbC___b_, abc -> abc__abc, ABC -> ABC_____
Dim dict_Lowercase As String
dict_Lowercase = ""
Dim dict_i As Integer
Dim dict_Char As String
Dim dict_Ascii As Integer
For dict_i = 1 To VBA.Len(dict_GetFormattedKey)
dict_Char = VBA.Mid$(dict_GetFormattedKey, dict_i, 1)
dict_Ascii = VBA.Asc(dict_Char)
If dict_Ascii >= 97 And dict_Ascii <= 122 Then
dict_Lowercase = dict_Lowercase & dict_Char
Else
dict_Lowercase = dict_Lowercase & "_"
End If
Next dict_i
If dict_Lowercase <> "" Then
dict_GetFormattedKey = dict_GetFormattedKey & "__" & dict_Lowercase
End If
End If
Else
' For numbers, add duplicate to distinguish from strings
' -> 123 -> "123__123"
' "123" -> "123"
dict_GetFormattedKey = VBA.CStr(dict_Key) & "__" & CStr(dict_Key)
End If
End Function
Private Function dict_GetObjectKey(dict_ObjKey As Variant) As String
Dim dict_i As Integer
For dict_i = 1 To dict_pObjectKeys.Count
If dict_pObjectKeys.Item(dict_i) Is dict_ObjKey Then
dict_GetObjectKey = "__object__" & dict_i
Exit Function
End If
Next dict_i
dict_pObjectKeys.Add dict_ObjKey
dict_GetObjectKey = "__object__" & dict_pObjectKeys.Count
End Function
Private Sub dict_RemoveObjectKey(dict_ObjKey As Variant)
Dim dict_i As Integer
For dict_i = 1 To dict_pObjectKeys.Count
If dict_pObjectKeys.Item(dict_i) Is dict_ObjKey Then
dict_pObjectKeys.Remove dict_i
Exit Sub
End If
Next dict_i
End Sub
Private Function dict_GetKeyIndex(dict_Key As Variant) As Long
Dim dict_i As Long
For dict_i = 0 To UBound(dict_pKeys)
If VBA.IsObject(dict_pKeys(dict_i)) And VBA.IsObject(dict_Key) Then
If dict_pKeys(dict_i) Is dict_Key Then
dict_GetKeyIndex = dict_i
Exit For
End If
ElseIf VBA.IsObject(dict_pKeys(dict_i)) Or VBA.IsObject(dict_Key) Then
' Both need to be objects to check equality, skip
ElseIf dict_pKeys(dict_i) = dict_Key Then
dict_GetKeyIndex = dict_i
Exit For
End If
Next dict_i
End Function
#End If
Private Sub Class_Initialize()
#If Mac Or Not UseScriptingDictionaryIfAvailable Then
Set dict_pKeyValues = New Collection
Erase dict_pKeys
Erase dict_pItems
Set dict_pObjectKeys = New Collection
#Else
Set dict_pDictionary = CreateObject("Scripting.Dictionary")
#End If
End Sub
Private Sub Class_Terminate()
#If Mac Or Not UseScriptingDictionaryIfAvailable Then
Set dict_pKeyValues = Nothing
Set dict_pObjectKeys = Nothing
#Else
Set dict_pDictionary = Nothing
#End If
End Sub

Просмотреть файл

648
samples/VBA/specs.bas Normal file
Просмотреть файл

@ -0,0 +1,648 @@
Attribute VB_Name = "Specs"
Private pForDisplay As Boolean
Private pUseNative As Boolean
Public Sub SpeedTest()
#If Mac Then
' Mac
ExecuteSpeedTest CompareToNative:=False
#Else
' Windows
ExecuteSpeedTest CompareToNative:=True
#End If
End Sub
Sub ToggleNative(Optional Enabled As Boolean = True)
Dim Code As CodeModule
Dim Lines As Variant
Dim i As Integer
Set Code = ThisWorkbook.VBProject.VBComponents("Dictionary").CodeModule
Lines = Split(Code.Lines(1, 50), vbNewLine)
For i = 0 To UBound(Lines)
If InStr(1, Lines(i), "#Const UseScriptingDictionaryIfAvailable") Then
Code.ReplaceLine i + 1, "#Const UseScriptingDictionaryIfAvailable = " & Enabled
Exit Sub
End If
Next i
End Sub
Public Sub RunSpecs()
DisplayRunner.IdCol = 1
DisplayRunner.DescCol = 1
DisplayRunner.ResultCol = 2
DisplayRunner.OutputStartRow = 4
pForDisplay = True
DisplayRunner.RunSuite Specs()
pForDisplay = False
End Sub
Public Function Specs() As SpecSuite
Dim UseNative As Boolean
#If Mac Then
UseNative = False
#Else
If pUseNative Then
UseNative = True
pUseNative = False
Else
If Not pForDisplay Then
' Run native specs first
pUseNative = True
Specs
End If
UseNative = False
End If
#End If
Set Specs = New SpecSuite
If UseNative Then
Specs.Description = "Scripting.Dictionary"
Else
Specs.Description = "VBA-Dictionary"
End If
Dim Dict As Object
Dim Items As Variant
Dim Keys As Variant
Dim Key As Variant
Dim Item As Variant
Dim A As New Collection
Dim B As New Dictionary
' Properties
' ------------------------- '
With Specs.It("should get count of items")
Set Dict = CreateDictionary(UseNative)
Dict.Add "A", 123
Dict.Add "B", 3.14
Dict.Add "C", "ABC"
.Expect(Dict.Count).ToEqual 3
Dict.Remove "C"
.Expect(Dict.Count).ToEqual 2
End With
With Specs.It("should get item by key")
Set Dict = CreateDictionary(UseNative)
Dict.Add "A", 123
Dict.Add "B", 3.14
Dict.Add "C", "ABC"
.Expect(Dict.Item("B")).ToEqual 3.14
.Expect(Dict.Item("D")).ToBeEmpty
.Expect(Dict("B")).ToEqual 3.14
.Expect(Dict("D")).ToBeEmpty
End With
With Specs.It("should let item by key")
Set Dict = CreateDictionary(UseNative)
Dict.Add "A", 123
Dict.Add "B", 3.14
Dict.Add "C", "ABC"
' Let + New
Dict("D") = True
' Let + Replace
Dict("A") = 456
Dict("B") = 3.14159
' Should have correct values
.Expect(Dict("A")).ToEqual 456
.Expect(Dict("B")).ToEqual 3.14159
.Expect(Dict("C")).ToEqual "ABC"
.Expect(Dict("D")).ToEqual True
' Should have correct order
.Expect(Dict.Keys()(0)).ToEqual "A"
.Expect(Dict.Keys()(1)).ToEqual "B"
.Expect(Dict.Keys()(2)).ToEqual "C"
.Expect(Dict.Keys()(3)).ToEqual "D"
End With
With Specs.It("should set item by key")
Set Dict = CreateDictionary(UseNative)
Dict.Add "A", 123
Dict.Add "B", 3.14
Dict.Add "C", "ABC"
' Set + New
Set Dict("D") = CreateDictionary(UseNative)
Dict("D").Add "key", "D"
' Set + Replace
Set Dict("A") = CreateDictionary(UseNative)
Dict("A").Add "key", "A"
Set Dict("B") = CreateDictionary(UseNative)
Dict("B").Add "key", "B"
' Should have correct values
.Expect(Dict.Item("A")("key")).ToEqual "A"
.Expect(Dict.Item("B")("key")).ToEqual "B"
.Expect(Dict.Item("C")).ToEqual "ABC"
.Expect(Dict.Item("D")("key")).ToEqual "D"
' Should have correct order
.Expect(Dict.Keys()(0)).ToEqual "A"
.Expect(Dict.Keys()(1)).ToEqual "B"
.Expect(Dict.Keys()(2)).ToEqual "C"
.Expect(Dict.Keys()(3)).ToEqual "D"
End With
With Specs.It("should change key")
Set Dict = CreateDictionary(UseNative)
Dict.Add "A", 123
Dict.Add "B", 3.14
Dict.Add "C", "ABC"
Dict.Key("B") = "PI"
.Expect(Dict("PI")).ToEqual 3.14
End With
With Specs.It("should use CompareMode")
Set Dict = CreateDictionary(UseNative)
Dict.CompareMode = 0
Dict.Add "A", 123
Dict("a") = 456
Dict.Add "B", 3.14
Dict.Add "C", "ABC"
.Expect(Dict("A")).ToEqual 123
.Expect(Dict("a")).ToEqual 456
Set Dict = CreateDictionary(UseNative)
Dict.CompareMode = 1
Dict.Add "A", 123
Dict("a") = 456
Dict.Add "B", 3.14
Dict.Add "C", "ABC"
.Expect(Dict("A")).ToEqual 456
.Expect(Dict("a")).ToEqual 456
End With
With Specs.It("should allow Variant for key")
Set Dict = CreateDictionary(UseNative)
Key = "A"
Dict(Key) = 123
.Expect(Dict(Key)).ToEqual 123
Key = "B"
Set Dict(Key) = CreateDictionary(UseNative)
.Expect(Dict(Key).Count).ToEqual 0
End With
With Specs.It("should handle numeric keys")
Set Dict = CreateDictionary(UseNative)
Dict.Add 3, 1
Dict.Add 2, 2
Dict.Add 1, 3
Dict.Add "3", 4
Dict.Add "2", 5
Dict.Add "1", 6
.Expect(Dict(3)).ToEqual 1
.Expect(Dict(2)).ToEqual 2
.Expect(Dict(1)).ToEqual 3
.Expect(Dict("3")).ToEqual 4
.Expect(Dict("2")).ToEqual 5
.Expect(Dict("1")).ToEqual 6
.Expect(Dict.Keys()(0)).ToEqual 3
.Expect(Dict.Keys()(1)).ToEqual 2
.Expect(Dict.Keys()(2)).ToEqual 1
.Expect(TypeName(Dict.Keys()(0))).ToEqual "Integer"
.Expect(TypeName(Dict.Keys()(1))).ToEqual "Integer"
.Expect(TypeName(Dict.Keys()(2))).ToEqual "Integer"
End With
With Specs.It("should handle boolean keys")
Set Dict = CreateDictionary(UseNative)
Dict.Add True, 1
Dict.Add False, 2
.Expect(Dict(True)).ToEqual 1
.Expect(Dict(False)).ToEqual 2
.Expect(Dict.Keys()(0)).ToEqual True
.Expect(Dict.Keys()(1)).ToEqual False
.Expect(TypeName(Dict.Keys()(0))).ToEqual "Boolean"
.Expect(TypeName(Dict.Keys()(1))).ToEqual "Boolean"
End With
With Specs.It("should handle object keys")
Set Dict = CreateDictionary(UseNative)
Set A = New Collection
Set B = New Dictionary
A.Add 123
B.Add "a", 456
Dict.Add A, "123"
Dict.Add B, "456"
.Expect(Dict(A)).ToEqual "123"
.Expect(Dict(B)).ToEqual "456"
Dict.Remove B
Dict.Key(A) = B
.Expect(Dict(B)).ToEqual "123"
End With
' Methods
' ------------------------- '
With Specs.It("should add an item")
Set Dict = CreateDictionary(UseNative)
Dict.Add "A", 123
Dict.Add "B", 3.14
Dict.Add "C", "ABC"
Dict.Add "D", True
Dict.Add "E", Array(1, 2, 3)
Dict.Add "F", Dict
.Expect(Dict("A")).ToEqual 123
.Expect(Dict("B")).ToEqual 3.14
.Expect(Dict("C")).ToEqual "ABC"
.Expect(Dict("D")).ToEqual True
.Expect(Dict("E")(1)).ToEqual 2
.Expect(Dict("F")("C")).ToEqual "ABC"
End With
With Specs.It("should check if an item exists")
Set Dict = CreateDictionary(UseNative)
Dict.Add "Exists", 123
.Expect(Dict.Exists("Exists")).ToEqual True
.Expect(Dict.Exists("Doesn't Exist")).ToEqual False
End With
With Specs.It("should get an array of all items")
Set Dict = CreateDictionary(UseNative)
.Expect(Dict.Items).RunMatcher "Specs.ToBeAnEmptyArray", "to be an empty array"
Dict.Add "A", 123
Dict.Add "B", 3.14
Dict.Add "C", "ABC"
Dict.Add "D", True
Items = Dict.Items
.Expect(UBound(Items)).ToEqual 3
.Expect(Items(0)).ToEqual 123
.Expect(Items(3)).ToEqual True
Dict.Remove "A"
Dict.Remove "B"
Dict.Remove "C"
Dict.Remove "D"
.Expect(Dict.Items).RunMatcher "Specs.ToBeAnEmptyArray", "to be an empty array"
End With
With Specs.It("should get an array of all keys")
Set Dict = CreateDictionary(UseNative)
.Expect(Dict.Keys).RunMatcher "Specs.ToBeAnEmptyArray", "to be an empty array"
Dict.Add "A", 123
Dict.Add "B", 3.14
Dict.Add "C", "ABC"
Dict.Add "D", True
Keys = Dict.Keys
.Expect(UBound(Keys)).ToEqual 3
.Expect(Keys(0)).ToEqual "A"
.Expect(Keys(3)).ToEqual "D"
Dict.RemoveAll
.Expect(Dict.Keys).RunMatcher "Specs.ToBeAnEmptyArray", "to be an empty array"
End With
With Specs.It("should remove item")
Set Dict = CreateDictionary(UseNative)
Dict.Add "A", 123
Dict.Add "B", 3.14
Dict.Add "C", "ABC"
Dict.Add "D", True
.Expect(Dict.Count).ToEqual 4
Dict.Remove "C"
.Expect(Dict.Count).ToEqual 3
End With
With Specs.It("should remove all items")
Set Dict = CreateDictionary(UseNative)
Dict.Add "A", 123
Dict.Add "B", 3.14
Dict.Add "C", "ABC"
Dict.Add "D", True
.Expect(Dict.Count).ToEqual 4
Dict.RemoveAll
.Expect(Dict.Count).ToEqual 0
End With
' Other
' ------------------------- '
With Specs.It("should For Each over keys")
Set Dict = CreateDictionary(UseNative)
Set Keys = New Collection
For Each Key In Dict.Keys
Keys.Add Key
Next Key
.Expect(Keys.Count).ToEqual 0
Dict.Add "A", 123
Dict.Add "B", 3.14
Dict.Add "C", "ABC"
Dict.Add "D", True
Set Keys = New Collection
For Each Key In Dict.Keys
Keys.Add Key
Next Key
.Expect(Keys.Count).ToEqual 4
.Expect(Keys(1)).ToEqual "A"
.Expect(Keys(4)).ToEqual "D"
End With
With Specs.It("should For Each over items")
Set Dict = CreateDictionary(UseNative)
Set Items = New Collection
For Each Item In Dict.Items
Items.Add Item
Next Item
.Expect(Items.Count).ToEqual 0
Dict.Add "A", 123
Dict.Add "B", 3.14
Dict.Add "C", "ABC"
Dict.Add "D", True
Set Items = New Collection
For Each Item In Dict.Items
Items.Add Item
Next Item
.Expect(Items.Count).ToEqual 4
.Expect(Items(1)).ToEqual 123
.Expect(Items(4)).ToEqual True
End With
With Specs.It("should have UBound of -1 for empty Keys and Items")
Set Dict = CreateDictionary(UseNative)
.Expect(UBound(Dict.Keys)).ToEqual -1
.Expect(UBound(Dict.Items)).ToEqual -1
.Expect(Err.Number).ToEqual 0
End With
' Errors
' ------------------------- '
Err.Clear
On Error Resume Next
With Specs.It("should throw 5 when changing CompareMode with items in Dictionary")
Set Dict = CreateDictionary(UseNative)
Dict.Add "A", 123
Dict.CompareMode = vbTextCompare
.Expect(Err.Number).ToEqual 5
Err.Clear
End With
With Specs.It("should throw 457 on Add if key exists")
Set Dict = CreateDictionary(UseNative)
Dict.Add "A", 123
Dict.Add "A", 456
.Expect(Err.Number).ToEqual 457
Err.Clear
Dict.RemoveAll
Dict.Add "A", 123
Dict.Add "a", 456
.Expect(Err.Number).ToEqual 0
Err.Clear
Dict.RemoveAll
Dict.CompareMode = vbTextCompare
Dict.Add "A", 123
Dict.Add "a", 456
.Expect(Err.Number).ToEqual 457
Err.Clear
End With
With Specs.It("should throw 32811 on Remove if key doesn't exist")
Set Dict = CreateDictionary(UseNative)
Dict.Remove "A"
.Expect(Err.Number).ToEqual 32811
Err.Clear
End With
With Specs.It("should throw 457 for Boolean key quirks")
Set Dict = CreateDictionary(UseNative)
Dict.Add True, "abc"
Dict.Add -1, "def"
.Expect(Err.Number).ToEqual 457
Err.Clear
Dict.Add False, "abc"
Dict.Add 0, "def"
.Expect(Err.Number).ToEqual 457
Err.Clear
End With
On Error GoTo 0
InlineRunner.RunSuite Specs
End Function
Public Sub ExecuteSpeedTest(Optional CompareToNative As Boolean = False)
Dim Counts As Variant
Counts = Array(5000, 5000, 5000, 5000, 7500, 7500, 7500, 7500)
Dim Baseline As Collection
If CompareToNative Then
Set Baseline = RunSpeedTest(Counts, True)
End If
Dim Results As Collection
Set Results = RunSpeedTest(Counts, False)
Debug.Print vbNewLine & "SpeedTest Results:" & vbNewLine
PrintResults "Add", Baseline, Results, 0
PrintResults "Iterate", Baseline, Results, 1
End Sub
Public Sub PrintResults(Test As String, Baseline As Collection, Results As Collection, Index As Integer)
Dim BaselineAvg As Single
Dim ResultsAvg As Single
Dim i As Integer
If Not Baseline Is Nothing Then
For i = 1 To Baseline.Count
BaselineAvg = BaselineAvg + Baseline(i)(Index)
Next i
BaselineAvg = BaselineAvg / Baseline.Count
End If
For i = 1 To Results.Count
ResultsAvg = ResultsAvg + Results(i)(Index)
Next i
ResultsAvg = ResultsAvg / Results.Count
Dim Result As String
Result = Test & ": " & Format(Round(ResultsAvg, 0), "#,##0") & " ops./s"
If Not Baseline Is Nothing Then
Result = Result & " vs. " & Format(Round(BaselineAvg, 0), "#,##0") & " ops./s "
If ResultsAvg < BaselineAvg Then
Result = Result & Format(Round(BaselineAvg / ResultsAvg, 0), "#,##0") & "x slower"
ElseIf BaselineAvg > ResultsAvg Then
Result = Result & Format(Round(ResultsAvg / BaselineAvg, 0), "#,##0") & "x faster"
End If
End If
Result = Result
If Results.Count > 1 Then
Result = Result & vbNewLine
For i = 1 To Results.Count
Result = Result & " " & Format(Round(Results(i)(Index), 0), "#,##0")
If Not Baseline Is Nothing Then
Result = Result & " vs. " & Format(Round(Baseline(i)(Index), 0), "#,##0")
End If
Result = Result & vbNewLine
Next i
End If
Debug.Print Result
End Sub
Public Function RunSpeedTest(Counts As Variant, Optional UseNative As Boolean = False) As Collection
Dim Results As New Collection
Dim CountIndex As Integer
Dim Dict As Object
Dim i As Long
Dim AddResult As Double
Dim Key As Variant
Dim Value As Variant
Dim IterateResult As Double
Dim Timer As New PreciseTimer
For CountIndex = LBound(Counts) To UBound(Counts)
Timer.StartTimer
Set Dict = CreateDictionary(UseNative)
For i = 1 To Counts(CountIndex)
Dict.Add CStr(i), i
Next i
' Convert to seconds
AddResult = Timer.TimeElapsed / 1000#
' Convert to ops./s
If AddResult > 0 Then
AddResult = Counts(CountIndex) / AddResult
Else
' Due to single precision, timer resolution is 0.01 ms, set to 0.005 ms
AddResult = Counts(CountIndex) / 0.005
End If
Timer.StartTimer
For Each Key In Dict.Keys
Value = Dict.Item(Key)
Next Key
' Convert to seconds
IterateResult = Timer.TimeElapsed / 1000#
' Convert to ops./s
If IterateResult > 0 Then
IterateResult = Counts(CountIndex) / IterateResult
Else
' Due to single precision, timer resolution is 0.01 ms, set to 0.005 ms
IterateResult = Counts(CountIndex) / 0.005
End If
Results.Add Array(AddResult, IterateResult)
Next CountIndex
Set RunSpeedTest = Results
End Function
Public Function CreateDictionary(Optional UseNative As Boolean = False) As Object
If UseNative Then
Set CreateDictionary = CreateObject("Scripting.Dictionary")
Else
Set CreateDictionary = New Dictionary
End If
End Function
Public Function ToBeAnEmptyArray(Actual As Variant) As Variant
Dim UpperBound As Long
Err.Clear
On Error Resume Next
' First, make sure it's an array
If IsArray(Actual) = False Then
' we weren't passed an array, return True
ToBeAnEmptyArray = True
Else
' Attempt to get the UBound of the array. If the array is
' unallocated, an error will occur.
UpperBound = UBound(Actual, 1)
If (Err.Number <> 0) Then
ToBeAnEmptyArray = True
Else
' Check for case of -1 UpperBound (Scripting.Dictionary.Keys/Items)
Err.Clear
If LBound(Actual) > UpperBound Then
ToBeAnEmptyArray = True
Else
ToBeAnEmptyArray = False
End If
End If
End If
End Function

Просмотреть файл

@ -0,0 +1,140 @@
Class v_Data_ArrayList
Private pArrayList
Private Sub Class_Initialize()
Set pArrayList = CreateObject("System.Collections.ArrayList")
End Sub
' Properties
Public Property Get Capacity()
Capacity = pArrayList.Capacity
End Property
Public Property Let Capacity(intSize)
pArrayList.Capacity = intSize
End Property
Public Property Get Count()
Count = pArrayList.Count
End Property
Public Property Get IsFixedSize()
IsFixedSize = pArrayList.IsFixedSize
End Property
Public Property Get IsReadOnly()
IsReadOnly = pArrayList.IsReadOnly
End Property
Public Property Get IsSynchronized()
IsSynchronized = pArrayList.IsSynchronized
End Property
Public Default Property Get Item(intIndex)
If IsObject(pArrayList(intIndex)) Then
Set Item = pArrayList(intIndex)
Else
Item = pArrayList(intIndex)
End If
End Property
Public Property Let Item(intIndex, varInput)
pArrayList(intIndex) = varInput
End Property
Public Property Set Item(intIndex, varInput)
Set pArrayList(intIndex) = varInput
End Property
Public Property Get SyncRoot()
SyncRoot = pArrayList.SyncRoot
End Property
' Methods
Public Sub Add(varItem)
pArrayList.Add varItem
End Sub
Public Sub Clear()
pArrayList.Clear()
End Sub
Public Function Clone()
Set Clone = pArrayList.Clone()
End Function
Public Function Contains(varItem)
Contains = pArrayList.Contains(varItem)
End Function
Public Function Equals(objItem)
Equals = pArrayList.Equals(objItem)
End Function
Public Function GetEnumerator(intStart, intEnd)
Set GetEnumerator = pArrayList.GetEnumerator(intStart, intEnd)
End Function
Public Function GetHashCode()
GetHashCode = pArrayList.GetHashCode()
End Function
Public Function GetType()
GetType = pArrayList.GetType()
End Function
Public Sub Insert(intIndex, varItem)
pArrayList.Insert intIndex, varItem
End Sub
Public Sub Remove(varItem)
pArrayList.Remove varItem
End Sub
Public Sub RemoveAt(intIndex)
pArrayList.RemoveAt intIndex
End Sub
Public Sub Reverse()
pArrayList.Reverse()
End Sub
Public Sub Sort()
pArrayList.Sort()
End Sub
Public Function ToArray()
ToArray = pArrayList.ToArray()
End Function
Public Function ToString()
ToString = pArrayList.ToString()
End Function
Public Function TrimToSize()
TrimToSize = pArrayList.TrimToSize()
End Function
Private Sub Class_Terminate()
Set pArrayList = Nothing
End Sub
End Class
If WScript.ScriptName = "v_Data_ArrayList.vbs" Then
Dim arraylist
Set arraylist = New v_Data_ArrayList
arraylist.Add "Train"
arraylist.Add "Bus"
arraylist.Add "Car"
arraylist.Add "Bicycle"
arraylist.Add "Boat"
WScript.Echo arraylist(2)
End If

Просмотреть файл

Просмотреть файл

@ -117,7 +117,7 @@ class TestHeuristics < Minitest::Test
"TeX" => all_fixtures("TeX", "*.cls"),
"ObjectScript" => all_fixtures("ObjectScript", "*.cls"),
# Missing heuristics
nil => all_fixtures("Apex", "*.cls") + all_fixtures("OpenEdge ABL", "*.cls") + all_fixtures("Visual Basic", "*.cls"),
nil => all_fixtures("Apex", "*.cls") + all_fixtures("OpenEdge ABL", "*.cls") + all_fixtures("VBA", "*.cls"),
})
end
@ -510,7 +510,7 @@ class TestHeuristics < Minitest::Test
def test_vba_by_heuristics
assert_heuristics({
"Visual Basic" => all_fixtures("Visual Basic", "*.vba"),
"VBA" => all_fixtures("VBA", "*.vba"),
"Vim script" => all_fixtures("Vim script", "*.vba")
})
end

4
vendor/README.md поставляемый
Просмотреть файл

@ -420,13 +420,15 @@ This is a list of grammars that Linguist selects to provide syntax highlighting
- **UnrealScript:** [textmate/java.tmbundle](https://github.com/textmate/java.tmbundle)
- **UrWeb:** [gwalborn/UrWeb-Language-Definition](https://github.com/gwalborn/UrWeb-Language-Definition)
- **V:** [0x9ef/vscode-vlang](https://github.com/0x9ef/vscode-vlang)
- **VBA:** [angryant0007/VBDotNetSyntax](https://github.com/angryant0007/VBDotNetSyntax)
- **VBScript:** [angryant0007/VBDotNetSyntax](https://github.com/angryant0007/VBDotNetSyntax)
- **VCL:** [brandonwamboldt/sublime-varnish](https://github.com/brandonwamboldt/sublime-varnish)
- **VHDL:** [textmate/vhdl.tmbundle](https://github.com/textmate/vhdl.tmbundle)
- **Vala:** [technosophos/Vala-TMBundle](https://github.com/technosophos/Vala-TMBundle)
- **Verilog:** [textmate/verilog.tmbundle](https://github.com/textmate/verilog.tmbundle)
- **Vim Snippet:** [Alhadis/language-viml](https://github.com/Alhadis/language-viml)
- **Vim script:** [Alhadis/language-viml](https://github.com/Alhadis/language-viml)
- **Visual Basic:** [angryant0007/VBDotNetSyntax](https://github.com/angryant0007/VBDotNetSyntax)
- **Visual Basic .NET:** [angryant0007/VBDotNetSyntax](https://github.com/angryant0007/VBDotNetSyntax)
- **Volt:** [textmate/d.tmbundle](https://github.com/textmate/d.tmbundle)
- **Vue:** [vuejs/vue-syntax-highlight](https://github.com/vuejs/vue-syntax-highlight)
- **Wavefront Material:** [Alhadis/language-wavefront](https://github.com/Alhadis/language-wavefront)