@@ -9,6 +9,7 @@ open System.Text.RegularExpressions
9
9
open System.Web
10
10
open Microsoft.FSharp .Reflection
11
11
open FSharp.Data
12
+ open System.Linq
12
13
13
14
module GlobalVars =
14
15
let inputFolder = Path.Combine(__ SOURCE_ DIRECTORY__, " inputfiles" )
@@ -122,6 +123,22 @@ module Types =
122
123
type InterfaceOrNamespace =
123
124
| Interface of Browser.Interface
124
125
| Namespace of Browser.Namespace
126
+ member self.Name =
127
+ match self with
128
+ | Interface i -> i.Name
129
+ | Namespace n -> n.Name
130
+ member self.Exposed =
131
+ match self with
132
+ | Interface i -> i.Exposed
133
+ | Namespace n -> n.Exposed
134
+ member self.Properties =
135
+ match self with
136
+ | Interface i -> i.Properties
137
+ | Namespace n -> n.Properties
138
+ member self.Methods =
139
+ match self with
140
+ | Interface i -> i.Methods
141
+ | Namespace n -> n.Methods
125
142
126
143
// Note:
127
144
// Eventhandler's name and the eventName are not just off by "on".
@@ -277,8 +294,19 @@ module Data =
277
294
let browser =
278
295
( new StreamReader( Path.Combine( GlobalVars.inputFolder, " browser.webidl.xml" ))) .ReadToEnd() |> Browser.Parse
279
296
280
- let worker =
281
- ( new StreamReader( Path.Combine( GlobalVars.inputFolder, " webworkers.specidl.xml" ))) .ReadToEnd() |> Browser.Parse
297
+ let knownExposures =
298
+ let asArray ( k : string , v : JsonValue ) =
299
+ match v with
300
+ | JsonValue.String s -> ( k, s.Split [| ' ' |])
301
+ | _ -> failwith " Incorrect format"
302
+
303
+ File.ReadAllText( Path.Combine( GlobalVars.inputFolder, " knownExposures.json" ))
304
+ |> JsonValue.Parse
305
+ |> JsonExtensions.Properties
306
+ |> Array.map asArray
307
+ |> Map.ofArray
308
+
309
+ let WorkerTypes = [| " Worker" ; " DedicatedWorker" ; " SharedWorker" ; " ServiceWorker" |]
282
310
283
311
/// Check if the given element should be disabled or not
284
312
/// reason is that ^a can be an interface, property or method, but they
@@ -291,22 +319,40 @@ module Data =
291
319
match flavor with
292
320
| Flavor.All -> true
293
321
| Flavor.Web -> Array.contains " Window" exposedArray
294
- | Flavor.Worker -> true
295
- | _ -> true
322
+ | Flavor.Worker -> ( exposedArray.Intersect WorkerTypes) .Count() <> 0
323
+ | _ ->
324
+ match flavor with
325
+ | Flavor.All | Flavor.Web -> true
326
+ | Flavor.Worker -> false
296
327
filterByTag
297
328
329
+ let inline ShouldKeepInherit flavor inheritedExposure ( i : ^a when ^a : ( member Exposed : string option )) =
330
+ let exposure = ( ^a : ( member Exposed : string option) i);
331
+ if exposure.IsSome then ShouldKeep flavor i
332
+ else ShouldKeep flavor inheritedExposure
333
+
334
+ let inline ShouldKeepUnexposed flavor name =
335
+ let exposure = knownExposures.TryFind name
336
+ match flavor with
337
+ | Flavor.All -> true
338
+ | Flavor.Web -> exposure.IsNone || Array.contains " Window" exposure.Value
339
+ | Flavor.Worker -> exposure.IsSome
340
+
341
+ let inline getName (( i : ^a when ^a : ( member Name : string ))) =
342
+ ( ^a : ( member Name : string) i)
343
+
344
+ let inline getTypedefName (( i : ^a when ^a : ( member NewType : string ))) =
345
+ ( ^a : ( member NewType : string) i)
346
+
298
347
// Global interfacename to interface object map
299
348
let allWebNonCallbackInterfaces =
300
349
Array.concat [| browser.Interfaces; browser.MixinInterfaces.Interfaces |]
301
350
302
351
let allWebInterfaces =
303
352
Array.concat [| browser.Interfaces; browser.CallbackInterfaces.Interfaces; browser.MixinInterfaces.Interfaces |]
304
353
305
- let allWorkerAdditionalInterfaces =
306
- Array.concat [| worker.Interfaces; worker.MixinInterfaces.Interfaces |]
307
-
308
354
let allInterfaces =
309
- Array.concat [| allWebInterfaces; allWorkerAdditionalInterfaces |]
355
+ Array.concat [| allWebInterfaces |]
310
356
311
357
let inline toNameMap < ^a when ^a : ( member Name : string ) > ( data : array < ^a > ) =
312
358
data
@@ -317,15 +363,15 @@ module Data =
317
363
allInterfaces |> toNameMap
318
364
319
365
let allDictionariesMap =
320
- Array.concat [| browser.Dictionaries; worker.Dictionaries |]
366
+ Array.concat [| browser.Dictionaries |]
321
367
|> toNameMap
322
368
323
369
let allEnumsMap =
324
- Array.concat [| browser.Enums; worker.Enums |]
370
+ Array.concat [| browser.Enums |]
325
371
|> toNameMap
326
372
327
373
let allCallbackFuncs =
328
- Array.concat [| browser.CallbackFunctions; worker.CallbackFunctions |]
374
+ Array.concat [| browser.CallbackFunctions |]
329
375
|> toNameMap
330
376
331
377
let GetInterfaceByName = allInterfacesMap.TryFind
@@ -342,28 +388,19 @@ module Data =
342
388
|> set
343
389
344
390
let GetNonCallbackInterfacesByFlavor flavor =
345
- match flavor with
346
- | Flavor.Web -> allWebNonCallbackInterfaces |> Array.filter ( ShouldKeep Flavor.Web)
347
- | Flavor.All -> allWebNonCallbackInterfaces |> Array.filter ( ShouldKeep Flavor.All)
348
- | Flavor.Worker ->
349
- let isFromBrowserXml = allWebNonCallbackInterfaces |> Array.filter ( fun i -> knownWorkerInterfaces.Contains i.Name)
350
- Array.append isFromBrowserXml allWorkerAdditionalInterfaces
391
+ allWebNonCallbackInterfaces |> Array.filter ( ShouldKeep flavor)
351
392
352
393
let GetCallbackFuncsByFlavor flavor =
353
- browser.CallbackFunctions
354
- |> Array.filter ( fun cb -> flavor <> Flavor.Worker || knownWorkerInterfaces.Contains cb.Name)
394
+ browser.CallbackFunctions |> Array.filter ( getName >> ShouldKeepUnexposed flavor)
355
395
356
396
let GetEnumsByFlavor flavor =
357
- match flavor with
358
- | Flavor.Web | Flavor.All -> browser.Enums
359
- | Flavor.Worker ->
360
- let isFromBrowserXml = browser.Enums |> Array.filter ( fun i -> knownWorkerEnums.Contains i.Name)
361
- Array.append isFromBrowserXml worker.Enums
397
+ browser.Enums |> Array.filter ( getName >> ShouldKeepUnexposed flavor)
362
398
363
399
let GetNamespacesByFlavor flavor =
364
- match flavor with
365
- | Flavor.Web | Flavor.All -> browser.Namespaces
366
- | Flavor.Worker -> worker.Namespaces
400
+ browser.Namespaces |> Array.filter ( ShouldKeep flavor)
401
+
402
+ let GetTypedefsByFlavor flavor =
403
+ browser.Typedefs |> Array.filter ( getTypedefName >> ShouldKeepUnexposed flavor)
367
404
368
405
/// Event name to event type map
369
406
let eNameToEType =
@@ -461,22 +498,22 @@ module Data =
461
498
| Some i -> List.ofArray i.Implements
462
499
| _ -> []
463
500
464
- Array.concat [| allWebNonCallbackInterfaces; worker.Interfaces ; worker.MixinInterfaces.Interfaces |]
501
+ Array.concat [| allWebNonCallbackInterfaces |]
465
502
|> Array.map ( fun i -> ( i.Name, List.concat [ ( getExtendList i.Name); ( getImplementList i.Name) ]))
466
503
|> Map.ofArray
467
504
468
505
/// Distinct event type list, used in the "createEvent" function
469
506
let distinctETypeList =
470
507
let usedEvents =
471
- [ for i in GetNonCallbackInterfacesByFlavor Flavor.All do
508
+ [ for i in GetNonCallbackInterfacesByFlavor Flavor.Web do
472
509
match i.Events with
473
510
| Some es -> yield ! es.Events
474
511
| _ -> () ]
475
512
|> List.map ( fun e -> e.Type)
476
513
|> List.distinct
477
514
478
515
let unUsedEvents =
479
- GetNonCallbackInterfacesByFlavor Flavor.All
516
+ GetNonCallbackInterfacesByFlavor Flavor.Web
480
517
|> Array.choose ( fun i ->
481
518
if i.Extends = " Event" && i.Name.EndsWith( " Event" ) && not ( List.contains i.Name usedEvents) then Some( i.Name) else None)
482
519
|> Array.distinct
@@ -569,7 +606,7 @@ module Data =
569
606
let GetGlobalPollutor flavor =
570
607
match flavor with
571
608
| Flavor.Web | Flavor.All -> browser.Interfaces |> Array.tryFind ( fun i -> i.PrimaryGlobal.IsSome)
572
- | Flavor.Worker -> worker .Interfaces |> Array.tryFind ( fun i -> i.Global.IsSome)
609
+ | Flavor.Worker -> browser .Interfaces |> Array.tryFind ( fun i -> i.Global.IsSome && i.Name = " DedicatedWorkerGlobalScope " )
573
610
574
611
let GetGlobalPollutorName flavor =
575
612
match GetGlobalPollutor flavor with
@@ -722,7 +759,8 @@ module Emit =
722
759
| integerType when List.contains integerType integerTypes -> " number"
723
760
| extendedType when List.contains extendedType extendedTypes -> extendedType
724
761
| _ ->
725
- if ignoreDOMTypes && Seq.contains objDomType [ " Element" ; " Window" ; " Document" ] then " any"
762
+ if ignoreDOMTypes && ( Seq.contains objDomType [ " Element" ; " Window" ; " Document" ; " WindowProxy" ; " WebGLRenderingContext" ] || objDomType.StartsWith " HTML" ) then " never"
763
+ elif objDomType = " WindowProxy" then " Window"
726
764
else
727
765
// Name of an interface / enum / dict. Just return itself
728
766
if allInterfacesMap.ContainsKey objDomType ||
@@ -898,15 +936,6 @@ module Emit =
898
936
| _ -> " "
899
937
900
938
let EmitProperties flavor prefix ( emitScope : EmitScope ) ( i : InterfaceOrNamespace ) ( conflictedMembers : Set < string >) =
901
- let name =
902
- match i with
903
- | InterfaceOrNamespace.Interface it -> it.Name
904
- | InterfaceOrNamespace.Namespace n -> n.Name
905
- let properties =
906
- match i with
907
- | InterfaceOrNamespace.Interface it -> it.Properties
908
- | InterfaceOrNamespace.Namespace n -> n.Properties
909
-
910
939
let emitPropertyFromJson ( p : InputJsonType.Root ) =
911
940
let readOnlyModifier =
912
941
match p.Readonly with
@@ -915,7 +944,7 @@ module Emit =
915
944
Pt.Printl " %s%s%s : %s ;" prefix readOnlyModifier p.Name.Value p.Type.Value
916
945
917
946
let emitCommentForProperty ( printLine : Printf.StringFormat < _ , unit > -> _ ) pName =
918
- match CommentJson.GetCommentForProperty name pName with
947
+ match CommentJson.GetCommentForProperty i.Name pName with
919
948
| Some comment -> printLine " %s " comment
920
949
| _ -> ()
921
950
@@ -925,10 +954,10 @@ module Emit =
925
954
emitCommentForProperty printLine p.Name
926
955
927
956
// Treat window.name specially because of https://github.com/Microsoft/TypeScript/issues/9850
928
- if p.Name = " name" && name = " Window" && emitScope = EmitScope.All then
957
+ if p.Name = " name" && i.Name = " Window" && emitScope = EmitScope.All then
929
958
printLine " declare const name: never;"
930
- elif Option.isNone ( getRemovedItemByName p.Name ItemKind.Property name ) then
931
- match getOverriddenItemByName p.Name ItemKind.Property name with
959
+ elif Option.isNone ( getRemovedItemByName p.Name ItemKind.Property i.Name ) then
960
+ match getOverriddenItemByName p.Name ItemKind.Property i.Name with
932
961
| Some p' -> emitPropertyFromJson p'
933
962
| None ->
934
963
let pType =
@@ -956,29 +985,19 @@ module Emit =
956
985
// Note: the schema file shows the property doesn't have "static" attribute,
957
986
// therefore all properties are emited for the instance type.
958
987
if emitScope <> StaticOnly then
959
- match properties with
988
+ match i.Properties with
960
989
| Some ps ->
961
990
ps.Properties
962
- |> Array.filter ( ShouldKeep flavor)
991
+ |> Array.filter ( ShouldKeepInherit flavor i )
963
992
|> Array.iter emitProperty
964
993
| None -> ()
965
994
966
995
for addedItem in getAddedItems ItemKind.Property flavor do
967
- if ( matchInterface name addedItem) && ( prefix <> " declare var " || addedItem.ExposeGlobally.IsNone || addedItem.ExposeGlobally.Value) then
996
+ if ( matchInterface i.Name addedItem) && ( prefix <> " declare var " || addedItem.ExposeGlobally.IsNone || addedItem.ExposeGlobally.Value) then
968
997
emitCommentForProperty Pt.Printl addedItem.Name.Value
969
998
emitPropertyFromJson addedItem
970
999
971
1000
let EmitMethods flavor prefix ( emitScope : EmitScope ) ( i : InterfaceOrNamespace ) ( conflictedMembers : Set < string >) =
972
- let name =
973
- match i with
974
- | InterfaceOrNamespace.Interface it -> it.Name
975
- | InterfaceOrNamespace.Namespace n -> n.Name
976
-
977
- let methods =
978
- match i with
979
- | InterfaceOrNamespace.Interface it -> it.Methods
980
- | InterfaceOrNamespace.Namespace n -> n.Methods
981
-
982
1001
// Note: two cases:
983
1002
// 1. emit the members inside a interface -> no need to add prefix
984
1003
// 2. emit the members outside to expose them (for "Window") -> need to add "declare"
@@ -987,7 +1006,7 @@ module Emit =
987
1006
988
1007
let emitCommentForMethod ( printLine : Printf.StringFormat < _ , unit > -> _ ) ( mName : string option ) =
989
1008
if mName.IsSome then
990
- match CommentJson.GetCommentForMethod name mName.Value with
1009
+ match CommentJson.GetCommentForMethod i.Name mName.Value with
991
1010
| Some comment -> printLine " %s " comment
992
1011
| _ -> ()
993
1012
@@ -1008,8 +1027,8 @@ module Emit =
1008
1027
// - removedType: meaning the type is marked as removed in the json file
1009
1028
// if there is any conflicts between the two, the "removedType" has a higher priority over
1010
1029
// the "overridenType".
1011
- let removedType = Option.bind ( fun name -> InputJson.getRemovedItemByName name InputJson.ItemKind.Method name ) m.Name
1012
- let overridenType = Option.bind ( fun mName -> InputJson.getOverriddenItemByName mName InputJson.ItemKind.Method name ) m.Name
1030
+ let removedType = Option.bind ( fun name -> InputJson.getRemovedItemByName name InputJson.ItemKind.Method i.Name ) m.Name
1031
+ let overridenType = Option.bind ( fun mName -> InputJson.getOverriddenItemByName mName InputJson.ItemKind.Method i.Name ) m.Name
1013
1032
1014
1033
if removedType.IsNone then
1015
1034
match overridenType with
@@ -1019,7 +1038,7 @@ module Emit =
1019
1038
| _ -> ()
1020
1039
t.Signatures |> Array.iter ( printLine " %s%s ;" prefix)
1021
1040
| None ->
1022
- match name , m.Name with
1041
+ match i.Name , m.Name with
1023
1042
| _, Some " createElement" -> EmitCreateElementOverloads m
1024
1043
| _, Some " createEvent" -> EmitCreateEventOverloads m
1025
1044
| _, Some " getElementsByTagName" -> EmitGetElementsByTagNameOverloads m
@@ -1028,7 +1047,7 @@ module Emit =
1028
1047
| _ ->
1029
1048
if m.Name.IsSome then
1030
1049
// If there are added overloads from the json files, print them first
1031
- match getAddedItemByName m.Name.Value ItemKind.SignatureOverload name with
1050
+ match getAddedItemByName m.Name.Value ItemKind.SignatureOverload i.Name with
1032
1051
| Some ol -> ol.Signatures |> Array.iter ( printLine " %s ;" )
1033
1052
| _ -> ()
1034
1053
@@ -1040,29 +1059,26 @@ module Emit =
1040
1059
if isNullable then makeNullable returnType else returnType
1041
1060
printLine " %s%s (%s ): %s ;" prefix ( if m.Name.IsSome then m.Name.Value else " " ) paramsString returnString
1042
1061
1043
- if methods.IsSome then
1044
- methods.Value.Methods
1062
+ if i.Methods.IsSome then
1063
+ i.Methods.Value.Methods
1064
+ |> Array.filter ( ShouldKeepInherit flavor i)
1045
1065
|> Array.filter mFilter
1046
1066
|> Array.iter ( emitMethod flavor prefix i)
1047
1067
1048
1068
for addedItem in getAddedItems ItemKind.Method flavor do
1049
- if ( matchInterface name addedItem && matchScope emitScope addedItem) then
1069
+ if ( matchInterface i.Name addedItem && matchScope emitScope addedItem) then
1050
1070
emitCommentForMethod Pt.Printl addedItem.Name
1051
1071
emitMethodFromJson addedItem
1052
1072
1053
1073
// The window interface inherited some methods from "Object",
1054
1074
// which need to explicitly exposed
1055
- if name = " Window" && prefix = " declare function " then
1075
+ if i.Name = " Window" && prefix = " declare function " then
1056
1076
Pt.Printl " declare function toString(): string;"
1057
1077
1058
1078
/// Emit the properties and methods of a given interface
1059
1079
let EmitMembers flavor ( prefix : string ) ( emitScope : EmitScope ) ( i : InterfaceOrNamespace ) =
1060
- let name =
1061
- match i with
1062
- | InterfaceOrNamespace.Interface it -> it.Name
1063
- | InterfaceOrNamespace.Namespace n -> n.Name
1064
1080
let conflictedMembers =
1065
- match Map.tryFind name extendConflictsBaseTypes with
1081
+ match Map.tryFind i.Name extendConflictsBaseTypes with
1066
1082
| Some conflict -> conflict.MemberNames
1067
1083
| _ -> []
1068
1084
|> Set.ofList
@@ -1427,12 +1443,9 @@ module Emit =
1427
1443
Pt.Printl " "
1428
1444
1429
1445
browser.Dictionaries
1430
- |> Array.filter ( fun dict -> flavor <> Worker || knownWorkerInterfaces.Contains dict.Name )
1446
+ |> Array.filter ( getName >> ShouldKeepUnexposed flavor )
1431
1447
|> Array.iter emitDictionary
1432
1448
1433
- if flavor = Worker then
1434
- worker.Dictionaries |> Array.iter emitDictionary
1435
-
1436
1449
let EmitAddedInterface ( ai : InputJsonType.Root ) =
1437
1450
match ai.Extends with
1438
1451
| Some e -> Pt.Printl " interface %s extends %s {" ai.Name.Value ai.Extends.Value
@@ -1481,15 +1494,9 @@ module Emit =
1481
1494
let emitTypeDefFromJson ( typeDef : InputJsonType.Root ) =
1482
1495
Pt.Printl " type %s = %s ;" typeDef.Name.Value typeDef.Type.Value
1483
1496
1484
- match flavor with
1485
- | Flavor.Worker ->
1486
- browser.Typedefs
1487
- |> Array.filter ( fun typedef -> knownWorkerInterfaces.Contains typedef.NewType)
1488
- |> Array.iter emitTypeDef
1489
- | _ ->
1490
- browser.Typedefs
1491
- |> Array.filter ( fun typedef -> getRemovedItemByName typedef.NewType ItemKind.TypeDef " " |> Option.isNone)
1492
- |> Array.iter emitTypeDef
1497
+ GetTypedefsByFlavor flavor
1498
+ |> Array.filter ( fun typedef -> getRemovedItemByName typedef.NewType ItemKind.TypeDef " " |> Option.isNone)
1499
+ |> Array.iter emitTypeDef
1493
1500
1494
1501
InputJson.getAddedItems ItemKind.TypeDef flavor
1495
1502
|> Array.iter emitTypeDefFromJson
0 commit comments