Skip to content

Commit 06a7b80

Browse files
committed
Cache parsed properties, change provided properties to fields
1 parent c8510df commit 06a7b80

File tree

6 files changed

+240
-262
lines changed

6 files changed

+240
-262
lines changed

src/CssClassesTypeProvider.fs

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -75,23 +75,18 @@ module TypeProvider =
7575
let getProperties = args.[ 3 ] :?> bool
7676
let nameCollisions = args.[ 4 ] :?> NameCollisions
7777

78-
let parseSampleToTypeSpec _ value =
79-
using ( logTimeType typeName this.Id "ParseAndGenerateMembers" typeName ) <| fun _ ->
80-
81-
let cssType = ProvidedTypeDefinition( asm , ns , typeName , Some ( typeof< obj > ) )
78+
let tryParseText value =
8279
logType typeName this.Id "Parsing CSS"
83-
let cssClasses = Utils.parseCss value naming nameCollisions
84-
logType typeName this.Id "Adding type members"
85-
Utils.addTypeMembersFromCss getProperties cssClasses cssType
80+
Utils.parseCss value naming nameCollisions
8681

87-
{
88-
GeneratedType = cssType
89-
RepresentationType = cssType
90-
WasValidInput = Option.isSome cssClasses
91-
}
82+
let createType parseResult =
83+
logType typeName this.Id "Creating type"
84+
let cssType = ProvidedTypeDefinition( asm , ns , typeName , Some ( typeof< obj > ) )
85+
Utils.addTypeMembersFromCss getProperties parseResult cssType
86+
cssType
9287

9388
let source = args.[ 0 ] |> processStringParameter
94-
generateType source parseSampleToTypeSpec commandConfig this config finalResolutionFolder typeName
89+
generateType source commandConfig this config finalResolutionFolder typeName tryParseText createType
9590

9691
let parameters = [
9792
ProvidedStaticParameter( "source" , typeof< string >, parameterDefaultValue = "" )

src/TypedCssClasses.fsproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
<TargetFramework>netstandard2.0</TargetFramework>
55
<DisableImplicitSystemValueTupleReference>true</DisableImplicitSystemValueTupleReference>
66
<Configurations>Debug;Release;ReleaseTest</Configurations>
7-
<VersionPrefix>0.3.1</VersionPrefix>
7+
<VersionPrefix>0.4.0</VersionPrefix>
88
<VersionSuffix></VersionSuffix>
99
<PackageId>Zanaptak.TypedCssClasses</PackageId>
1010
<Authors>zanaptak</Authors>

src/Utils.fs

Lines changed: 18 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,9 @@ open System.Text.RegularExpressions
66
open System.Collections.Generic
77
open System.Runtime.InteropServices
88
open Zanaptak.TypedCssClasses.Internal.ProviderImplementation.ProvidedTypes
9+
open Zanaptak.TypedCssClasses.Internal.FSharpData.ProvidedTypes
910
open Zanaptak.TypedCssClasses.Internal.FSharpData.Helpers
1011

11-
type Property = { Name : string ; Value : string }
12-
1312
/// Converts the string to an array of Int32 code-points (the actual Unicode Code Point number).
1413
let toCodePoints (source : string) : seq<int> =
1514
let mapper i c =
@@ -81,7 +80,6 @@ let unescapeHexStr hexStr =
8180
| true , codePoint when isUnicodeScalar codePoint -> Char.ConvertFromUtf32 codePoint
8281
| _ -> replacementChar
8382

84-
8583
// https://github.com/dotnet/fsharp/blob/master/src/fsharp/PrettyNaming.fs
8684
/// The characters that are allowed to be the first character of an identifier.
8785
let IsIdentifierFirstCharacter c =
@@ -161,9 +159,9 @@ let symbolsToUnderscores s =
161159
// Insert underscores at word boundaries inferred from case changes
162160
let wordCaseBoundaries s =
163161
s
164-
|> fun s -> Regex.Replace ( s , @"(\p{Lu})(\p{Ll})" , "_$1$2" ) // upper then lower
165-
|> fun s -> Regex.Replace ( s , @"([^_\p{Lu}])([\p{Lu}])" , "$1_$2" ) // upper after non upper
166-
|> fun s -> Regex.Replace ( s , @"(\p{Nd})([\p{Lu}\p{Ll}])" , "$1_$2" ) // upper/lower after digit
162+
|> fun s -> Regex.Replace ( s , @"(\p{Lu})(\p{Ll})" , "_$1$2" , RegexOptions.None , TimeSpan.FromSeconds 10. ) // upper then lower
163+
|> fun s -> Regex.Replace ( s , @"([^_\p{Lu}])([\p{Lu}])" , "$1_$2" , RegexOptions.None , TimeSpan.FromSeconds 10. ) // upper after non upper
164+
|> fun s -> Regex.Replace ( s , @"(\p{Nd})([\p{Lu}\p{Ll}])" , "$1_$2" , RegexOptions.None , TimeSpan.FromSeconds 10. ) // upper/lower after digit
167165

168166
let capitalize ( s : string ) = s.[ 0 ].ToString().ToUpperInvariant() + s.[ 1 .. ].ToLowerInvariant()
169167

@@ -241,7 +239,7 @@ let rec selectorPreludesFromCss text =
241239
text
242240
, selectorsAndBlockCapture
243241
, RegexOptions.IgnorePatternWhitespace ||| RegexOptions.ExplicitCapture
244-
, TimeSpan.FromSeconds 5.
242+
, TimeSpan.FromSeconds 10.
245243
)
246244
|> Seq.cast
247245
|> Seq.map ( fun ( m : Match ) -> m.Groups.[ "selectors" ].Value.Trim() , m.Groups.[ "blockcontent" ].Value )
@@ -257,7 +255,7 @@ let classNamesFromSelectorText text =
257255
text
258256
, classCapture
259257
, RegexOptions.IgnorePatternWhitespace ||| RegexOptions.ExplicitCapture
260-
, TimeSpan.FromSeconds 5.
258+
, TimeSpan.FromSeconds 10.
261259
)
262260
|> Seq.cast
263261
|> Seq.map ( fun ( m : Match ) ->
@@ -273,6 +271,8 @@ let classNamesFromSelectorText text =
273271
else
274272
escapeStr
275273
)
274+
, RegexOptions.None
275+
, TimeSpan.FromSeconds 10.
276276
)
277277
|> replaceNonHtml
278278
)
@@ -386,9 +386,7 @@ let getPropertiesFromCss text naming nameCollisions =
386386
let parseCss text naming nameCollisions =
387387

388388
// Remove comments
389-
let text =
390-
text
391-
|> fun t -> Regex.Replace( t , @"\s*/\*([^*]|\*(?!/))*\*/\s*" , "" , RegexOptions.None , TimeSpan.FromSeconds 5. )
389+
let text = Regex.Replace( text , @"\s*/\*([^*]|\*(?!/))*\*/\s*" , "" , RegexOptions.None , TimeSpan.FromSeconds 10. )
392390

393391
// Check for existence of one declaration block to indicate valid css.
394392
// Used when file open fails and we are subsequently checking if file-like string is actually inline CSS.
@@ -398,14 +396,15 @@ let parseCss text naming nameCollisions =
398396
text
399397
, selectorsAndBlockCapture
400398
, RegexOptions.IgnorePatternWhitespace ||| RegexOptions.ExplicitCapture
401-
, TimeSpan.FromSeconds 5.
399+
, TimeSpan.FromSeconds 10.
402400
)
403401

404402
if cssContainsBlock then
405-
getPropertiesFromCss text naming nameCollisions |> Some
403+
getPropertiesFromCss text naming nameCollisions
404+
|> Array.sort
405+
|> Some
406406
else None
407407

408-
409408
// Hard-coded since we know we are targeting netstandard2.0
410409
// https://docs.microsoft.com/en-us/dotnet/api/system.runtime.interopservices.osplatform.create?view=netstandard-2.0
411410
let private validPlatforms = set [ "FREEBSD" ; "LINUX" ; "OSX" ; "WINDOWS" ]
@@ -454,17 +453,15 @@ let platformSpecific ( delimiters : string ) ( text : string ) =
454453
else
455454
text
456455

457-
458-
let addTypeMembersFromCss getProperties ( cssClasses : Property [] option ) ( cssType : ProvidedTypeDefinition ) =
459-
460-
let cssClasses = cssClasses |> Option.defaultValue [||]
456+
let addTypeMembersFromCss getProperties ( cssClasses : Property array ) ( cssType : ProvidedTypeDefinition ) =
461457

462458
cssClasses
463459
|> Array.iter ( fun c ->
464460
let propName , propValue = c.Name , c.Value
465-
let prop = ProvidedProperty( propName , typeof< string > , isStatic = true , getterCode = ( fun _ -> <@@ propValue @@> ) )
466-
prop.AddXmlDoc( escapeHtml propValue )
467-
cssType.AddMember prop
461+
// Use literal field instead of property for better completion list performance in IDEs
462+
let field = ProvidedField.Literal( propName , typeof< string > , propValue ) // public static literal
463+
field.SetFieldAttributes( field.Attributes ||| Reflection.FieldAttributes.InitOnly ) // prevent assignment
464+
cssType.AddMember field
468465
)
469466

470467
if getProperties then
@@ -488,4 +485,3 @@ let addTypeMembersFromCss getProperties ( cssClasses : Property [] option ) ( cs
488485
invokeCode = fun _-> <@@ propsArray @@>)
489486

490487
cssType.AddMember staticMethod
491-

0 commit comments

Comments
 (0)