5454import javax .swing .text .PlainDocument ;
5555import javax .swing .tree .DefaultMutableTreeNode ;
5656
57+ import org .eclipse .core .runtime .IProgressMonitor ;
5758import org .eclipse .jdt .core .JavaCore ;
5859import org .eclipse .jdt .core .compiler .CharOperation ;
5960import org .eclipse .jdt .core .compiler .IProblem ;
8384import processing .app .ui .Editor ;
8485import processing .app .ui .EditorStatus ;
8586import processing .app .ui .ErrorTable ;
87+ import processing .core .PApplet ;
8688import processing .data .IntList ;
8789import processing .data .StringList ;
8890import processing .mode .java .JavaMode ;
@@ -222,8 +224,8 @@ public void run() {
222224 public void run () {
223225 synchronized (astGenerator ) {
224226 astGenerator .updateAST (latestResult .compilationUnit , tree );
227+ astGenerator .classPath = result .classPath ;
225228 }
226- calcPdeOffsetsForProbList (result );
227229 updateErrorTable (result .problems );
228230 editor .updateErrorBar (result .problems );
229231 editor .getTextArea ().repaint ();
@@ -358,9 +360,6 @@ public static class PreprocessedSketch {
358360 final List <ImportStatement > programImports = new ArrayList <>();
359361 final List <ImportStatement > coreAndDefaultImports = new ArrayList <>();
360362 final List <ImportStatement > codeFolderImports = new ArrayList <>();
361-
362-
363-
364363 }
365364
366365 protected PreprocessedSketch checkCode () {
@@ -377,7 +376,6 @@ protected PreprocessedSketch checkCode() {
377376
378377 StringBuilder workBuffer = new StringBuilder ();
379378
380-
381379 // Combine code into one buffer
382380 IntList tabStartsList = new IntList ();
383381 for (SketchCode sc : sketch .getCode ()) {
@@ -453,6 +451,8 @@ protected PreprocessedSketch checkCode() {
453451 syntaxMapping .addAll (SourceUtils .replaceHexLiterals (workBuffer ));
454452 syntaxMapping .addAll (SourceUtils .wrapSketch (mode , className , workBuffer .length ()));
455453
454+ // TODO: all imports are parsed now, check if they need to be filtered somehow
455+
456456 // Transform code
457457 syntaxStage = syntaxMapping .apply (pdeStage );
458458
@@ -475,7 +475,7 @@ protected PreprocessedSketch checkCode() {
475475
476476 }}
477477
478- if (result .hasSyntaxErrors ) {
478+ if (! result .hasSyntaxErrors ) {
479479
480480 {{ // COMPILATION CHECK
481481
@@ -549,44 +549,70 @@ protected PreprocessedSketch checkCode() {
549549 }}
550550 }
551551
552- if (!syntaxProblems .isEmpty ()) {
553- for (IProblem problem : syntaxProblems ) {
552+ List <Problem > mappedSyntaxProblems =
553+ mapProblems (syntaxProblems , result .tabStarts , result .pdeCode ,
554+ result .syntaxMapping );
554555
555- // Hide a useless error which is produced when a line ends with
556- // an identifier without a semicolon. "Missing a semicolon" is
557- // also produced and is preferred over this one.
558- // (Syntax error, insert ":: IdentifierOrNew" to complete Expression)
559- // See: https://bugs.eclipse.org/bugs/show_bug.cgi?id=405780
560- if (problem .getMessage ().contains ("Syntax error, insert \" :: IdentifierOrNew\" " )) {
561- continue ;
562- }
556+ List <Problem > mappedCompilationProblems =
557+ mapProblems (compilationProblems , result .tabStarts , result .pdeCode ,
558+ result .compilationMapping , result .syntaxMapping );
563559
564- int start = problem . getSourceStart ( );
565- int end = problem . getSourceEnd () - 1 ;
560+ result . problems . addAll ( mappedSyntaxProblems );
561+ result . problems . addAll ( mappedCompilationProblems ) ;
566562
567- int mappedStart = result . syntaxMapping . getInputOffset ( start ) ;
568- int mappedEnd = result . syntaxMapping . getInputOffset ( end );
563+ return result ;
564+ }
569565
570- int tab = Arrays .binarySearch (result .tabStarts , mappedStart );
571- if (tab < 0 ) {
572- tab = -(tab + 1 ) - 1 ;
573- }
574566
575- int tabStart = result .tabStarts [tab ];
567+ protected static List <Problem > mapProblems (List <IProblem > problems ,
568+ int [] tabStarts , String pdeCode ,
569+ SourceMapping ... mappings ) {
576570
577- int line = Util . countLines ( result . pdeCode . substring ( tabStart , mappedStart ) );
571+ List < Problem > result = new ArrayList <>( );
578572
579- Problem p = new Problem (problem , tab , line - 1 );
580- if (p .isWarning () && !JavaMode .warningsEnabled ) {
581- continue ;
582- }
583- result .problems .add (p );
573+ for (IProblem problem : problems ) {
574+ if (problem .isWarning () && !JavaMode .warningsEnabled ) continue ;
575+
576+ // Hide a useless error which is produced when a line ends with
577+ // an identifier without a semicolon. "Missing a semicolon" is
578+ // also produced and is preferred over this one.
579+ // (Syntax error, insert ":: IdentifierOrNew" to complete Expression)
580+ // See: https://bugs.eclipse.org/bugs/show_bug.cgi?id=405780
581+ if (problem .getMessage ().contains ("Syntax error, insert \" :: IdentifierOrNew\" " )) {
582+ continue ;
583+ }
584+
585+ int start = problem .getSourceStart ();
586+ int stop = problem .getSourceEnd (); // inclusive
587+
588+ for (SourceMapping mapping : mappings ) {
589+ start = mapping .getInputOffset (start );
590+ stop = mapping .getInputOffset (stop );
584591 }
592+
593+ int pdeStart = PApplet .constrain (start , 0 , pdeCode .length ()-1 );
594+ int pdeStop = PApplet .constrain (stop + 1 , 1 , pdeCode .length ()); // +1 for exclusive end
595+
596+ // TODO: maybe optimize this, some people use tons of tabs
597+ int tab = Arrays .binarySearch (tabStarts , pdeStart );
598+ if (tab < 0 ) {
599+ tab = -(tab + 1 ) - 1 ;
600+ }
601+
602+ int tabStart = tabStarts [tab ];
603+
604+ // TODO: quick hack; make it smart, fast & beautiful later
605+ int line = Util .countLines (pdeCode .substring (tabStart , pdeStart )) - 1 ;
606+
607+ Problem p = new Problem (problem , tab , line );
608+ p .setPDEOffsets (pdeStart - tabStart , pdeStop - tabStart );
609+ result .add (p );
585610 }
586611
587612 return result ;
588613 }
589614
615+
590616 protected static CompilationUnit makeAST (ASTParser parser ,
591617 char [] source ,
592618 Map <String , String > options ) {
@@ -598,13 +624,11 @@ protected static CompilationUnit makeAST(ASTParser parser,
598624 return (CompilationUnit ) parser .createAST (null );
599625 }
600626
627+
601628 public boolean hasSyntaxErrors (){
602629 return latestResult .hasSyntaxErrors ;
603630 }
604631
605- public boolean hasErrors (){
606- return latestResult .hasSyntaxErrors || latestResult .hasCompilationErrors ;
607- }
608632
609633 /**
610634 * Performs compiler error check.
@@ -652,68 +676,6 @@ public void acceptResult(CompilationResult cr) {
652676 }
653677
654678
655- /**
656- * Calculates PDE Offsets from Java Offsets for Problems
657- */
658- private void calcPdeOffsetsForProbList (PreprocessedSketch preprocessedSketch ) {
659- try {
660- PlainDocument javaSource = new PlainDocument ();
661-
662- javaSource .insertString (0 , preprocessedSketch .preprocessedCode , null );
663- // Code in pde tabs stored as PlainDocument
664- List <Document > pdeTabs = new ArrayList <>();
665- for (SketchCode sc : editor .getSketch ().getCode ()) {
666- PlainDocument tab = new PlainDocument ();
667- if (editor .getSketch ().getCurrentCode ().equals (sc )) {
668- tab .insertString (0 , sc .getDocumentText (), null );
669- } else {
670- tab .insertString (0 , sc .getProgram (), null );
671- }
672- pdeTabs .add (tab );
673- }
674-
675- for (Problem p : preprocessedSketch .problems ) {
676- int prbStart = p .getIProblem ().getSourceStart ();
677- int prbEnd = p .getIProblem ().getSourceEnd ();
678- int javaLineNumber = p .getSourceLineNumber () - 1 ;
679- Element lineElement =
680- javaSource .getDefaultRootElement ().getElement (javaLineNumber );
681- if (lineElement == null ) {
682- Messages .log ("calcPDEOffsetsForProbList(): " +
683- "Couldn't fetch Java line number " +
684- javaLineNumber + "\n Problem: " + p );
685- p .setPDEOffsets (-1 , -1 );
686- continue ;
687- }
688- int lineStart = lineElement .getStartOffset ();
689- int lineLength = lineElement .getEndOffset () - lineStart ;
690- String javaLine = javaSource .getText (lineStart , lineLength );
691-
692- Document doc = pdeTabs .get (p .getTabIndex ());
693- Element pdeLineElement =
694- doc .getDefaultRootElement ().getElement (p .getLineNumber ());
695- if (pdeLineElement == null ) {
696- Messages .log ("calcPDEOffsetsForProbList(): " +
697- "Couldn't fetch pde line number " +
698- javaLineNumber + "\n Problem: " + p );
699- p .setPDEOffsets (-1 ,-1 );
700- continue ;
701- }
702- int pdeLineStart = pdeLineElement .getStartOffset ();
703- int pdeLineLength = pdeLineElement .getEndOffset () - pdeLineStart ;
704- String pdeLine =
705- pdeTabs .get (p .getTabIndex ()).getText (pdeLineStart , pdeLineLength );
706- OffsetMatcher ofm = new OffsetMatcher (pdeLine , javaLine );
707- int pdeOffset =
708- ofm .getPdeOffForJavaOff (prbStart - lineStart , prbEnd - prbStart + 1 );
709- p .setPDEOffsets (pdeOffset , pdeOffset + prbEnd - prbStart );
710- }
711- } catch (Exception e ) {
712- e .printStackTrace ();
713- }
714- }
715-
716-
717679 public CompilationUnit getLatestCU () {
718680 return latestResult .compilationUnit ;
719681 }
@@ -1161,22 +1123,6 @@ protected int[] calculateTabIndexAndLineNumber(int javalineNumber) {
11611123 }
11621124
11631125
1164- /**
1165- * Returns line number of corresponding java source
1166- */
1167- protected int getJavaLineNumFromPDElineNum (int tab , int pdeLineNum ){
1168- return 0 ;
1169-
1170- /*int jLineNum = programImports.size() + 1;
1171- for (int i = 0; i < tab; i++) {
1172- SketchCode sc = editor.getSketch().getCode(i);
1173- int len = Util.countLines(sc.getProgram()) + 1;
1174- jLineNum += len;
1175- }
1176- return jLineNum;*/
1177- }
1178-
1179-
11801126 /**
11811127 * Now defunct.
11821128 * The super method that highlights any ASTNode in the pde editor =D
@@ -1209,45 +1155,28 @@ public boolean highlightNode(ASTNode node){
12091155 }
12101156
12111157
1158+ // TODO: does this belong here?
1159+ // Thread: EDT
12121160 public void scrollToErrorLine (Problem p ) {
1213- if (editor == null ) {
1214- return ;
1215- }
1216- if (p == null )
1217- return ;
1218- try {
1219- if (p .getPDELineStartOffset () == -1 || p .getPDELineStopOffset () == -1 ){
1220- // bad offsets, don't highlight, just scroll.
1221- editor .toFront ();
1222- editor .getSketch ().setCurrentCode (p .getTabIndex ());
1223- }
1224- else {
1225- astGenerator .highlightPDECode (p .getTabIndex (),
1226- p .getLineNumber (),
1227- p .getPDELineStartOffset (),
1228- (p .getPDELineStopOffset ()
1229- - p .getPDELineStartOffset () + 1 ));
1230- }
1161+ if (editor == null ) return ;
1162+ if (p == null ) return ;
12311163
1232- // scroll, but within boundaries
1233- // It's also a bit silly that if parameters to scrollTo() are out of range,
1234- // a BadLocation Exception is thrown internally and caught in JTextArea AND
1235- // even the stack trace gets printed! W/o letting me catch it later! SMH
1236- // That's because 1) you can prevent it by not causing the BLE,
1237- // and 2) there are so many JEditSyntax bugs that actually throwing the
1238- // exception all the time would cause the editor to shut down over
1239- // trivial/recoverable quirks. It's the least bad option. [fry]
1240- final Document doc = editor .getTextArea ().getDocument ();
1241- final int lineCount = countLines (doc .getText (0 , doc .getLength ()));
1242- if (p .getLineNumber () < lineCount && p .getLineNumber () >= 0 ) {
1243- editor .getTextArea ().scrollTo (p .getLineNumber (), 0 );
1244- }
1245- editor .repaint ();
1164+ // Switch to tab
1165+ editor .toFront ();
1166+ editor .getSketch ().setCurrentCode (p .getTabIndex ());
12461167
1247- } catch (Exception e ) {
1248- Messages .loge ("Error while selecting text in scrollToErrorLine(), for problem: " + p , e );
1249- }
1250- // log("---");
1168+ // Highlight the code
1169+ int startOffset = p .getStartOffset ();
1170+ int stopOffset = p .getStopOffset ();
1171+
1172+ int length = editor .getTextArea ().getDocumentLength ();
1173+ startOffset = PApplet .constrain (startOffset , 0 , length );
1174+ stopOffset = PApplet .constrain (stopOffset , 0 , length );
1175+ editor .getTextArea ().select (startOffset , stopOffset );
1176+
1177+ // Scroll to error line
1178+ editor .getTextArea ().scrollToCaret ();
1179+ editor .repaint ();
12511180 }
12521181
12531182 /**
0 commit comments