22
33const log = require ( "@ui5/logger" ) . getLogger ( "lbt:resources:ResourceFilterList" ) ;
44
5- function makeMatcher ( globPattern ) {
5+ function makeFileTypePattern ( fileTypes ) {
6+ if ( fileTypes == null ) {
7+ return undefined ;
8+ }
9+ return "(?:" + fileTypes . map ( ( type ) => {
10+ if ( ! type . startsWith ( "." ) ) {
11+ type = "." + type ;
12+ }
13+ return type . replace ( / [ * + ? . ( ) | ^ $ ] / g, "\\$&" ) ;
14+ } ) . join ( "|" ) + ")" ;
15+ }
16+
17+ function makeMatcher ( globPattern , fileTypesPattern ) {
618 const result = {
719 pattern : globPattern ,
820 include : true
@@ -14,29 +26,53 @@ function makeMatcher(globPattern) {
1426 globPattern = globPattern . slice ( 1 ) ;
1527 }
1628
17- // check for wildcards
18- if ( / \* | \/ $ / . test ( globPattern ) ) {
19- if ( ! / \/ \* \* \/ $ / . test ( globPattern ) ) {
20- globPattern = globPattern . replace ( / \/ $ / , "/**/" ) ;
29+ // normalize some convenience shortcuts
30+ // - a lonely 'any sub-path' pattern implies the 'any file' pattern:
31+ // "**/" --> "**/*"
32+ // - a trailing 'any sub-path' pattern also implies the 'any file' pattern:
33+ // ".../foo/**/" --> "../foo/**/*"
34+ // - any other trailing slash matches any files in any sub-folder:
35+ // ".../foo/" --> ".../foo/**/*"
36+ if ( globPattern . endsWith ( "/" ) ) {
37+ if ( globPattern === "**/" || globPattern . endsWith ( "/**/" ) ) {
38+ globPattern = globPattern + "*" ;
39+ } else {
40+ globPattern = globPattern + "**/*" ;
2141 }
42+ }
2243
23- const regexp = globPattern . replace ( / \* \* \/ | \* | [ [ \] { } ( ) + ? . \\ ^ $ | ] / g, function ( match ) {
44+ // check for wildcards
45+ if ( / \* / . test ( globPattern ) ) {
46+ // Transform the globPattern into a regular expression pattern by converting
47+ // the "all sub-directories" pattern "/**/" and the "any file name" pattern "*"
48+ // to their respective regexp counterparts and escape all other regexp special
49+ // characters.
50+ let regexp = globPattern . replace ( / ^ \* \* \/ | \/ \* \* \/ | \* | [ [ \] { } ( ) + ? . \\ ^ $ | ] / g, ( match ) => {
2451 switch ( match ) {
2552 case "**/" : return "(?:[^/]+/)*" ;
53+ case "/**/" : return "/(?:[^/]+/)*" ;
2654 case "*" : return "[^/]*" ;
2755 default : return "\\" + match ;
2856 }
2957 } ) ;
3058
31- log . verbose ( "%s -> %s,%s" , result . pattern , "^" + regexp , result . include ? "include" : "exclude" ) ;
32- result . regexp = new RegExp ( "^" + regexp ) ;
59+ // if the pattern ended with an asterisk and if a default file type pattern is defined,
60+ // add that pattern. This limits the matches to the specified set of file types
61+ if ( fileTypesPattern != null && regexp . endsWith ( "[^/]*" ) ) {
62+ regexp = regexp + fileTypesPattern ;
63+ }
64+
65+ result . regexp = new RegExp ( "^" + regexp + "$" ) ;
3366 result . calcMatch = result . include ? function ( candidate , matchSoFar ) {
3467 return matchSoFar || this . regexp . test ( candidate ) ;
3568 } : function ( candidate , matchSoFar ) {
3669 return matchSoFar && ! this . regexp . test ( candidate ) ;
3770 } ;
71+
72+ log . verbose ( ` ${ result . pattern } --> ${ result . include ? "include" : "exclude" } : /${ result . regexp . source } /` ) ;
3873 } else {
3974 result . value = globPattern ;
75+ log . verbose ( ` ${ result . pattern } --> ${ result . include ? "include" : "exclude" } : "${ globPattern } "` ) ;
4076 result . calcMatch = result . include ? function ( candidate , matchSoFar ) {
4177 return matchSoFar || candidate === this . value ;
4278 } : function ( candidate , matchSoFar ) {
@@ -56,19 +92,20 @@ function makeMatcher(globPattern) {
5692 * @author Frank Weigel
5793 * @since 1.16.2
5894 * @private
59- * TODO Share with plugins, esp. coldWater, lightening, ...
6095 */
6196class ResourceFilterList {
62- constructor ( filters ) {
97+ constructor ( filters , fileTypes ) {
6398 this . matchers = [ ] ;
6499 this . matchByDefault = true ;
100+ this . fileTypes = makeFileTypePattern ( fileTypes ) ;
101+ log . verbose ( `filetypes: ${ fileTypes } ` ) ;
65102 this . addFilters ( filters ) ;
66103 }
67104
68105 addFilters ( filters ) {
69106 if ( Array . isArray ( filters ) ) {
70107 filters . forEach ( ( filter ) => {
71- const matcher = makeMatcher ( filter ) ;
108+ const matcher = makeMatcher ( filter , this . fileTypes ) ;
72109 this . matchers . push ( matcher ) ;
73110 this . matchByDefault = this . matchByDefault && ! matcher . include ;
74111 } ) ;
@@ -78,59 +115,6 @@ class ResourceFilterList {
78115 return this ;
79116 }
80117
81- /* NODE-TODO
82- public ResourceFilterList addIncludes(String[] includes){
83- if ( includes != null ) {
84- for(String include : includes) {
85- add(include, false);
86- }
87- }
88- return this;
89- }
90-
91- public ResourceFilterList addExcludes(String[] excludes) {
92- if ( excludes != null ) {
93- for(String exclude : excludes) {
94- add(exclude, true);
95- }
96- }
97- return this;
98- }
99-
100- /**
101- * old style resource pattern (from old Optimizer)
102- * @param excludePattern
103- * @deprecated Use the more flexible add or addFilters instead.
104- *
105- public void addExcludePattern(Pattern excludePattern) {
106- isExclude.set(patterns.size(), true);
107- patterns.add(excludePattern);
108- }
109-
110- public ResourceFilterList add(String patternList, boolean exclude) {
111- for(String pattern : patternList.trim().split("\\s*,\\s*")) {
112- if ( !pattern.isEmpty() ) {
113- isExclude.set(patterns.size(), exclude);
114- patterns.add(ModuleNamePattern.createRegEx(pattern, ignoreCase));
115- hasInclude = hasInclude || !exclude;
116- }
117- }
118- return this;
119- }
120-
121- public ResourceFilterList add(String patternList) {
122- for(String pattern : patternList.trim().split("\\s*,\\s*")) {
123- if ( !pattern.isEmpty() ) {
124- boolean exclude = pattern.startsWith("!") || pattern.startsWith("-");
125- isExclude.set(patterns.size(), exclude);
126- patterns.add(ModuleNamePattern.createRegEx(exclude || pattern.startsWith("+")
127- ? pattern.substring(1) : pattern, ignoreCase));
128- hasInclude = hasInclude || !exclude;
129- }
130- }
131- return this;
132- } */
133-
134118 matches ( candidate , initialMatch ) {
135119 return this . matchers . reduce (
136120 ( acc , cur ) => cur . calcMatch ( candidate , acc ) ,
@@ -146,7 +130,7 @@ class ResourceFilterList {
146130ResourceFilterList . fromString = function ( filterStr ) {
147131 const result = new ResourceFilterList ( ) ;
148132 if ( filterStr != null ) {
149- result . addFilters ( filterStr . trim ( ) . split ( / \s * , \s * / ) ) ;
133+ result . addFilters ( filterStr . trim ( ) . split ( / \s * , \s * / ) . filter ( Boolean ) ) ;
150134 }
151135 return result ;
152136} ;
0 commit comments