FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

Gather error checking code in PDEX.ErrorChecker · meikis/processing@9efa410 · GitHub

Repository navigation

Commit 9efa410

Browse files
committed
Gather error checking code in PDEX.ErrorChecker
1 parent 0ebd09e commit 9efa410

4 files changed

Lines changed: 150 additions & 69 deletions

File tree

‎java/src/processing/mode/java/pdex/PDEX.java‎

Lines changed: 134 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
import java.util.concurrent.atomic.AtomicReference;
4949
import java.util.function.Consumer;
5050
import java.util.function.Predicate;
51+
import java.util.regex.Matcher;
5152
import java.util.regex.Pattern;
5253
import java.util.stream.Collectors;
5354

@@ -1083,32 +1084,18 @@ private void handleSketchProblems(PreprocessedSketch ps) {
10831084

10841085
IProblem[] iproblems = ps.compilationUnit.getProblems();
10851086

1086-
{ // Handle missing brace problems
1087-
IProblem missingBraceProblem = Arrays.stream(iproblems)
1088-
.filter(ErrorChecker::isMissingBraceProblem)
1089-
.findFirst()
1090-
// Ignore if it is at the end of file
1091-
.filter(p -> p.getSourceEnd() + 1 < ps.javaCode.length())
1092-
// Ignore if the tab number does not match our detected tab number
1093-
.filter(p -> ps.missingBraceProblems.isEmpty() ||
1094-
ps.missingBraceProblems.get(0).getTabIndex() ==
1095-
ps.mapJavaToSketch(p.getSourceStart(), p.getSourceEnd()+1).tabIndex
1096-
)
1097-
.orElse(null);
1098-
1099-
// If there is missing brace ignore all other problems
1100-
if (missingBraceProblem != null) {
1101-
// Prefer ECJ problem, shows location more accurately
1102-
iproblems = new IProblem[]{missingBraceProblem};
1103-
} else if (!ps.missingBraceProblems.isEmpty()) {
1104-
// Fallback to manual detection
1105-
problems.addAll(ps.missingBraceProblems);
1106-
}
1087+
{ // Check for curly quotes
1088+
List<JavaProblem> curlyQuoteProblems = checkForCurlyQuotes(ps);
1089+
problems.addAll(curlyQuoteProblems);
11071090
}
11081091

1109-
AtomicReference<ClassPath> searchClassPath = new AtomicReference<>(null);
1092+
if (problems.isEmpty()) { // Check for missing braces
1093+
List<JavaProblem> missingBraceProblems = checkForMissingBraces(ps);
1094+
problems.addAll(missingBraceProblems);
1095+
}
11101096

11111097
if (problems.isEmpty()) {
1098+
AtomicReference<ClassPath> searchClassPath = new AtomicReference<>(null);
11121099
List<Problem> cuProblems = Arrays.stream(iproblems)
11131100
// Filter Warnings if they are not enabled
11141101
.filter(iproblem -> !(iproblem.isWarning() && !JavaMode.warningsEnabled))
@@ -1121,17 +1108,10 @@ private void handleSketchProblems(PreprocessedSketch ps) {
11211108
.contains("Syntax error, insert \":: IdentifierOrNew\""))
11221109
// Transform into our Problems
11231110
.map(iproblem -> {
1124-
int start = iproblem.getSourceStart();
1125-
int stop = iproblem.getSourceEnd() + 1; // make it exclusive
1126-
SketchInterval in = ps.mapJavaToSketch(start, stop);
1127-
if (in == SketchInterval.BEFORE_START) return null;
1128-
String badCode = ps.pdeCode.substring(in.startPdeOffset, in.stopPdeOffset);
1129-
int line = ps.tabOffsetToTabLine(in.tabIndex, in.startTabOffset);
1130-
JavaProblem p = JavaProblem.fromIProblem(iproblem, in.tabIndex, line, badCode);
1131-
p.setPDEOffsets(in.startTabOffset, in.stopTabOffset);
1111+
JavaProblem p = convertIProblem(iproblem, ps);
11321112

11331113
// Handle import suggestions
1134-
if (JavaMode.importSuggestEnabled && isUndefinedTypeProblem(iproblem)) {
1114+
if (p != null && JavaMode.importSuggestEnabled && isUndefinedTypeProblem(iproblem)) {
11351115
ClassPath cp = searchClassPath.updateAndGet(prev -> prev != null ?
11361116
prev : new ClassPathFactory().createFromPaths(ps.searchClassPathArray));
11371117
String[] s = suggCache.computeIfAbsent(iproblem.getArguments()[0],
@@ -1161,6 +1141,16 @@ private void handleSketchProblems(PreprocessedSketch ps) {
11611141
TimeUnit.MILLISECONDS);
11621142
}
11631143

1144+
static private JavaProblem convertIProblem(IProblem iproblem, PreprocessedSketch ps) {
1145+
SketchInterval in = ps.mapJavaToSketch(iproblem);
1146+
if (in == SketchInterval.BEFORE_START) return null;
1147+
String badCode = ps.pdeCode.substring(in.startPdeOffset, in.stopPdeOffset);
1148+
int line = ps.tabOffsetToTabLine(in.tabIndex, in.startTabOffset);
1149+
JavaProblem p = JavaProblem.fromIProblem(iproblem, in.tabIndex, line, badCode);
1150+
p.setPDEOffsets(in.startTabOffset, in.stopTabOffset);
1151+
return p;
1152+
}
1153+
11641154

11651155
static private boolean isUndefinedTypeProblem(IProblem iproblem) {
11661156
int id = iproblem.getID();
@@ -1186,6 +1176,119 @@ static private boolean isMissingBraceProblem(IProblem iproblem) {
11861176
}
11871177

11881178

1179+
private static final Pattern CURLY_QUOTE_REGEX =
1180+
Pattern.compile("([“”‘’])", Pattern.UNICODE_CHARACTER_CLASS);
1181+
1182+
static private List<JavaProblem> checkForCurlyQuotes(PreprocessedSketch ps) {
1183+
List<JavaProblem> problems = new ArrayList<>(0);
1184+
1185+
// Go through the scrubbed code and look for curly quotes (they should not be any)
1186+
Matcher matcher = CURLY_QUOTE_REGEX.matcher(ps.scrubbedPdeCode);
1187+
while (matcher.find()) {
1188+
int pdeOffset = matcher.start();
1189+
String q = matcher.group();
1190+
1191+
int tabIndex = ps.pdeOffsetToTabIndex(pdeOffset);
1192+
int tabOffset = ps.pdeOffsetToTabOffset(tabIndex, pdeOffset);
1193+
int tabLine = ps.tabOffsetToTabLine(tabIndex, tabOffset);
1194+
1195+
String message = Language.interpolate("editor.status.bad_curly_quote", q);
1196+
JavaProblem problem = new JavaProblem(message, JavaProblem.ERROR, tabIndex, tabLine, 10);
1197+
problem.setPDEOffsets(tabOffset, tabOffset+1);
1198+
1199+
problems.add(problem);
1200+
}
1201+
1202+
1203+
// Go through iproblems and look for problems involving curly quotes
1204+
List<JavaProblem> problems2 = new ArrayList<>(0);
1205+
IProblem[] iproblems = ps.compilationUnit.getProblems();
1206+
1207+
for (IProblem iproblem : iproblems) {
1208+
switch (iproblem.getID()) {
1209+
case IProblem.ParsingErrorDeleteToken:
1210+
case IProblem.ParsingErrorDeleteTokens:
1211+
case IProblem.ParsingErrorInvalidToken:
1212+
case IProblem.ParsingErrorReplaceTokens:
1213+
case IProblem.UnterminatedString:
1214+
SketchInterval in = ps.mapJavaToSketch(iproblem);
1215+
if (in == SketchInterval.BEFORE_START) continue;
1216+
String badCode = ps.pdeCode.substring(in.startPdeOffset, in.stopPdeOffset);
1217+
matcher.reset(badCode);
1218+
while (matcher.find()) {
1219+
int offset = matcher.start();
1220+
String q = matcher.group();
1221+
int tabStart = in.startTabOffset + offset;
1222+
int tabStop = tabStart + 1;
1223+
// Prevent duplicate problems
1224+
if (problems.stream().noneMatch(p -> p.getStartOffset() == tabStart)) {
1225+
int line = ps.tabOffsetToTabLine(in.tabIndex, tabStart);
1226+
String message;
1227+
if (iproblem.getID() == IProblem.UnterminatedString) {
1228+
message = Language.interpolate("editor.status.unterm_string_curly", q);
1229+
} else {
1230+
message = Language.interpolate("editor.status.bad_curly_quote", q);
1231+
}
1232+
JavaProblem p = new JavaProblem(message, JavaProblem.ERROR, in.tabIndex, line, 10);
1233+
p.setPDEOffsets(tabStart, tabStop);
1234+
problems2.add(p);
1235+
}
1236+
}
1237+
}
1238+
}
1239+
1240+
problems.addAll(problems2);
1241+
1242+
return problems;
1243+
}
1244+
1245+
1246+
static private List<JavaProblem> checkForMissingBraces(PreprocessedSketch ps) {
1247+
List<JavaProblem> problems = new ArrayList<>(0);
1248+
for (int tabIndex = 0; tabIndex < ps.tabStartOffsets.length; tabIndex++) {
1249+
int tabStartOffset = ps.tabStartOffsets[tabIndex];
1250+
int tabEndOffset = (tabIndex < ps.tabStartOffsets.length - 1) ?
1251+
ps.tabStartOffsets[tabIndex + 1] : ps.scrubbedPdeCode.length();
1252+
int[] braceResult = SourceUtils.checkForMissingBraces(ps.scrubbedPdeCode, tabStartOffset, tabEndOffset);
1253+
if (braceResult[0] != 0) {
1254+
JavaProblem problem =
1255+
new JavaProblem(braceResult[0] < 0
1256+
? Language.interpolate("editor.status.missing.left_curly_bracket")
1257+
: Language.interpolate("editor.status.missing.right_curly_bracket"),
1258+
JavaProblem.ERROR, tabIndex, braceResult[1], 8);
1259+
problem.setPDEOffsets(braceResult[3], braceResult[3] + 1);
1260+
problems.add(problem);
1261+
}
1262+
}
1263+
1264+
if (problems.isEmpty()) {
1265+
return problems;
1266+
}
1267+
1268+
int problemTabIndex = problems.get(0).getTabIndex();
1269+
1270+
IProblem missingBraceProblem = Arrays.stream(ps.compilationUnit.getProblems())
1271+
.filter(ErrorChecker::isMissingBraceProblem)
1272+
// Ignore if it is at the end of file
1273+
.filter(p -> p.getSourceEnd() + 1 < ps.javaCode.length())
1274+
// Ignore if the tab number does not match our detected tab number
1275+
.filter(p -> problemTabIndex == ps.mapJavaToSketch(p).tabIndex)
1276+
.findFirst()
1277+
.orElse(null);
1278+
1279+
// Prefer ECJ problem, shows location more accurately
1280+
if (missingBraceProblem != null) {
1281+
JavaProblem p = convertIProblem(missingBraceProblem, ps);
1282+
if (p != null) {
1283+
problems.clear();
1284+
problems.add(p);
1285+
}
1286+
}
1287+
1288+
return problems;
1289+
}
1290+
1291+
11891292
static public String[] getImportSuggestions(ClassPath cp, String className) {
11901293
RegExpResourceFilter regf = new RegExpResourceFilter(
11911294
Pattern.compile(".*"),

‎java/src/processing/mode/java/pdex/PreprocessedSketch.java‎

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import com.google.classpath.ClassPath;
44

5+
import org.eclipse.jdt.core.compiler.IProblem;
56
import org.eclipse.jdt.core.dom.ASTNode;
67
import org.eclipse.jdt.core.dom.CompilationUnit;
78

@@ -11,7 +12,6 @@
1112
import java.util.Collections;
1213
import java.util.List;
1314

14-
import processing.app.Problem;
1515
import processing.app.Sketch;
1616
import processing.core.PApplet;
1717
import processing.mode.java.pdex.TextTransform.OffsetMapper;
@@ -30,13 +30,12 @@ public class PreprocessedSketch {
3030

3131
public final int[] tabStartOffsets;
3232

33+
public final String scrubbedPdeCode;
3334
public final String pdeCode;
3435
public final String javaCode;
3536

3637
public final OffsetMapper offsetMapper;
3738

38-
public final List<Problem> missingBraceProblems;
39-
4039
public final boolean hasSyntaxErrors;
4140
public final boolean hasCompilationErrors;
4241

@@ -84,6 +83,12 @@ public SketchInterval mapJavaToSketch(ASTNode node) {
8483
}
8584

8685

86+
public SketchInterval mapJavaToSketch(IProblem iproblem) {
87+
return mapJavaToSketch(iproblem.getSourceStart(),
88+
iproblem.getSourceEnd() + 1); // make it exclusive
89+
}
90+
91+
8792
public SketchInterval mapJavaToSketch(int startJavaOffset, int stopJavaOffset) {
8893
int length = stopJavaOffset - startJavaOffset;
8994
int startPdeOffset = javaOffsetToPdeOffset(startJavaOffset);
@@ -120,7 +125,7 @@ private int javaOffsetToPdeOffset(int javaOffset) {
120125
}
121126

122127

123-
private int pdeOffsetToTabIndex(int pdeOffset) {
128+
public int pdeOffsetToTabIndex(int pdeOffset) {
124129
pdeOffset = Math.max(0, pdeOffset);
125130
int tab = Arrays.binarySearch(tabStartOffsets, pdeOffset);
126131
if (tab < 0) {
@@ -130,7 +135,7 @@ private int pdeOffsetToTabIndex(int pdeOffset) {
130135
}
131136

132137

133-
private int pdeOffsetToTabOffset(int tabIndex, int pdeOffset) {
138+
public int pdeOffsetToTabOffset(int tabIndex, int pdeOffset) {
134139
int tabStartOffset = tabStartOffsets[clipTabIndex(tabIndex)];
135140
return pdeOffset - tabStartOffset;
136141
}
@@ -210,13 +215,12 @@ public static class Builder {
210215

211216
public int[] tabStartOffsets = new int[0];
212217

218+
public String scrubbedPdeCode;
213219
public String pdeCode;
214220
public String javaCode;
215221

216222
public OffsetMapper offsetMapper;
217223

218-
public final List<Problem> missingBraceProblems = new ArrayList<>(0);
219-
220224
public boolean hasSyntaxErrors;
221225
public boolean hasCompilationErrors;
222226

@@ -246,13 +250,12 @@ private PreprocessedSketch(Builder b) {
246250

247251
tabStartOffsets = b.tabStartOffsets;
248252

253+
scrubbedPdeCode = b.scrubbedPdeCode;
249254
pdeCode = b.pdeCode;
250255
javaCode = b.javaCode;
251256

252257
offsetMapper = b.offsetMapper != null ? b.offsetMapper : OffsetMapper.EMPTY_MAPPER;
253258

254-
missingBraceProblems = Collections.unmodifiableList(b.missingBraceProblems);
255-
256259
hasSyntaxErrors = b.hasSyntaxErrors;
257260
hasCompilationErrors = b.hasCompilationErrors;
258261

‎java/src/processing/mode/java/pdex/PreprocessingService.java‎

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -312,6 +312,8 @@ private PreprocessedSketch preprocessSketch(PreprocessedSketch prevResult) {
312312

313313
SourceUtils.scrubCommentsAndStrings(workBuffer);
314314

315+
result.scrubbedPdeCode = workBuffer.toString();
316+
315317
Mode sketchMode = PdePreprocessor.parseMode(workBuffer);
316318

317319
// Prepare transforms to convert pde code into parsable code
@@ -394,15 +396,6 @@ private PreprocessedSketch preprocessSketch(PreprocessedSketch prevResult) {
394396
}
395397
}
396398

397-
{ // Check for missing braces
398-
List<JavaProblem> missingBraceProblems =
399-
SourceUtils.checkForMissingBraces(workBuffer, result.tabStartOffsets);
400-
if (!missingBraceProblems.isEmpty()) {
401-
result.missingBraceProblems.addAll(missingBraceProblems);
402-
result.hasSyntaxErrors = true;
403-
}
404-
}
405-
406399
// Transform code to parsable state
407400
String parsableStage = toParsable.apply();
408401
OffsetMapper parsableMapper = toParsable.getMapper();

‎java/src/processing/mode/java/pdex/SourceUtils.java‎

Lines changed: 2 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -331,27 +331,9 @@ static public void scrubCommentsAndStrings(StringBuilder p) {
331331

332332
}
333333

334-
static public List<JavaProblem> checkForMissingBraces(StringBuilder p, int[] tabStartOffsets) {
335-
List<JavaProblem> problems = new ArrayList<>(0);
336-
for (int tabIndex = 0; tabIndex < tabStartOffsets.length; tabIndex++) {
337-
int tabStartOffset = tabStartOffsets[tabIndex];
338-
int tabEndOffset = (tabIndex < tabStartOffsets.length - 1) ?
339-
tabStartOffsets[tabIndex + 1] : p.length();
340-
int[] braceResult = checkForMissingBraces(p, tabStartOffset, tabEndOffset);
341-
if (braceResult[0] != 0) {
342-
JavaProblem problem =
343-
new JavaProblem(braceResult[0] < 0
344-
? "Found one too many } characters without { to match it."
345-
: "Found one too many { characters without } to match it.",
346-
JavaProblem.ERROR, tabIndex, braceResult[1], 8);
347-
problem.setPDEOffsets(braceResult[3], braceResult[3] + 1);
348-
problems.add(problem);
349-
}
350-
}
351-
return problems;
352-
}
353-
354334

335+
// TODO: move this to a better place when JavaBuild starts using JDT and we
336+
// don't need to check errors at two different places [jv 2017-09-19]
355337
/**
356338
* Checks a single code fragment (such as a tab) for non-matching braces.
357339
* Broken out to allow easy use in JavaBuild.

0 commit comments

Comments
 (0)

Back | FazBrowse Home | New Git URL