This is an automated email from the ASF dual-hosted git repository.

lkishalmi pushed a commit to branch use-snakeyaml-parser-improved
in repository https://gitbox.apache.org/repos/asf/netbeans.git

commit c3e2a0293142578085cc5b8853b75945063efe74
Author: Laszlo Kishalmi <laszlo.kisha...@gmail.com>
AuthorDate: Tue Oct 12 18:10:41 2021 -0700

    Working YAML Parser without auto-recovery.
---
 .../modules/languages/yaml/YamlParser.java         | 26 +++----
 .../modules/languages/yaml/YamlParserResult.java   |  2 +-
 .../modules/languages/yaml/YamlSection.java        | 81 ++++++++++++++++++----
 .../test/unit/data/testfiles/error3.yaml.errors    |  2 +-
 .../test/unit/data/testfiles/error4.yaml           |  7 ++
 .../test/unit/data/testfiles/error4.yaml.errors    |  1 +
 .../modules/languages/yaml/YamlParserTest.java     |  4 ++
 7 files changed, 91 insertions(+), 32 deletions(-)

diff --git 
a/ide/languages.yaml/src/org/netbeans/modules/languages/yaml/YamlParser.java 
b/ide/languages.yaml/src/org/netbeans/modules/languages/yaml/YamlParser.java
index 01bef63..ff230f4 100644
--- a/ide/languages.yaml/src/org/netbeans/modules/languages/yaml/YamlParser.java
+++ b/ide/languages.yaml/src/org/netbeans/modules/languages/yaml/YamlParser.java
@@ -38,7 +38,6 @@ import org.netbeans.modules.parsing.api.Task;
 import org.netbeans.modules.parsing.spi.ParseException;
 import org.netbeans.modules.parsing.spi.SourceModificationEvent;
 import org.openide.util.NbBundle;
-import org.snakeyaml.engine.v2.exceptions.MarkedYamlEngineException;
 import org.snakeyaml.engine.v2.exceptions.ParserException;
 import org.snakeyaml.engine.v2.exceptions.ScannerException;
 
@@ -90,7 +89,7 @@ public class YamlParser extends 
org.netbeans.modules.parsing.spi.Parser {
     }
 
     private YamlParserResult resultForTooLargeFile(Snapshot snapshot) {
-        YamlParserResult result = new YamlParserResult(snapshot, false);
+        YamlParserResult result = new YamlParserResult(snapshot);
         // FIXME this can violate contract of DefaultError (null fo)
         DefaultError error = new DefaultError(null, 
NbBundle.getMessage(YamlParser.class, "TooLarge"), null,
                 snapshot.getSource().getFileObject(), 0, 0, Severity.WARNING);
@@ -177,7 +176,7 @@ public class YamlParser extends 
org.netbeans.modules.parsing.spi.Parser {
         replaceCommonSpecialCharacters(sb);
 //        source = replaceInlineRegexBrackets(source);
 
-        YamlParserResult result = new YamlParserResult(snapshot, false);
+        YamlParserResult result = new YamlParserResult(snapshot);
 
         Deque<YamlSection> sources = new LinkedList<>();
         sources.push(new YamlSection(sb.toString()));
@@ -189,22 +188,13 @@ public class YamlParser extends 
org.netbeans.modules.parsing.spi.Parser {
                 result.addStructure(items);
             } catch (ScannerException se) {
                 result.addError(section.processScannerException(snapshot, se));
-                YamlSection after = 
section.after(se.getProblemMark().get().getIndex());
-                YamlSection before = 
section.before(se.getContextMark().get().getIndex());
-                if (!after.isEmpty()) sources.push(after);
-                if (!before.isEmpty()) sources.push(before);
-                if ((before.getLength() + after.getLength()) == 
section.getLength()) {
-                    LOGGER.info("Chanche to loop forever");
-                }
+//                YamlSection after = 
section.after(se.getProblemMark().get().getIndex());
+//                YamlSection before = 
section.before(se.getContextMark().get().getIndex());
+//                if (!after.isEmpty()) sources.push(after);
+//                if (!before.isEmpty()) sources.push(before);
             } catch (ParserException pe ){
                 result.addError(section.processParserException(snapshot, pe));
-                YamlSection after = 
section.after(pe.getProblemMark().get().getIndex());
-                YamlSection before = 
section.before(pe.getProblemMark().get().getIndex());
-                if (!after.isEmpty()) sources.push(after);
-                if (!before.isEmpty()) sources.push(before);
-                if ((before.getLength() + after.getLength()) == 
section.getLength()) {
-                    LOGGER.info("Chanche to loop forever");
-                }
+//                sources.addAll(section.splitOnParserException(pe));
             } catch (Exception ex) {
                 String message = ex.getMessage();
                 if (message != null && message.length() > 0) {
@@ -291,7 +281,7 @@ public class YamlParser extends 
org.netbeans.modules.parsing.spi.Parser {
 
             lastResult = parse(source, snapshot);
         } catch (Exception ioe) {
-            lastResult = new YamlParserResult(snapshot, false);
+            lastResult = new YamlParserResult(snapshot);
         }
     }
 }
diff --git 
a/ide/languages.yaml/src/org/netbeans/modules/languages/yaml/YamlParserResult.java
 
b/ide/languages.yaml/src/org/netbeans/modules/languages/yaml/YamlParserResult.java
index 14a383a..4010e73 100644
--- 
a/ide/languages.yaml/src/org/netbeans/modules/languages/yaml/YamlParserResult.java
+++ 
b/ide/languages.yaml/src/org/netbeans/modules/languages/yaml/YamlParserResult.java
@@ -36,7 +36,7 @@ public class YamlParserResult extends ParserResult {
     private final List<Error> errors = new ArrayList<>();
     private final List<StructureItem> structure = new ArrayList<>();
 
-    public YamlParserResult(Snapshot snapshot, boolean valid) {
+    public YamlParserResult(Snapshot snapshot) {
         super(snapshot);
     }
 
diff --git 
a/ide/languages.yaml/src/org/netbeans/modules/languages/yaml/YamlSection.java 
b/ide/languages.yaml/src/org/netbeans/modules/languages/yaml/YamlSection.java
index 0c73f44..80befe2 100644
--- 
a/ide/languages.yaml/src/org/netbeans/modules/languages/yaml/YamlSection.java
+++ 
b/ide/languages.yaml/src/org/netbeans/modules/languages/yaml/YamlSection.java
@@ -19,6 +19,7 @@
 package org.netbeans.modules.languages.yaml;
 
 import java.util.ArrayList;
+import java.util.LinkedList;
 import java.util.List;
 import java.util.Optional;
 import org.netbeans.modules.csl.api.Severity;
@@ -42,6 +43,7 @@ import org.snakeyaml.engine.v2.scanner.ScannerImpl;
 import org.snakeyaml.engine.v2.scanner.StreamReader;
 
 import static org.netbeans.modules.languages.yaml.YamlStructureItem.NodeType.*;
+
 /**
  *
  * @author lkishalmi
@@ -53,7 +55,7 @@ public class YamlSection {
     final String source;
 
     private Parser parser = null;
-    
+
     YamlSection(int offset, String source) {
         this.offset = offset;
         this.source = source;
@@ -71,14 +73,36 @@ public class YamlSection {
         return new YamlSection(offset + index, source.substring(index));
     }
 
+    public YamlSection trimTail() {
+        int index = source.length() - 1;
+        while ((index > 0) && Character.isWhitespace(source.charAt(index))) {
+            index--;
+        }
+        while ((index > 0) && !Character.isWhitespace(source.charAt(index))) {
+            index--;
+        }
+        return before(index);
+    }
+
+    public YamlSection trimHead() {
+        int index = 0;
+        while ((index < source.length()) && 
Character.isWhitespace(source.charAt(index))) {
+            index++;
+        }
+        while ((index < source.length()) && 
!Character.isWhitespace(source.charAt(index))) {
+            index++;
+        }
+        return after(index);
+    }
+
     public boolean isEmpty() {
         return source.isEmpty();
     }
-    
-    public int getLength() {
+
+    public int length() {
         return source.length();
     }
-    
+
     List<? extends StructureItem> collectItems() {
         if (parser != null) {
             throw new IllegalStateException("This YAML segment is already 
parsed.");
@@ -87,7 +111,7 @@ public class YamlSection {
         ScannerImpl scanner = new ScannerImpl(SETTINGS, new 
StreamReader(SETTINGS, source));
         parser = new ParserImpl(SETTINGS, scanner);
         while (parser.hasNext()) {
-            YamlStructureItem root = processItem(); 
+            YamlStructureItem root = processItem();
             if (root != null) {
                 ret.addAll(root.getNestedItems());
             }
@@ -123,10 +147,9 @@ public class YamlSection {
     }
 
     private YamlStructureItem processScalar(ScalarEvent evt) {
-        return new YamlStructureItem.Simple(SCALAR,evt.getValue(), 
getIndex(evt.getStartMark()), getIndex(evt.getEndMark()));
+        return new YamlStructureItem.Simple(SCALAR, evt.getValue(), 
getIndex(evt.getStartMark()), getIndex(evt.getEndMark()));
     }
 
-    
     private YamlStructureItem processMapping(MappingStartEvent evt) {
         YamlStructureItem.Collection item = new 
YamlStructureItem.Collection(MAP, getIndex(evt.getStartMark()));
         while (parser.hasNext() && !parser.checkEvent(Event.ID.MappingEnd)) {
@@ -168,18 +191,52 @@ public class YamlSection {
     }
 
     DefaultError processParserException(Snapshot snapshot, ParserException se) 
{
-        int problemIndex = getIndex(se.getProblemMark());
-        StringBuilder message = new StringBuilder(se.getContext());
-        message.append(", ").append(se.getProblem());
+        int problemIndex = se.getProblemMark().isPresent() ? 
getIndex(se.getProblemMark()) : 0;
+        int contextIndex = problemIndex;
+        StringBuilder message = new StringBuilder();
+        if (se.getContext() != null) {
+            contextIndex = getIndex(se.getContextMark());
+            message.append(se.getContext()).append(", ");
+        }
+        message.append(se.getProblem());
         char upper = Character.toUpperCase(message.charAt(0));
         message.setCharAt(0, upper);
-        return new DefaultError(null, message.toString(), null, 
snapshot.getSource().getFileObject(), problemIndex, problemIndex, 
Severity.ERROR);
+        return new DefaultError(null, message.toString(), null, 
snapshot.getSource().getFileObject(), contextIndex, problemIndex, 
Severity.ERROR);
+    }
+
+    List<YamlSection> splitOnParserException(ParserException pe) {
+        if (pe.getContextMark().isPresent()) {
+            int contextIndex = pe.getContextMark().get().getIndex();
+            return split(contextIndex, contextIndex + 1);
+        } else {
+            int problemIndex = pe.getProblemMark().get().getIndex();
+            return split(problemIndex, problemIndex + 1);
+        }
+    }
+
+    List<YamlSection> split(int a, int b) {
+        List<YamlSection> ret = new LinkedList<>();
+        YamlSection before = before(a);
+        YamlSection after = after(b);
+        if (before.isEmpty()) {
+            after = after.trimHead();
+        }
+        if (after.isEmpty()) {
+            before = before.trimTail();
+        }
+        if (!before.isEmpty()) {
+            ret.add(before);
+        }
+        if (!after.isEmpty()) {
+            ret.add(after);
+        }
+        return ret;
     }
 
     private int getIndex(Optional<Mark> om) {
         return om.get().getIndex() + offset;
     }
-    
+
     @Override
     public String toString() {
         return "" + offset + ":" + source;
diff --git a/ide/languages.yaml/test/unit/data/testfiles/error3.yaml.errors 
b/ide/languages.yaml/test/unit/data/testfiles/error3.yaml.errors
index ebfa576..6fd938b 100644
--- a/ide/languages.yaml/test/unit/data/testfiles/error3.yaml.errors
+++ b/ide/languages.yaml/test/unit/data/testfiles/error3.yaml.errors
@@ -1 +1 @@
-31-31:While parsing a block mapping, expected <block end>, but found '<block 
mapping start>'
+0-31:While parsing a block mapping, expected <block end>, but found '<block 
mapping start>'
diff --git a/ide/languages.yaml/test/unit/data/testfiles/error4.yaml 
b/ide/languages.yaml/test/unit/data/testfiles/error4.yaml
new file mode 100644
index 0000000..6b54141
--- /dev/null
+++ b/ide/languages.yaml/test/unit/data/testfiles/error4.yaml
@@ -0,0 +1,7 @@
+name: John Smith
+age: 47
+spouse:
+    name: {
+    age: 35
+children:
+
diff --git a/ide/languages.yaml/test/unit/data/testfiles/error4.yaml.errors 
b/ide/languages.yaml/test/unit/data/testfiles/error4.yaml.errors
new file mode 100644
index 0000000..fc439a7
--- /dev/null
+++ b/ide/languages.yaml/test/unit/data/testfiles/error4.yaml.errors
@@ -0,0 +1 @@
+43-65:While parsing a flow mapping, expected ',' or '}', but got :
diff --git 
a/ide/languages.yaml/test/unit/src/org/netbeans/modules/languages/yaml/YamlParserTest.java
 
b/ide/languages.yaml/test/unit/src/org/netbeans/modules/languages/yaml/YamlParserTest.java
index e17982d..3d8a440 100644
--- 
a/ide/languages.yaml/test/unit/src/org/netbeans/modules/languages/yaml/YamlParserTest.java
+++ 
b/ide/languages.yaml/test/unit/src/org/netbeans/modules/languages/yaml/YamlParserTest.java
@@ -50,6 +50,10 @@ public class YamlParserTest extends YamlTestBase {
         checkErrors("testfiles/error3.yaml");
     }
 
+    public void testErrors4() throws Exception {
+        checkErrors("testfiles/error4.yaml");
+    }
+
     public void testIssue232192_01() throws Exception {
         checkErrors("testfiles/issue232192_01.yaml");
     }

---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscr...@netbeans.apache.org
For additional commands, e-mail: commits-h...@netbeans.apache.org

For further information about the NetBeans mailing lists, visit:
https://cwiki.apache.org/confluence/display/NETBEANS/Mailing+lists

Reply via email to