@@ -1079,40 +1079,69 @@ private void handleSketchProblems(PreprocessedSketch ps) {
10791079 Map <String , String []> suggCache =
10801080 JavaMode .importSuggestEnabled ? new HashMap <>() : Collections .emptyMap ();
10811081
1082- // Process problems
1082+ final List <Problem > problems = new ArrayList <>();
1083+
10831084 IProblem [] iproblems = ps .compilationUnit .getProblems ();
1084- final List <Problem > problems = Arrays .stream (iproblems )
1085- // Filter Warnings if they are not enabled
1086- .filter (iproblem -> !(iproblem .isWarning () && !JavaMode .warningsEnabled ))
1087- // Hide a useless error which is produced when a line ends with
1088- // an identifier without a semicolon. "Missing a semicolon" is
1089- // also produced and is preferred over this one.
1090- // (Syntax error, insert ":: IdentifierOrNew" to complete Expression)
1091- // See: https://bugs.eclipse.org/bugs/show_bug.cgi?id=405780
1092- .filter (iproblem -> !iproblem .getMessage ()
1093- .contains ("Syntax error, insert \" :: IdentifierOrNew\" " ))
1094- // Transform into our Problems
1095- .map (iproblem -> {
1096- int start = iproblem .getSourceStart ();
1097- int stop = iproblem .getSourceEnd () + 1 ; // make it exclusive
1098- SketchInterval in = ps .mapJavaToSketch (start , stop );
1099- if (in == SketchInterval .BEFORE_START ) return null ;
1100- int line = ps .tabOffsetToTabLine (in .tabIndex , in .startTabOffset );
1101- JavaProblem p = new JavaProblem (iproblem , in .tabIndex , line );
1102- p .setPDEOffsets (in .startTabOffset , in .stopTabOffset );
1103-
1104- // Handle import suggestions
1105- if (JavaMode .importSuggestEnabled && isUndefinedTypeProblem (iproblem )) {
1106- ClassPath cp = ps .searchClassPath ;
1107- String [] s = suggCache .computeIfAbsent (iproblem .getArguments ()[0 ],
1108- name -> getImportSuggestions (cp , name ));
1109- p .setImportSuggestions (s );
1110- }
11111085
1112- return p ;
1113- })
1114- .filter (Objects ::nonNull )
1115- .collect (Collectors .toList ());
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+ }
1107+ }
1108+
1109+ if (problems .isEmpty ()) {
1110+ List <Problem > cuProblems = Arrays .stream (iproblems )
1111+ // Filter Warnings if they are not enabled
1112+ .filter (iproblem -> !(iproblem .isWarning () && !JavaMode .warningsEnabled ))
1113+ // Hide a useless error which is produced when a line ends with
1114+ // an identifier without a semicolon. "Missing a semicolon" is
1115+ // also produced and is preferred over this one.
1116+ // (Syntax error, insert ":: IdentifierOrNew" to complete Expression)
1117+ // See: https://bugs.eclipse.org/bugs/show_bug.cgi?id=405780
1118+ .filter (iproblem -> !iproblem .getMessage ()
1119+ .contains ("Syntax error, insert \" :: IdentifierOrNew\" " ))
1120+ // Transform into our Problems
1121+ .map (iproblem -> {
1122+ int start = iproblem .getSourceStart ();
1123+ int stop = iproblem .getSourceEnd () + 1 ; // make it exclusive
1124+ SketchInterval in = ps .mapJavaToSketch (start , stop );
1125+ if (in == SketchInterval .BEFORE_START ) return null ;
1126+ int line = ps .tabOffsetToTabLine (in .tabIndex , in .startTabOffset );
1127+ JavaProblem p = JavaProblem .fromIProblem (iproblem , in .tabIndex , line );
1128+ p .setPDEOffsets (in .startTabOffset , in .stopTabOffset );
1129+
1130+ // Handle import suggestions
1131+ if (JavaMode .importSuggestEnabled && isUndefinedTypeProblem (iproblem )) {
1132+ ClassPath cp = ps .searchClassPath ;
1133+ String [] s = suggCache .computeIfAbsent (iproblem .getArguments ()[0 ],
1134+ name -> getImportSuggestions (cp , name ));
1135+ p .setImportSuggestions (s );
1136+ }
1137+
1138+ return p ;
1139+ })
1140+ .filter (Objects ::nonNull )
1141+ .collect (Collectors .toList ());
1142+
1143+ problems .addAll (cuProblems );
1144+ }
11161145
11171146 if (scheduledUiUpdate != null ) {
11181147 scheduledUiUpdate .cancel (true );
@@ -1129,13 +1158,28 @@ private void handleSketchProblems(PreprocessedSketch ps) {
11291158 }
11301159
11311160
1132- private boolean isUndefinedTypeProblem (IProblem iproblem ) {
1161+ static private boolean isUndefinedTypeProblem (IProblem iproblem ) {
11331162 int id = iproblem .getID ();
11341163 return id == IProblem .UndefinedType ||
11351164 id == IProblem .UndefinedName ||
11361165 id == IProblem .UnresolvedVariable ;
11371166 }
11381167
1168+ static private boolean isMissingBraceProblem (IProblem iproblem ) {
1169+ switch (iproblem .getID ()) {
1170+ case IProblem .ParsingErrorInsertToComplete : {
1171+ char brace = iproblem .getArguments ()[0 ].charAt (0 );
1172+ return brace == '{' || brace == '}' ;
1173+ }
1174+ case IProblem .ParsingErrorInsertTokenAfter : {
1175+ char brace = iproblem .getArguments ()[1 ].charAt (0 );
1176+ return brace == '{' || brace == '}' ;
1177+ }
1178+ default :
1179+ return false ;
1180+ }
1181+ }
1182+
11391183
11401184 public static String [] getImportSuggestions (ClassPath cp , String className ) {
11411185 RegExpResourceFilter regf = new RegExpResourceFilter (
0 commit comments