• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

i-net-software / jlessc / 281

pending completion
281

push

travis-ci-com

volker
Handle doubled rule correctly in the compressed formatter if previous
rule ends with an block

5 of 5 new or added lines in 1 file covered. (100.0%)

3586 of 3873 relevant lines covered (92.59%)

2.78 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

84.0
/src/com/inet/lib/less/RegExp.java
1
/**
2
 * MIT License (MIT)
3
 *
4
 * Copyright (c) 2014 - 2015 Volker Berlin
5
 *
6
 * Permission is hereby granted, free of charge, to any person obtaining a copy
7
 * of this software and associated documentation files (the "Software"), to deal
8
 * in the Software without restriction, including without limitation the rights
9
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
 * copies of the Software, and to permit persons to whom the Software is
11
 * furnished to do so, subject to the following conditions:
12
 * 
13
 * The above copyright notice and this permission notice shall be included in
14
 * all copies or substantial portions of the Software.
15
 * 
16
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
 * UT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22
 * THE SOFTWARE.
23
 *
24
 * @author Volker Berlin
25
 * @license: The MIT license <http://opensource.org/licenses/MIT>
26
 */
27
package com.inet.lib.less;
28

29
import java.util.regex.Matcher;
30
import java.util.regex.Pattern;
31

32
/**
33
 * Converter for less regular expressions and Java regular expressiosn
34
 */
35
class RegExp {
36

37
    // In JS syntax, a \ in the replacement string has no special meaning.
38
    // In Java syntax, a \ in the replacement string escapes the next character,
39
    // so we have to translate \ to \\ before passing it to Java.
40
    private static final Pattern REPLACEMENT_BACKSLASH                 = Pattern.compile( "\\\\" );
3✔
41

42
    // To get \\, we have to say \\\\\\\\:
43
    // \\\\\\\\ --> Java string unescape --> \\\\
44
    // \\\\ ---> Pattern replacement unescape in replacement preprocessing --> \\
45
    private static final String  REPLACEMENT_BACKSLASH_FOR_JAVA        = "\\\\\\\\";
46

47
    // In JS syntax, a $& in the replacement string stands for the whole match.
48
    // In Java syntax, the equivalent is $0, so we have to translate $& to
49
    // $0 before passing it to Java. However, we have to watch out for $$&, which
50
    // is actually a Javascript $$ (see below) followed by a & with no special
51
    // meaning, and must not get translated.
52
    private static final Pattern REPLACEMENT_DOLLAR_AMPERSAND          = Pattern.compile( "((?:^|\\G|[^$])(?:\\$\\$)*)\\$&" );
3✔
53

54
    private static final String  REPLACEMENT_DOLLAR_AMPERSAND_FOR_JAVA = "$1\\$0";
55

56
    // In JS syntax, a $` and $' in the replacement string stand for everything
57
    // before the match and everything after the match.
58
    // In Java syntax, there is no equivalent, so we detect and reject $` and $'.
59
    // However, we have to watch out for $$` and $$', which are actually a JS $$
60
    // (see below) followed by a ` or ' with no special meaning, and must not be
61
    // rejected.
62
    private static final Pattern REPLACEMENT_DOLLAR_APOSTROPHE         = Pattern.compile( "(?:^|[^$])(?:\\$\\$)*\\$[`']" );
3✔
63

64
    // In JS syntax, a $$ in the replacement string stands for a (single) dollar
65
    // sign, $.
66
    // In Java syntax, the equivalent is \$, so we have to translate $$ to \$
67
    // before passing it to Java.
68
    private static final Pattern REPLACEMENT_DOLLAR_DOLLAR             = Pattern.compile( "\\$\\$" );
3✔
69

70
    // To get \$, we have to say \\\\\\$:
71
    // \\\\\\$ --> Java string unescape --> \\\$
72
    // \\\$ ---> Pattern replacement unescape in replacement preprocessing --> \$
73
    private static final String  REPLACEMENT_DOLLAR_DOLLAR_FOR_JAVA    = "\\\\\\$";
74

75
    private boolean              global;
76

77
    private final Pattern        pattern;
78

79
    /**
80
     * Create an new instance.
81
     * @param pattern the regular expression pattern
82
     * @param flags some flags
83
     * @throws ParameterOutOfBoundsException if the flags are invalid
84
     */
85
    RegExp( String pattern, String flags ) throws ParameterOutOfBoundsException {
3✔
86
        int patternFlags = Pattern.UNIX_LINES;
3✔
87
        for( int i = 0; i < flags.length(); i++ ) {
3✔
88
            char flag = flags.charAt( i );
3✔
89
            switch( flag ) {
3✔
90
                case 'g':
91
                    global = true;
3✔
92
                    break;
3✔
93
                case 'i':
94
                    patternFlags |= Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE;
3✔
95
                    break;
3✔
96
                case 'm':
97
                    patternFlags |= Pattern.MULTILINE;
×
98
                    break;
×
99
                default:
100
                    throw new ParameterOutOfBoundsException();
×
101
            }
102
        }
103
        this.pattern = Pattern.compile( pattern, patternFlags );
3✔
104
    }
3✔
105

106
    /**
107
     * Replace the matches in the input with the replacement.
108
     * @param input the input string
109
     * @param replacement the replacement
110
     * @return the resulting string
111
     * @throws ParameterOutOfBoundsException if Java can not replace it like Javascript
112
     */
113
    public String replace( String input, String replacement ) throws ParameterOutOfBoundsException {
114
        // Replace \ in the replacement with \\ to escape it for Java replace.
115
        replacement = REPLACEMENT_BACKSLASH.matcher( replacement ).replaceAll( REPLACEMENT_BACKSLASH_FOR_JAVA );
3✔
116

117
        // Replace the Javascript-ese $& in the replacement with Java-ese $0, but
118
        // watch out for $$&, which should stay $$&, to be changed to \$& below.
119
        replacement = REPLACEMENT_DOLLAR_AMPERSAND.matcher( replacement ).replaceAll( REPLACEMENT_DOLLAR_AMPERSAND_FOR_JAVA );
3✔
120

121
        // Test for Javascript-ese $` and $', which we do not support in the pure
122
        // Java version.
123
        if( REPLACEMENT_DOLLAR_APOSTROPHE.matcher( replacement ).find() ) {
3✔
124
            throw new ParameterOutOfBoundsException();
×
125
        }
126

127
        // Replace the Javascript-ese $$ in the replacement with Java-ese \$.
128
        replacement = REPLACEMENT_DOLLAR_DOLLAR.matcher( replacement ).replaceAll( REPLACEMENT_DOLLAR_DOLLAR_FOR_JAVA );
3✔
129

130
        Matcher matcher = pattern.matcher( input );
3✔
131
        return global ? matcher.replaceAll( replacement ) : matcher.replaceFirst( replacement );
3✔
132
    }
133
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc