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