-
-
Notifications
You must be signed in to change notification settings - Fork 34
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fixes valentjn/vscode-ltex#350.
- Loading branch information
Showing
13 changed files
with
678 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
115 changes: 115 additions & 0 deletions
115
src/main/java/org/bsplines/ltexls/parsing/program/ProgramAnnotatedTextBuilder.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,115 @@ | ||
/* Copyright (C) 2020 Julian Valentin, LTeX Development Community | ||
* | ||
* This Source Code Form is subject to the terms of the Mozilla Public | ||
* License, v. 2.0. If a copy of the MPL was not distributed with this | ||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. | ||
*/ | ||
|
||
package org.bsplines.ltexls.parsing.program; | ||
|
||
import java.util.regex.Matcher; | ||
import java.util.regex.Pattern; | ||
import org.bsplines.ltexls.parsing.CodeAnnotatedTextBuilder; | ||
import org.bsplines.ltexls.parsing.markdown.MarkdownAnnotatedTextBuilder; | ||
import org.bsplines.ltexls.tools.Tools; | ||
import org.checkerframework.checker.nullness.qual.Nullable; | ||
import org.languagetool.markup.AnnotatedText; | ||
|
||
public class ProgramAnnotatedTextBuilder extends CodeAnnotatedTextBuilder { | ||
private static final Pattern lineSeparatorPattern = Pattern.compile("\r?\n"); | ||
private static final Pattern firstCharacterPattern = Pattern.compile( | ||
"^[ \t]*(?:([#$%*+\\-/])|(.))"); | ||
|
||
private MarkdownAnnotatedTextBuilder markdownAnnotatedTextBuilder; | ||
private Pattern commentBlockPattern; | ||
private @Nullable String lineCommentPatternString; | ||
|
||
public ProgramAnnotatedTextBuilder(String codeLanguageId) { | ||
super(codeLanguageId); | ||
|
||
this.markdownAnnotatedTextBuilder = new MarkdownAnnotatedTextBuilder("markdown"); | ||
|
||
ProgramCommentPatterns commentPatterns = new ProgramCommentPatterns(codeLanguageId); | ||
this.commentBlockPattern = commentPatterns.getCommentBlockPattern(); | ||
this.lineCommentPatternString = commentPatterns.getLineCommentPatternString(); | ||
} | ||
|
||
@Override | ||
public CodeAnnotatedTextBuilder addCode(String code) { | ||
Matcher commentBlockMatcher = this.commentBlockPattern.matcher(code); | ||
int curPos = 0; | ||
|
||
while (commentBlockMatcher.find()) { | ||
int lastPos = curPos; | ||
boolean isLineComment = (commentBlockMatcher.group("lineComment") != null); | ||
String groupName = (isLineComment ? "lineComment" : "blockComment"); | ||
curPos = commentBlockMatcher.start(groupName); | ||
this.markdownAnnotatedTextBuilder.addMarkup(code.substring(lastPos, curPos), "\n\n"); | ||
@Nullable String comment = commentBlockMatcher.group(groupName); | ||
|
||
if (comment == null) { | ||
Tools.logger.warning(Tools.i18n( | ||
"couldNotFindExpectedGroupInRegularExpressionMatch", groupName)); | ||
continue; | ||
} | ||
|
||
addComment(comment, isLineComment); | ||
curPos = commentBlockMatcher.end(groupName); | ||
} | ||
|
||
if (curPos < code.length()) this.markdownAnnotatedTextBuilder.addMarkup(code.substring(curPos)); | ||
|
||
return this; | ||
} | ||
|
||
private CodeAnnotatedTextBuilder addComment(String comment, boolean isLineComment) { | ||
String commonFirstCharacter = ""; | ||
|
||
for (String line : lineSeparatorPattern.split(comment)) { | ||
Matcher firstCharacterMatcher = firstCharacterPattern.matcher(line); | ||
if (!firstCharacterMatcher.find()) continue; | ||
@Nullable String firstCharacter = firstCharacterMatcher.group(1); | ||
|
||
if (firstCharacter == null) { | ||
commonFirstCharacter = ""; | ||
break; | ||
} | ||
|
||
if (commonFirstCharacter.isEmpty()) { | ||
commonFirstCharacter = firstCharacter; | ||
} else if (!firstCharacter.equals(commonFirstCharacter)) { | ||
commonFirstCharacter = ""; | ||
break; | ||
} | ||
} | ||
|
||
Pattern lineContentsPattern = Pattern.compile( | ||
"[ \t]*" | ||
+ ((isLineComment && (this.lineCommentPatternString != null)) | ||
? this.lineCommentPatternString : "") | ||
+ "(?:" + Pattern.quote(commonFirstCharacter) + ")?[ \t]*(.*?)(?:\r?\n|$)"); | ||
Matcher lineContentsMatcher = lineContentsPattern.matcher(comment); | ||
int curPos = 0; | ||
|
||
while (lineContentsMatcher.find()) { | ||
int lastPos = curPos; | ||
curPos = lineContentsMatcher.start(1); | ||
this.markdownAnnotatedTextBuilder.addMarkup(comment.substring(lastPos, curPos), "\n"); | ||
|
||
lastPos = curPos; | ||
curPos = lineContentsMatcher.end(1); | ||
this.markdownAnnotatedTextBuilder.addCode(comment.substring(lastPos, curPos)); | ||
} | ||
|
||
if (curPos < comment.length()) { | ||
this.markdownAnnotatedTextBuilder.addMarkup(comment.substring(curPos)); | ||
} | ||
|
||
return this; | ||
} | ||
|
||
@Override | ||
public AnnotatedText build() { | ||
return this.markdownAnnotatedTextBuilder.build(); | ||
} | ||
} |
144 changes: 144 additions & 0 deletions
144
src/main/java/org/bsplines/ltexls/parsing/program/ProgramCommentPatterns.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,144 @@ | ||
/* Copyright (C) 2020 Julian Valentin, LTeX Development Community | ||
* | ||
* This Source Code Form is subject to the terms of the Mozilla Public | ||
* License, v. 2.0. If a copy of the MPL was not distributed with this | ||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. | ||
*/ | ||
|
||
package org.bsplines.ltexls.parsing.program; | ||
|
||
import java.util.regex.Pattern; | ||
import org.checkerframework.checker.nullness.qual.MonotonicNonNull; | ||
import org.checkerframework.checker.nullness.qual.Nullable; | ||
|
||
public class ProgramCommentPatterns { | ||
private @MonotonicNonNull String blockCommentStartPatternString; | ||
private @MonotonicNonNull String blockCommentEndPatternString; | ||
private @MonotonicNonNull String lineCommentPatternString; | ||
|
||
public ProgramCommentPatterns(String codeLanguageId) { | ||
if (codeLanguageId.equals("c") | ||
|| codeLanguageId.equals("cpp") | ||
|| codeLanguageId.equals("csharp") | ||
|| codeLanguageId.equals("dart") | ||
|| codeLanguageId.equals("fsharp") | ||
|| codeLanguageId.equals("go") | ||
|| codeLanguageId.equals("groovy") | ||
|| codeLanguageId.equals("java") | ||
|| codeLanguageId.equals("javascript") | ||
|| codeLanguageId.equals("javascriptreact") | ||
|| codeLanguageId.equals("kotlin") | ||
|| codeLanguageId.equals("php") | ||
|| codeLanguageId.equals("rust") | ||
|| codeLanguageId.equals("scala") | ||
|| codeLanguageId.equals("swift") | ||
|| codeLanguageId.equals("typescript") | ||
|| codeLanguageId.equals("typescriptreact") | ||
|| codeLanguageId.equals("verilog")) { | ||
this.blockCommentStartPatternString = "/\\*\\*?"; | ||
this.blockCommentEndPatternString = "\\*\\*?/"; | ||
this.lineCommentPatternString = "///?"; | ||
} else if (codeLanguageId.equals("elixir") | ||
|| codeLanguageId.equals("python")) { | ||
this.blockCommentStartPatternString = "\"\"\""; | ||
this.blockCommentEndPatternString = "\"\"\""; | ||
this.lineCommentPatternString = "##?"; | ||
} else if (codeLanguageId.equals("powershell")) { | ||
this.blockCommentStartPatternString = "<#"; | ||
this.blockCommentEndPatternString = "#>"; | ||
this.lineCommentPatternString = "##?"; | ||
} else if (codeLanguageId.equals("coffeescript") | ||
|| codeLanguageId.equals("julia") | ||
|| codeLanguageId.equals("perl") | ||
|| codeLanguageId.equals("perl6") | ||
|| codeLanguageId.equals("puppet") | ||
|| codeLanguageId.equals("r") | ||
|| codeLanguageId.equals("ruby") | ||
|| codeLanguageId.equals("shellscript")) { | ||
this.lineCommentPatternString = "##?"; | ||
} else if (codeLanguageId.equals("lua")) { | ||
this.blockCommentStartPatternString = "--\\[\\["; | ||
this.blockCommentEndPatternString = "\\]\\]"; | ||
this.lineCommentPatternString = "---?"; | ||
} else if (codeLanguageId.equals("elm") | ||
|| codeLanguageId.equals("haskell")) { | ||
this.blockCommentStartPatternString = "\\{-"; | ||
this.blockCommentEndPatternString = "-\\}"; | ||
this.lineCommentPatternString = "---?"; | ||
} else if (codeLanguageId.equals("sql")) { | ||
this.lineCommentPatternString = "---?"; | ||
} else if (codeLanguageId.equals("clojure") | ||
|| codeLanguageId.equals("lisp")) { | ||
this.lineCommentPatternString = ";;?"; | ||
} else if (codeLanguageId.equals("matlab")) { | ||
this.blockCommentStartPatternString = "%\\{"; | ||
this.blockCommentEndPatternString = "%\\}"; | ||
this.lineCommentPatternString = "%%?"; | ||
} else if (codeLanguageId.equals("erlang")) { | ||
this.lineCommentPatternString = "%%?"; | ||
} else if (codeLanguageId.equals("fortran-modern")) { | ||
this.lineCommentPatternString = "c"; | ||
} else if (codeLanguageId.equals("vb")) { | ||
this.lineCommentPatternString = "''?"; | ||
} | ||
} | ||
|
||
public static boolean isSupportedCodeLanguageId(String codeLanguageId) { | ||
ProgramCommentPatterns patterns = new ProgramCommentPatterns(codeLanguageId); | ||
return ((patterns.blockCommentStartPatternString != null) | ||
|| (patterns.blockCommentEndPatternString != null) | ||
|| (patterns.lineCommentPatternString != null)); | ||
} | ||
|
||
public @Nullable String getBlockCommentStartPatternString() { | ||
return this.blockCommentStartPatternString; | ||
} | ||
|
||
public @Nullable String getBlockCommentEndPatternString() { | ||
return this.blockCommentEndPatternString; | ||
} | ||
|
||
public @Nullable String getLineCommentPatternString() { | ||
return this.lineCommentPatternString; | ||
} | ||
|
||
public Pattern getCommentBlockPattern() { | ||
StringBuilder patternStringBuilder = new StringBuilder(); | ||
|
||
if ((this.blockCommentStartPatternString != null) | ||
&& (this.blockCommentEndPatternString != null)) { | ||
if (patternStringBuilder.length() > 0) patternStringBuilder.append("|"); | ||
patternStringBuilder.append("^[ \t]*" + this.blockCommentStartPatternString | ||
+ "(?:[ \t]|$)(?<blockComment>(?:(?!" + this.blockCommentEndPatternString | ||
+ ").|\r?\n)*?)(?:[ \t]|^)" + this.blockCommentEndPatternString + "[ \t]*$"); | ||
} | ||
|
||
if (this.lineCommentPatternString != null) { | ||
if (patternStringBuilder.length() > 0) patternStringBuilder.append("|"); | ||
patternStringBuilder.append("(?<lineComment>(?:^[ \t]*" + this.lineCommentPatternString | ||
+ "[ \t](?:.*?)$(?:\r?\n)?)+)"); | ||
} | ||
|
||
return Pattern.compile(patternStringBuilder.toString(), Pattern.MULTILINE); | ||
} | ||
|
||
public Pattern getMagicCommentPattern() { | ||
StringBuilder patternStringBuilder = new StringBuilder(); | ||
|
||
if ((this.blockCommentStartPatternString != null) | ||
&& (this.blockCommentEndPatternString != null)) { | ||
if (patternStringBuilder.length() > 0) patternStringBuilder.append("|"); | ||
patternStringBuilder.append("^[ \t]*" + this.blockCommentStartPatternString | ||
+ "[ \t]*(?i)ltex(?-i):(.*?)[ \t]*" + this.blockCommentEndPatternString + "[ \t]*$"); | ||
} | ||
|
||
if (this.lineCommentPatternString != null) { | ||
if (patternStringBuilder.length() > 0) patternStringBuilder.append("|"); | ||
patternStringBuilder.append( | ||
"^[ \t]*" + this.lineCommentPatternString | ||
+ "[ \t]*(?i)ltex(?-i):(.*?)[ \t]*$"); | ||
} | ||
|
||
return Pattern.compile(patternStringBuilder.toString(), Pattern.MULTILINE); | ||
} | ||
} |
57 changes: 57 additions & 0 deletions
57
src/main/java/org/bsplines/ltexls/parsing/program/ProgramFragmentizer.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
/* Copyright (C) 2020 Julian Valentin, LTeX Development Community | ||
* | ||
* This Source Code Form is subject to the terms of the Mozilla Public | ||
* License, v. 2.0. If a copy of the MPL was not distributed with this | ||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. | ||
*/ | ||
|
||
package org.bsplines.ltexls.parsing.program; | ||
|
||
import java.util.ArrayList; | ||
import java.util.HashSet; | ||
import java.util.List; | ||
import org.bsplines.ltexls.parsing.CodeFragment; | ||
import org.bsplines.ltexls.parsing.RegexCodeFragmentizer; | ||
import org.bsplines.ltexls.settings.Settings; | ||
|
||
public class ProgramFragmentizer extends RegexCodeFragmentizer { | ||
public ProgramFragmentizer(String codeLanguageId) { | ||
super(codeLanguageId, (new ProgramCommentPatterns(codeLanguageId)).getMagicCommentPattern()); | ||
} | ||
|
||
@Override | ||
public List<CodeFragment> fragmentize(String code, Settings originalSettings) { | ||
List<CodeFragment> oldCodeFragments = super.fragmentize(code, originalSettings); | ||
ArrayList<CodeFragment> result = new ArrayList<>(); | ||
|
||
String[] ruleIdsToDisable = { | ||
"COPYRIGHT", | ||
"DASH_RULE", | ||
"R_SYMBOL", | ||
"UPPERCASE_SENTENCE_START", | ||
"WHITESPACE_RULE", | ||
}; | ||
|
||
for (CodeFragment oldCodeFragment : oldCodeFragments) { | ||
Settings settings = oldCodeFragment.getSettings(); | ||
|
||
HashSet<String> dictionary = new HashSet<>(settings.getDictionary()); | ||
dictionary.add("@param"); | ||
dictionary.add("param"); | ||
dictionary.add("@return"); | ||
|
||
HashSet<String> disabledRules = new HashSet<>(settings.getDisabledRules()); | ||
|
||
for (String ruleId : ruleIdsToDisable) { | ||
if (!settings.getEnabledRules().contains(ruleId)) { | ||
disabledRules.add(ruleId); | ||
} | ||
} | ||
|
||
result.add(oldCodeFragment.withSettings( | ||
settings.withDictionary(dictionary).withDisabledRules(disabledRules))); | ||
} | ||
|
||
return result; | ||
} | ||
} |
12 changes: 12 additions & 0 deletions
12
src/main/java/org/bsplines/ltexls/parsing/program/package-info.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
/* Copyright (C) 2020 Julian Valentin, LTeX Development Community | ||
* | ||
* This Source Code Form is subject to the terms of the Mozilla Public | ||
* License, v. 2.0. If a copy of the MPL was not distributed with this | ||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. | ||
*/ | ||
|
||
@DefaultQualifier(NonNull.class) | ||
package org.bsplines.ltexls.parsing.program; | ||
|
||
import org.checkerframework.checker.nullness.qual.NonNull; | ||
import org.checkerframework.framework.qual.DefaultQualifier; |
Oops, something went wrong.