Merge "Workarounds for HLJS parsing issues"
This commit is contained in:
commit
82ef5ed510
@ -78,6 +78,10 @@
|
||||
'gr-diff gr-syntax gr-syntax-selector-class': true,
|
||||
};
|
||||
|
||||
var CPP_DIRECTIVE_WITH_LT_PATTERN = /^\s*#(if|define).*</;
|
||||
var JAVA_PARAM_ANNOT_PATTERN = /(@[^\s]+)\(([^)]+)\)/g;
|
||||
var GLOBAL_LT_PATTERN = /</g;
|
||||
|
||||
Polymer({
|
||||
is: 'gr-syntax-layer',
|
||||
|
||||
@ -301,6 +305,7 @@
|
||||
var result;
|
||||
|
||||
if (this._baseLanguage && baseLine !== undefined) {
|
||||
baseLine = this._workaround(this._baseLanguage, baseLine);
|
||||
result = this._hljs.highlight(this._baseLanguage, baseLine, true,
|
||||
state.baseContext);
|
||||
this.push('_baseRanges', this._rangesFromString(result.value));
|
||||
@ -308,6 +313,7 @@
|
||||
}
|
||||
|
||||
if (this._revisionLanguage && revisionLine !== undefined) {
|
||||
revisionLine = this._workaround(this._revisionLanguage, revisionLine);
|
||||
result = this._hljs.highlight(this._revisionLanguage, revisionLine,
|
||||
true, state.revisionContext);
|
||||
this.push('_revisionRanges', this._rangesFromString(result.value));
|
||||
@ -315,6 +321,50 @@
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Ad hoc fixes for HLJS parsing bugs. Rewrite lines of code in constrained
|
||||
* cases before sending them into HLJS so that they parse correctly.
|
||||
*
|
||||
* Important notes:
|
||||
* * These tests should be as constrained as possible to avoid interfering
|
||||
* with code it shouldn't AND to avoid executing regexes as much as
|
||||
* possible.
|
||||
* * These tests should document the issue clearly enough that the test can
|
||||
* be condidently removed when the issue is solved in HLJS.
|
||||
* * These tests should rewrite the line of code to have the same number of
|
||||
* characters. This method rewrites the string that gets parsed, but NOT
|
||||
* the string that gets displayed and highlighted. Thus, the positions
|
||||
* must be consistent.
|
||||
*
|
||||
* @param {!string} language The name of the HLJS language plugin in use.
|
||||
* @param {!string} line The line of code to potentially rewrite.
|
||||
* @return {string} A potentially-rewritten line of code.
|
||||
*/
|
||||
_workaround: function(language, line) {
|
||||
/**
|
||||
* Prevent confusing < and << operators for the start of a meta string by
|
||||
* converting them to a different operator.
|
||||
* {@see Issue 4864}
|
||||
* {@see https://github.com/isagalaev/highlight.js/issues/1341}
|
||||
*/
|
||||
if (language === 'cpp' && CPP_DIRECTIVE_WITH_LT_PATTERN.test(line)) {
|
||||
return line.replace(GLOBAL_LT_PATTERN, '|');
|
||||
}
|
||||
|
||||
/**
|
||||
* Prevent confusing the closing paren of a parameterized Java annotation
|
||||
* being applied to a formal argument as the closing paren of the argument
|
||||
* list. Rewrite the parens as spaces.
|
||||
* {@see Issue 4776}
|
||||
* {@see https://github.com/isagalaev/highlight.js/issues/1324}
|
||||
*/
|
||||
if (language === 'java' && JAVA_PARAM_ANNOT_PATTERN.test(line)) {
|
||||
return line.replace(JAVA_PARAM_ANNOT_PATTERN, '$1 $2 ');
|
||||
}
|
||||
|
||||
return line;
|
||||
},
|
||||
|
||||
/**
|
||||
* Tells whether the state has exhausted its current section.
|
||||
* @param {!Object} state
|
||||
|
@ -404,5 +404,41 @@ limitations under the License.
|
||||
state = {sectionIndex: 3, lineIndex: 4};
|
||||
assert.isTrue(element._isSectionDone(state));
|
||||
});
|
||||
|
||||
test('workaround CPP LT directive', function() {
|
||||
// Does nothing to regular line.
|
||||
var line = 'int main(int argc, char** argv) { return 0; }';
|
||||
assert.equal(element._workaround('cpp', line), line);
|
||||
|
||||
// Does nothing to include directive.
|
||||
line = '#include <stdio>';
|
||||
assert.equal(element._workaround('cpp', line), line);
|
||||
|
||||
// Converts left-shift operator in #define.
|
||||
line = '#define GiB (1ull << 30)';
|
||||
var expected = '#define GiB (1ull || 30)';
|
||||
assert.equal(element._workaround('cpp', line), expected);
|
||||
|
||||
// Converts less-than operator in #if.
|
||||
line = ' #if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 1)';
|
||||
expected = ' #if __GNUC__ | 4 || (__GNUC__ == 4 && __GNUC_MINOR__ | 1)';
|
||||
assert.equal(element._workaround('cpp', line), expected);
|
||||
});
|
||||
|
||||
test('workaround Java param-annotation', function() {
|
||||
// Does nothing to regular line.
|
||||
var line = 'public static void foo(int bar) { }';
|
||||
assert.equal(element._workaround('java', line), line);
|
||||
|
||||
// Does nothing to regular annotation.
|
||||
var line = 'public static void foo(@Nullable int bar) { }';
|
||||
assert.equal(element._workaround('java', line), line);
|
||||
|
||||
// Converts parameterized annotation.
|
||||
line = 'public static void foo(@SuppressWarnings("unused") int bar) { }';
|
||||
var expected = 'public static void foo(@SuppressWarnings "unused" ' +
|
||||
' int bar) { }';
|
||||
assert.equal(element._workaround('java', line), expected);
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
Loading…
Reference in New Issue
Block a user