4
4
5
5
using System ;
6
6
using System . Collections . Generic ;
7
+ using System . Globalization ;
7
8
using System . Linq ;
8
9
using UnityEditor . Scripting . Compilers ;
9
10
using File = System . IO . File ;
@@ -32,6 +33,7 @@ internal class TargetAssembly
32
33
public string Filename { get ; private set ; }
33
34
public SupportedLanguage Language { get ; set ; }
34
35
public AssemblyFlags Flags { get ; private set ; }
36
+ public string PathPrefix { get ; private set ; }
35
37
public Func < string , int > PathFilter { get ; private set ; }
36
38
public Func < BuildTarget , EditorScriptCompilationOptions , bool > IsCompatibleFunc { get ; private set ; }
37
39
public List < TargetAssembly > References { get ; private set ; }
@@ -42,17 +44,18 @@ public TargetAssembly()
42
44
References = new List < TargetAssembly > ( ) ;
43
45
}
44
46
45
- public TargetAssembly ( string name , SupportedLanguage language , AssemblyFlags flags , TargetAssemblyType type )
46
- : this ( name , language , flags , type , null , null )
47
- {
48
- }
49
-
50
- public TargetAssembly ( string name , SupportedLanguage language , AssemblyFlags flags , TargetAssemblyType type ,
51
- Func < string , int > pathFilter , Func < BuildTarget , EditorScriptCompilationOptions , bool > compatFunc ) : this ( )
47
+ public TargetAssembly ( string name ,
48
+ SupportedLanguage language ,
49
+ AssemblyFlags flags ,
50
+ TargetAssemblyType type ,
51
+ string pathPrefix ,
52
+ Func < string , int > pathFilter ,
53
+ Func < BuildTarget , EditorScriptCompilationOptions , bool > compatFunc ) : this ( )
52
54
{
53
55
Language = language ;
54
56
Filename = name ;
55
57
Flags = flags ;
58
+ PathPrefix = pathPrefix ;
56
59
PathFilter = pathFilter ;
57
60
IsCompatibleFunc = compatFunc ;
58
61
Type = type ;
@@ -145,6 +148,35 @@ public static PrecompiledAssembly CreateEditorCompiledAssembly(string path)
145
148
} ;
146
149
}
147
150
151
+ internal static bool FastStartsWith ( string str , string prefix , string prefixLowercase )
152
+ {
153
+ int strLength = str . Length ;
154
+ int prefixLength = prefix . Length ;
155
+
156
+ if ( prefixLength > strLength )
157
+ return false ;
158
+
159
+ int lastPrefixCharIndex = prefixLength - 1 ;
160
+
161
+ // Check last char in prefix is equal. Since we are comparing
162
+ // file paths against directory paths, the last char will be '/'.
163
+ if ( str [ lastPrefixCharIndex ] != prefix [ lastPrefixCharIndex ] )
164
+ return false ;
165
+
166
+ for ( int i = 0 ; i < prefixLength ; ++ i )
167
+ {
168
+ if ( str [ i ] == prefix [ i ] )
169
+ continue ;
170
+
171
+ char strC = char . ToLower ( str [ i ] , CultureInfo . InvariantCulture ) ;
172
+
173
+ if ( strC != prefixLowercase [ i ] )
174
+ return false ;
175
+ }
176
+
177
+ return true ;
178
+ }
179
+
148
180
public static TargetAssembly [ ] CreateTargetAssemblies ( IEnumerable < CustomScriptAssembly > customScriptAssemblies )
149
181
{
150
182
if ( customScriptAssemblies == null )
@@ -162,13 +194,18 @@ public static TargetAssembly[] CreateTargetAssemblies(IEnumerable<CustomScriptAs
162
194
var targetAssemblies = new List < TargetAssembly > ( ) ;
163
195
var nameToTargetAssembly = new Dictionary < string , TargetAssembly > ( ) ;
164
196
197
+
165
198
// Create TargetAssemblies
166
199
foreach ( var customAssembly in customScriptAssemblies )
167
200
{
168
- var pathPrefixLowerCase = customAssembly . PathPrefix . ToLower ( ) ;
169
-
170
- var targetAssembly = new TargetAssembly ( customAssembly . Name + ".dll" , null , customAssembly . AssemblyFlags ,
171
- TargetAssemblyType . Custom , path => path . StartsWith ( pathPrefixLowerCase ) ? pathPrefixLowerCase . Length : - 1 ,
201
+ var lowerPathPrefix = customAssembly . PathPrefix . ToLower ( CultureInfo . InvariantCulture ) ;
202
+
203
+ var targetAssembly = new TargetAssembly ( customAssembly . Name + ".dll" ,
204
+ null ,
205
+ customAssembly . AssemblyFlags ,
206
+ TargetAssemblyType . Custom ,
207
+ customAssembly . PathPrefix ,
208
+ path => FastStartsWith ( path , customAssembly . PathPrefix , lowerPathPrefix ) ? customAssembly . PathPrefix . Length : - 1 ,
172
209
( BuildTarget target , EditorScriptCompilationOptions options ) => customAssembly . IsCompatibleWith ( target , options ) ) ;
173
210
174
211
targetAssemblies . Add ( targetAssembly ) ;
@@ -607,17 +644,37 @@ internal static TargetAssembly[] CreatePredefinedTargetAssemblies()
607
644
{
608
645
var languageName = language . GetLanguageName ( ) ;
609
646
610
- var runtimeFirstPass = new TargetAssembly ( "Assembly-" + languageName + "-firstpass" + ".dll" , language ,
611
- AssemblyFlags . FirstPass , TargetAssemblyType . Predefined , FilterAssemblyInFirstpassFolder , null ) ;
612
-
613
- var runtime = new TargetAssembly ( "Assembly-" + languageName + ".dll" , language , AssemblyFlags . None , TargetAssemblyType . Predefined ) ;
614
-
615
- var editorFirstPass = new TargetAssembly ( "Assembly-" + languageName + "-Editor-firstpass" + ".dll" , language ,
616
- AssemblyFlags . EditorOnly | AssemblyFlags . FirstPass , TargetAssemblyType . Predefined , FilterAssemblyInFirstpassEditorFolder ,
647
+ var runtimeFirstPass = new TargetAssembly ( "Assembly-" + languageName + "-firstpass" + ".dll" ,
648
+ language ,
649
+ AssemblyFlags . FirstPass ,
650
+ TargetAssemblyType . Predefined ,
651
+ null ,
652
+ FilterAssemblyInFirstpassFolder ,
653
+ null ) ;
654
+
655
+ var runtime = new TargetAssembly ( "Assembly-" + languageName + ".dll" ,
656
+ language ,
657
+ AssemblyFlags . None ,
658
+ TargetAssemblyType . Predefined ,
659
+ null ,
660
+ null ,
661
+ null ) ;
662
+
663
+ var editorFirstPass = new TargetAssembly ( "Assembly-" + languageName + "-Editor-firstpass" + ".dll" ,
664
+ language ,
665
+ AssemblyFlags . EditorOnly | AssemblyFlags . FirstPass ,
666
+ TargetAssemblyType . Predefined ,
667
+ null ,
668
+ FilterAssemblyInFirstpassEditorFolder ,
617
669
IsCompatibleWithEditor ) ;
618
670
619
- var editor = new TargetAssembly ( "Assembly-" + languageName + "-Editor" + ".dll" , language ,
620
- AssemblyFlags . EditorOnly , TargetAssemblyType . Predefined , FilterAssemblyInEditorFolder , IsCompatibleWithEditor ) ;
671
+ var editor = new TargetAssembly ( "Assembly-" + languageName + "-Editor" + ".dll" ,
672
+ language ,
673
+ AssemblyFlags . EditorOnly ,
674
+ TargetAssemblyType . Predefined ,
675
+ null ,
676
+ FilterAssemblyInEditorFolder ,
677
+ IsCompatibleWithEditor ) ;
621
678
622
679
runtimeFirstPassAssemblies . Add ( runtimeFirstPass ) ;
623
680
runtimeAssemblies . Add ( runtime ) ;
@@ -702,11 +759,16 @@ internal static TargetAssembly GetCustomTargetAssembly(string scriptPath, string
702
759
703
760
// CustomScriptAssembly paths are absolute, so we convert the scriptPath to an absolute path, if necessary.
704
761
bool isPathAbsolute = AssetPath . IsPathRooted ( scriptPath ) ;
705
- var lowerFullPath = isPathAbsolute ? AssetPath . GetFullPath ( scriptPath ) . ToLower ( ) : AssetPath . Combine ( projectDirectory , scriptPath ) . ToLower ( ) ;
762
+ var fullPath = isPathAbsolute ? AssetPath . GetFullPath ( scriptPath ) : AssetPath . Combine ( projectDirectory , scriptPath ) ;
706
763
707
764
foreach ( var assembly in customTargetAssemblies )
708
765
{
709
- int pathDepth = assembly . PathFilter ( lowerFullPath ) ;
766
+ int maxPathDepth = assembly . PathPrefix . Length ;
767
+
768
+ if ( maxPathDepth <= highestPathDepth )
769
+ continue ;
770
+
771
+ int pathDepth = assembly . PathFilter ( fullPath ) ;
710
772
711
773
if ( pathDepth <= highestPathDepth )
712
774
continue ;
@@ -748,15 +810,15 @@ static int FilterAssemblyInFirstpassEditorFolder(string pathName)
748
810
static int FilterAssemblyInEditorFolder ( string pathName )
749
811
{
750
812
const string editorSegment = "/editor/" ;
751
- int editorSegmentIndex = pathName . IndexOf ( editorSegment ) ;
813
+ int editorSegmentIndex = pathName . IndexOf ( editorSegment , StringComparison . InvariantCulture ) ;
752
814
if ( editorSegmentIndex == - 1 ) return - 1 ;
753
815
754
816
return editorSegmentIndex + editorSegment . Length ;
755
817
}
756
818
757
- static int FilterAssemblyPathBeginsWith ( string pathName , string prefix )
819
+ static int FilterAssemblyPathBeginsWith ( string pathName , string lowerPrefix )
758
820
{
759
- return pathName . StartsWith ( prefix ) ? prefix . Length : - 1 ;
821
+ return FastStartsWith ( pathName , lowerPrefix , lowerPrefix ) ? lowerPrefix . Length : - 1 ;
760
822
}
761
823
}
762
824
}
0 commit comments