system/src/sc/parser/ParseUtil.java
public static ParseRange findErrorsInRange(IParseNode pn, int startIx, int endIx) {
      int pnStart = pn.getStartIndex();
      int pnLen = pn.length();
      int pnEnd = pnStart + pnLen;

      if (pnStart > endIx || pnEnd < startIx)
         return null;

      // NOTE: pn.isErrorNode() does not work here - we set the error node flag on the parent if any child has an error but the entire node is not an error node
      if (pn instanceof ErrorParseNode) {
         return new ParseRange(Math.max(pnStart,startIx), Math.min(pnEnd, endIx));
      }
      else if (pn instanceof ParseNode) {
         ParseNode p = (ParseNode) pn;
         if (p.value instanceof IParseNode) {
            return findErrorsInRange((IParseNode) p.value, startIx, endIx);
         }
         return null;
      }
      else if (pn instanceof ParentParseNode) {
         ParentParseNode p = (ParentParseNode) pn;
         ParseRange errors = null;
         if (p.children != null) {
            int curChildIndex = p.getStartIndex();
            for (int i = 0; i < p.children.size(); i++) {
               Object child = p.children.get(i);
               if (child instanceof IParseNode) {
                  IParseNode childPN = (IParseNode) child;
                  if (childPN.getStartIndex() > endIx)
                     return errors;
                  ParseRange range = findErrorsInRange(childPN, startIx, endIx);
                  if (range != null) {
                     if (errors == null)
                        errors = range;
                     else {
                        errors.mergeInto(range.startIx, range.endIx);
                     }
                  }
                  curChildIndex += childPN.length();
               }
               else if (PString.isString(child)) {
                  int childLen = ((CharSequence) child).length();
                  int childEndIx = curChildIndex + childLen;
                  if (curChildIndex < endIx && childEndIx > startIx) {
                     String childStr;
                     if (child.equals(";")) { // A semi-colon without a statement is legal syntactically but including it in errors here.  It's not ok to have non-whitespace not accounted - an exception is thrown in assertInvalidRanges.
                        if (errors == null) {
                           errors = new ParseRange(curChildIndex, childEndIx);
                        }
                        else
                           errors.mergeInto(curChildIndex, childEndIx);
                     }
                     else if ((childStr = child.toString()).trim().length() > 0) {
                        String childOverlapStr = childStr.substring(Math.max(0, startIx - curChildIndex), Math.min(endIx, childEndIx) - curChildIndex);
                        int childOverlapLen = childOverlapStr.length();
                        int startCommentIx = 0, endCommentIx = childOverlapLen - 1;
                        while (startCommentIx < childOverlapLen && Character.isWhitespace(childOverlapStr.charAt(startCommentIx)))
                           startCommentIx++;
                        while (endCommentIx >= startCommentIx && Character.isWhitespace(childOverlapStr.charAt(endCommentIx)))
                           endCommentIx--;
                        if (startCommentIx <= endCommentIx) {
                           if (childOverlapStr.indexOf("//") != -1 && childOverlapStr.indexOf("/*") != -1)
                              System.err.println("*** Unmatched text in findErrorsInRange!");
                           else {
                              if (errors == null) {
                                 errors = new ParseRange(curChildIndex + startCommentIx, curChildIndex + endCommentIx + 1);
                              }
                              else
                                 errors.mergeInto(curChildIndex + startCommentIx, curChildIndex + endCommentIx + 1);
                           }
                        }
                     }
                  }
                  curChildIndex = childEndIx;
               }
               else if (child != null) {
                  System.out.println("*** Error - unrecognized child in find error range");
               }
            }
         }
         return errors;
      }
      else // String based parse-node cannot be an error
         return null;
   }
/**
    * Utility method to find a single contiguous error inside of a specified region of a parse node.
    * If there are multiple errors, the 'error region' inside of the specified startIx and endIx params
    * is returned.  This is used for identifying unparsed regions in building a formatting code model
    * for this file to capture errors that exist between recognized parsed types.  It's not OK to just treat
    * them as whitespace since IntelliJ complains.  This also returns any text in comments or an extra ";" if that's
    * in the text body.
    */
Utility method to find a single contiguous error inside of a specified region of a parse node.
If there are multiple errors, the 'error region' inside of the specified startIx and endIx params
is returned.  This is used for identifying unparsed regions in building a formatting code model
for this file to capture errors that exist between recognized parsed types.  It's not OK to just treat
them as whitespace since IntelliJ complains.  This also returns any text in comments or an extra ";" if that's
in the text body.
Utility method to find a single contiguous error inside of a specified region of a parse node . If there are multiple errors the ' error region ' inside of the specified startIx and endIx params is returned . This is used for identifying unparsed regions in building a formatting code model for this file to capture errors that exist between recognized parsed types . It ' s not OK to just treat them as whitespace since IntelliJ complains . This also returns any text in comments or an extra " ; " if that ' s in the text body .
public static ParseRange findErrorsInRange(IParseNode pn, int startIx, int endIx) {
      int pnStart = pn.getStartIndex();
      int pnLen = pn.length();
      int pnEnd = pnStart + pnLen;
      if (pnStart > endIx || pnEnd < startIx)
         return null;
      if (pn instanceof ErrorParseNode) {
         return new ParseRange(Math.max(pnStart,startIx), Math.min(pnEnd, endIx));
      }
      else if (pn instanceof ParseNode) {
         ParseNode p = (ParseNode) pn;
         if (p.value instanceof IParseNode) {
            return findErrorsInRange((IParseNode) p.value, startIx, endIx);
         }
         return null;
      }
      else if (pn instanceof ParentParseNode) {
         ParentParseNode p = (ParentParseNode) pn;
         ParseRange errors = null;
         if (p.children != null) {
            int curChildIndex = p.getStartIndex();
            for (int i = 0; i < p.children.size(); i++) {
               Object child = p.children.get(i);
               if (child instanceof IParseNode) {
                  IParseNode childPN = (IParseNode) child;
                  if (childPN.getStartIndex() > endIx)
                     return errors;
                  ParseRange range = findErrorsInRange(childPN, startIx, endIx);
                  if (range != null) {
                     if (errors == null)
                        errors = range;
                     else {
                        errors.mergeInto(range.startIx, range.endIx);
                     }
                  }
                  curChildIndex += childPN.length();
               }
               else if (PString.isString(child)) {
                  int childLen = ((CharSequence) child).length();
                  int childEndIx = curChildIndex + childLen;
                  if (curChildIndex < endIx && childEndIx > startIx) {
                     String childStr;
                     if (child.equals(";")) { 
                        if (errors == null) {
                           errors = new ParseRange(curChildIndex, childEndIx);
                        }
                        else
                           errors.mergeInto(curChildIndex, childEndIx);
                     }
                     else if ((childStr = child.toString()).trim().length() > 0) {
                        String childOverlapStr = childStr.substring(Math.max(0, startIx - curChildIndex), Math.min(endIx, childEndIx) - curChildIndex);
                        int childOverlapLen = childOverlapStr.length();
                        int startCommentIx = 0, endCommentIx = childOverlapLen - 1;
                        while (startCommentIx < childOverlapLen && Character.isWhitespace(childOverlapStr.charAt(startCommentIx)))
                           startCommentIx++;
                        while (endCommentIx >= startCommentIx && Character.isWhitespace(childOverlapStr.charAt(endCommentIx)))
                           endCommentIx--;
                        if (startCommentIx <= endCommentIx) {
                           if (childOverlapStr.indexOf("//") != -1 && childOverlapStr.indexOf("/*") != -1)
                              System.err.println("*** Unmatched text in findErrorsInRange!");
                           else {
                              if (errors == null) {
                                 errors = new ParseRange(curChildIndex + startCommentIx, curChildIndex + endCommentIx + 1);
                              }
                              else
                                 errors.mergeInto(curChildIndex + startCommentIx, curChildIndex + endCommentIx + 1);
                           }
                        }
                     }
                  }
                  curChildIndex = childEndIx;
               }
               else if (child != null) {
                  System.out.println("*** Error - unrecognized child in find error range");
               }
            }
         }
         return errors;
      }
      else 
         return null;
   }
public static ParseRange findErrorsInRange ( IParseNode pn , int startIx , int endIx ) { int pnStart = pn . getStartIndex ( ) ; int pnLen = pn . length ( ) ; int pnEnd = pnStart + pnLen ; if ( pnStart > endIx || pnEnd < startIx ) return null ; if ( pn instanceof ErrorParseNode ) { return new ParseRange ( Math . max ( pnStart , startIx ) , Math . min ( pnEnd , endIx ) ) ; } else if ( pn instanceof ParseNode ) { ParseNode p = ( ParseNode ) pn ; if ( p . value instanceof IParseNode ) { return findErrorsInRange ( ( IParseNode ) p . value , startIx , endIx ) ; } return null ; } else if ( pn instanceof ParentParseNode ) { ParentParseNode p = ( ParentParseNode ) pn ; ParseRange errors = null ; if ( p . children != null ) { int curChildIndex = p . getStartIndex ( ) ; for ( int i = 0 ; i < p . children . size ( ) ; i ++ ) { Object child = p . children . get ( i ) ; if ( child instanceof IParseNode ) { IParseNode childPN = ( IParseNode ) child ; if ( childPN . getStartIndex ( ) > endIx ) return errors ; ParseRange range = findErrorsInRange ( childPN , startIx , endIx ) ; if ( range != null ) { if ( errors == null ) errors = range ; else { errors . mergeInto ( range . startIx , range . endIx ) ; } } curChildIndex += childPN . length ( ) ; } else if ( PString . isString ( child ) ) { int childLen = ( ( CharSequence ) child ) . length ( ) ; int childEndIx = curChildIndex + childLen ; if ( curChildIndex < endIx && childEndIx > startIx ) { String childStr ; if ( child . equals ( ";" ) ) { if ( errors == null ) { errors = new ParseRange ( curChildIndex , childEndIx ) ; } else errors . mergeInto ( curChildIndex , childEndIx ) ; } else if ( ( childStr = child . toString ( ) ) . trim ( ) . length ( ) > 0 ) { String childOverlapStr = childStr . substring ( Math . max ( 0 , startIx - curChildIndex ) , Math . min ( endIx , childEndIx ) - curChildIndex ) ; int childOverlapLen = childOverlapStr . length ( ) ; int startCommentIx = 0 , endCommentIx = childOverlapLen - 1 ; while ( startCommentIx < childOverlapLen && Character . isWhitespace ( childOverlapStr . charAt ( startCommentIx ) ) ) startCommentIx ++ ; while ( endCommentIx >= startCommentIx && Character . isWhitespace ( childOverlapStr . charAt ( endCommentIx ) ) ) endCommentIx -- ; if ( startCommentIx <= endCommentIx ) { if ( childOverlapStr . indexOf ( "//" ) != - 1 && childOverlapStr . indexOf ( "/*" ) != - 1 ) System . err . println ( "*** Unmatched text in findErrorsInRange!" ) ; else { if ( errors == null ) { errors = new ParseRange ( curChildIndex + startCommentIx , curChildIndex + endCommentIx + 1 ) ; } else errors . mergeInto ( curChildIndex + startCommentIx , curChildIndex + endCommentIx + 1 ) ; } } } } curChildIndex = childEndIx ; } else if ( child != null ) { System . out . println ( "*** Error - unrecognized child in find error range" ) ; } } } return errors ; } else return null ; }
Utility method to find a single contiguous error inside of a specified region of a parse node.
Utility method to find a single contiguous error inside of a specified region of a parse node .
// NOTE: pn.isErrorNode() does not work here - we set the error node flag on the parent if any child has an error but the entire node is not an error node // A semi-colon without a statement is legal syntactically but including it in errors here.  It's not ok to have non-whitespace not accounted - an exception is thrown in assertInvalidRanges. // String based parse-node cannot be an error