psych 5.0.2-java → 5.1.0-java

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: edb7088f7df001d7420b8b753d89a65ffdfc242cddcf7cd2de1dd9718b901be7
4
- data.tar.gz: dde4cab753d72ade698f930d83bced9717fd19294c1f9069f3d2e0498e5c521f
3
+ metadata.gz: '049d26410fdd607691084ad8609acc7a64ed0bb82d05b73e29302aa54138201d'
4
+ data.tar.gz: c39f3e4df9a0713e0931b818f14f43eb9baba434f2cbd7eb0a7f96c847e60268
5
5
  SHA512:
6
- metadata.gz: d8fe730222b14400fab71d34af04b5f385a8c7aab74faad9004d70d9d2a37f5314cfc4b40245f6c140d65d3466519fe89abff30b26a8897a0dbec379460c7643
7
- data.tar.gz: 02535d4ce60ee2410d54b784b146e5a24a4485d1ce3d6ba47ab93002dac04e867dd1fc0d6bcf57c09d3dbfdf1b29284c94f91b3723414b022e68cf4a6ebc5427
6
+ metadata.gz: de8658ee2b9b01ac7cd599e861e8d5859f5b2b31f7efe5e20dd7cbef795344a21826b9dc7b0cd6f5002f4fb801630030b8fb2ea81003e9fdf2856f00b4f7865b
7
+ data.tar.gz: dfa000fec2bd112fe40d6a82f130f5ba84fa0aba5cf25a7834e9a0379681cd018aabc1258fe459b5fa21ad73650ff7d4ac87c66db21824ef0d53ae5b5238e416
data/Mavenfile CHANGED
@@ -1,6 +1,6 @@
1
1
  #-*- mode: ruby -*-
2
2
 
3
- jar 'org.yaml:snakeyaml:${snakeyaml.version}'
3
+ jar 'org.snakeyaml:snakeyaml-engine:${snakeyaml.version}'
4
4
 
5
5
  plugin :dependency, '2.8', :outputFile => 'pkg/classpath'
6
6
 
@@ -27,48 +27,54 @@
27
27
  ***** END LICENSE BLOCK *****/
28
28
  package org.jruby.ext.psych;
29
29
 
30
- import java.io.IOException;
31
- import java.io.OutputStreamWriter;
32
- import java.io.Writer;
33
- import java.nio.charset.Charset;
34
- import java.util.HashMap;
35
- import java.util.Map;
36
-
37
30
  import org.jcodings.Encoding;
38
31
  import org.jcodings.specific.UTF8Encoding;
39
32
  import org.jruby.Ruby;
40
33
  import org.jruby.RubyArray;
41
34
  import org.jruby.RubyBoolean;
42
35
  import org.jruby.RubyClass;
43
- import org.jruby.RubyFixnum;
36
+ import org.jruby.RubyEncoding;
44
37
  import org.jruby.RubyModule;
45
38
  import org.jruby.RubyObject;
46
39
  import org.jruby.RubyString;
47
40
  import org.jruby.anno.JRubyMethod;
48
- import org.jruby.runtime.ObjectAllocator;
49
41
  import org.jruby.runtime.ThreadContext;
50
42
  import org.jruby.runtime.builtin.IRubyObject;
43
+ import org.jruby.util.ByteList;
51
44
  import org.jruby.util.IOOutputStream;
52
45
  import org.jruby.util.TypeConverter;
53
46
  import org.jruby.util.io.EncodingUtils;
54
- import org.yaml.snakeyaml.DumperOptions;
55
- import org.yaml.snakeyaml.emitter.Emitter;
56
- import org.yaml.snakeyaml.emitter.EmitterException;
57
- import org.yaml.snakeyaml.error.Mark;
58
- import org.yaml.snakeyaml.events.AliasEvent;
59
- import org.yaml.snakeyaml.events.DocumentEndEvent;
60
- import org.yaml.snakeyaml.events.DocumentStartEvent;
61
- import org.yaml.snakeyaml.events.Event;
62
- import org.yaml.snakeyaml.events.ImplicitTuple;
63
- import org.yaml.snakeyaml.events.MappingEndEvent;
64
- import org.yaml.snakeyaml.events.MappingStartEvent;
65
- import org.yaml.snakeyaml.events.ScalarEvent;
66
- import org.yaml.snakeyaml.events.SequenceEndEvent;
67
- import org.yaml.snakeyaml.events.SequenceStartEvent;
68
- import org.yaml.snakeyaml.events.StreamEndEvent;
69
- import org.yaml.snakeyaml.events.StreamStartEvent;
70
-
71
- import static org.jruby.runtime.Visibility.*;
47
+ import org.snakeyaml.engine.v2.api.DumpSettings;
48
+ import org.snakeyaml.engine.v2.api.DumpSettingsBuilder;
49
+ import org.snakeyaml.engine.v2.api.StreamDataWriter;
50
+ import org.snakeyaml.engine.v2.api.YamlOutputStreamWriter;
51
+ import org.snakeyaml.engine.v2.common.Anchor;
52
+ import org.snakeyaml.engine.v2.common.FlowStyle;
53
+ import org.snakeyaml.engine.v2.common.ScalarStyle;
54
+ import org.snakeyaml.engine.v2.common.SpecVersion;
55
+ import org.snakeyaml.engine.v2.emitter.Emitter;
56
+ import org.snakeyaml.engine.v2.events.AliasEvent;
57
+ import org.snakeyaml.engine.v2.events.DocumentEndEvent;
58
+ import org.snakeyaml.engine.v2.events.DocumentStartEvent;
59
+ import org.snakeyaml.engine.v2.events.Event;
60
+ import org.snakeyaml.engine.v2.events.ImplicitTuple;
61
+ import org.snakeyaml.engine.v2.events.MappingEndEvent;
62
+ import org.snakeyaml.engine.v2.events.MappingStartEvent;
63
+ import org.snakeyaml.engine.v2.events.ScalarEvent;
64
+ import org.snakeyaml.engine.v2.events.SequenceEndEvent;
65
+ import org.snakeyaml.engine.v2.events.SequenceStartEvent;
66
+ import org.snakeyaml.engine.v2.events.StreamEndEvent;
67
+ import org.snakeyaml.engine.v2.events.StreamStartEvent;
68
+ import org.snakeyaml.engine.v2.exceptions.EmitterException;
69
+ import org.snakeyaml.engine.v2.exceptions.Mark;
70
+
71
+ import java.io.IOException;
72
+ import java.nio.charset.Charset;
73
+ import java.util.HashMap;
74
+ import java.util.Map;
75
+ import java.util.Optional;
76
+
77
+ import static org.jruby.runtime.Visibility.PRIVATE;
72
78
 
73
79
  public class PsychEmitter extends RubyObject {
74
80
  public static void initPsychEmitter(Ruby runtime, RubyModule psych) {
@@ -84,8 +90,7 @@ public class PsychEmitter extends RubyObject {
84
90
 
85
91
  @JRubyMethod(visibility = PRIVATE)
86
92
  public IRubyObject initialize(ThreadContext context, IRubyObject io) {
87
- options = new DumperOptions();
88
- options.setIndent(2);
93
+ dumpSettingsBuilder.setIndent(2);
89
94
 
90
95
  this.io = io;
91
96
 
@@ -98,10 +103,8 @@ public class PsychEmitter extends RubyObject {
98
103
  IRubyObject canonical = rbOptions.callMethod(context, "canonical");
99
104
  IRubyObject level = rbOptions.callMethod(context, "indentation");
100
105
 
101
- options = new DumperOptions();
102
-
103
- options.setCanonical(canonical.isTrue());
104
- options.setIndent((int)level.convertToInteger().getLongValue());
106
+ dumpSettingsBuilder.setCanonical(canonical.isTrue());
107
+ dumpSettingsBuilder.setIndent((int)level.convertToInteger().getLongValue());
105
108
  line_width_set(context, width);
106
109
 
107
110
  this.io = io;
@@ -115,17 +118,14 @@ public class PsychEmitter extends RubyObject {
115
118
 
116
119
  initEmitter(context, encoding);
117
120
 
118
- StreamStartEvent event = new StreamStartEvent(NULL_MARK, NULL_MARK);
119
-
120
- emit(context, event);
121
+ emit(context, NULL_STREAM_START_EVENT);
121
122
 
122
123
  return this;
123
124
  }
124
125
 
125
126
  @JRubyMethod
126
127
  public IRubyObject end_stream(ThreadContext context) {
127
- StreamEndEvent event = new StreamEndEvent(NULL_MARK, NULL_MARK);
128
- emit(context, event);
128
+ emit(context, NULL_STREAM_START_EVENT);
129
129
  return this;
130
130
  }
131
131
 
@@ -133,30 +133,28 @@ public class PsychEmitter extends RubyObject {
133
133
  public IRubyObject start_document(ThreadContext context, IRubyObject _version, IRubyObject tags, IRubyObject implicit) {
134
134
  Ruby runtime = context.runtime;
135
135
 
136
- DumperOptions.Version version = null;
137
136
  boolean implicitBool = implicit.isTrue();
138
- Map<String, String> tagsMap = null;
139
137
 
140
138
  RubyClass arrayClass = runtime.getArray();
141
139
  TypeConverter.checkType(context, _version, arrayClass);
142
140
 
143
141
  RubyArray versionAry = _version.convertToArray();
142
+ Optional<SpecVersion> specVersion;
144
143
  if (versionAry.size() == 2) {
145
144
  int versionInt0 = versionAry.eltInternal(0).convertToInteger().getIntValue();
146
145
  int versionInt1 = versionAry.eltInternal(1).convertToInteger().getIntValue();
147
146
 
148
- if (versionInt0 == 1) {
149
- if (versionInt1 == 0) {
150
- version = DumperOptions.Version.V1_0;
151
- } else if (versionInt1 == 1) {
152
- version = DumperOptions.Version.V1_1;
153
- }
154
- }
155
- if (version == null) {
147
+ if (versionInt0 != 1) {
156
148
  throw runtime.newArgumentError("invalid YAML version: " + versionAry);
157
149
  }
150
+
151
+ specVersion = Optional.of(new SpecVersion(versionInt0, versionInt1));
152
+ } else {
153
+ specVersion = Optional.empty();
158
154
  }
159
155
 
156
+ Map<String, String> tagsMap = new HashMap<>();
157
+
160
158
  if (!tags.isNil()) {
161
159
  TypeConverter.checkType(context, tags, arrayClass);
162
160
 
@@ -177,14 +175,14 @@ public class PsychEmitter extends RubyObject {
177
175
  }
178
176
  }
179
177
 
180
- DocumentStartEvent event = new DocumentStartEvent(NULL_MARK, NULL_MARK, !implicitBool, version, tagsMap);
178
+ DocumentStartEvent event = new DocumentStartEvent(!implicitBool, specVersion, tagsMap, NULL_MARK, NULL_MARK);
181
179
  emit(context, event);
182
180
  return this;
183
181
  }
184
182
 
185
183
  @JRubyMethod
186
184
  public IRubyObject end_document(ThreadContext context, IRubyObject implicit) {
187
- DocumentEndEvent event = new DocumentEndEvent(NULL_MARK, NULL_MARK, !implicit.isTrue());
185
+ DocumentEndEvent event = new DocumentEndEvent(!implicit.isTrue(), NULL_MARK, NULL_MARK);
188
186
  emit(context, event);
189
187
  return this;
190
188
  }
@@ -206,17 +204,17 @@ public class PsychEmitter extends RubyObject {
206
204
 
207
205
  valueStr = EncodingUtils.strConvEnc(context, valueStr, valueStr.getEncoding(), UTF8Encoding.INSTANCE);
208
206
 
209
- RubyString anchorStr = exportToUTF8(context, anchor, stringClass);
210
- RubyString tagStr = exportToUTF8(context, tag, stringClass);
207
+ String anchorStr = exportToUTF8(context, anchor, stringClass);
208
+ String tagStr = exportToUTF8(context, tag, stringClass);
211
209
 
212
210
  ScalarEvent event = new ScalarEvent(
213
- anchorStr == null ? null : anchorStr.asJavaString(),
214
- tagStr == null ? null : tagStr.asJavaString(),
211
+ Optional.ofNullable(anchorStr == null ? null : new Anchor(anchorStr)),
212
+ Optional.ofNullable(tagStr),
215
213
  new ImplicitTuple(plain.isTrue(), quoted.isTrue()),
216
214
  valueStr.asJavaString(),
215
+ SCALAR_STYLES[style.convertToInteger().getIntValue()],
217
216
  NULL_MARK,
218
- NULL_MARK,
219
- SCALAR_STYLES[style.convertToInteger().getIntValue()]);
217
+ NULL_MARK);
220
218
 
221
219
  emit(context, event);
222
220
 
@@ -232,16 +230,16 @@ public class PsychEmitter extends RubyObject {
232
230
 
233
231
  RubyClass stringClass = context.runtime.getString();
234
232
 
235
- RubyString anchorStr = exportToUTF8(context, anchor, stringClass);
236
- RubyString tagStr = exportToUTF8(context, tag, stringClass);
233
+ String anchorStr = exportToUTF8(context, anchor, stringClass);
234
+ String tagStr = exportToUTF8(context, tag, stringClass);
237
235
 
238
236
  SequenceStartEvent event = new SequenceStartEvent(
239
- anchorStr == null ? null : anchorStr.asJavaString(),
240
- tagStr == null ? null : tagStr.asJavaString(),
237
+ Optional.ofNullable(anchorStr == null ? null : new Anchor(anchorStr)),
238
+ Optional.ofNullable(tagStr),
241
239
  implicit.isTrue(),
240
+ FLOW_STYLES[style.convertToInteger().getIntValue()],
242
241
  NULL_MARK,
243
- NULL_MARK,
244
- FLOW_STYLES[style.convertToInteger().getIntValue()]);
242
+ NULL_MARK);
245
243
  emit(context, event);
246
244
  return this;
247
245
  }
@@ -262,16 +260,16 @@ public class PsychEmitter extends RubyObject {
262
260
 
263
261
  RubyClass stringClass = context.runtime.getString();
264
262
 
265
- RubyString anchorStr = exportToUTF8(context, anchor, stringClass);
266
- RubyString tagStr = exportToUTF8(context, tag, stringClass);
263
+ String anchorStr = exportToUTF8(context, anchor, stringClass);
264
+ String tagStr = exportToUTF8(context, tag, stringClass);
267
265
 
268
266
  MappingStartEvent event = new MappingStartEvent(
269
- anchorStr == null ? null : anchorStr.asJavaString(),
270
- tagStr == null ? null : tagStr.asJavaString(),
267
+ Optional.ofNullable(anchorStr == null ? null : new Anchor(anchorStr)),
268
+ Optional.ofNullable(tagStr),
271
269
  implicit.isTrue(),
270
+ FLOW_STYLES[style.convertToInteger().getIntValue()],
272
271
  NULL_MARK,
273
- NULL_MARK,
274
- FLOW_STYLES[style.convertToInteger().getIntValue()]);
272
+ NULL_MARK);
275
273
 
276
274
  emit(context, event);
277
275
 
@@ -289,9 +287,9 @@ public class PsychEmitter extends RubyObject {
289
287
  public IRubyObject alias(ThreadContext context, IRubyObject anchor) {
290
288
  RubyClass stringClass = context.runtime.getString();
291
289
 
292
- RubyString anchorStr = exportToUTF8(context, anchor, stringClass);
290
+ String anchorStr = exportToUTF8(context, anchor, stringClass);
293
291
 
294
- AliasEvent event = new AliasEvent(anchorStr.asJavaString(), NULL_MARK, NULL_MARK);
292
+ AliasEvent event = new AliasEvent(Optional.of(new Anchor(anchorStr)), NULL_MARK, NULL_MARK);
295
293
  emit(context, event);
296
294
  return this;
297
295
  }
@@ -299,40 +297,40 @@ public class PsychEmitter extends RubyObject {
299
297
  @JRubyMethod(name = "canonical=")
300
298
  public IRubyObject canonical_set(ThreadContext context, IRubyObject canonical) {
301
299
  // TODO: unclear if this affects a running emitter
302
- options.setCanonical(canonical.isTrue());
300
+ dumpSettingsBuilder.setCanonical(canonical.isTrue());
303
301
  return canonical;
304
302
  }
305
303
 
306
304
  @JRubyMethod
307
305
  public IRubyObject canonical(ThreadContext context) {
308
306
  // TODO: unclear if this affects a running emitter
309
- return RubyBoolean.newBoolean(context, options.isCanonical());
307
+ return RubyBoolean.newBoolean(context, buildDumpSettings().isCanonical());
310
308
  }
311
309
 
312
310
  @JRubyMethod(name = "indentation=")
313
311
  public IRubyObject indentation_set(ThreadContext context, IRubyObject level) {
314
312
  // TODO: unclear if this affects a running emitter
315
- options.setIndent((int)level.convertToInteger().getLongValue());
313
+ dumpSettingsBuilder.setIndent(level.convertToInteger().getIntValue());
316
314
  return level;
317
315
  }
318
316
 
319
317
  @JRubyMethod
320
318
  public IRubyObject indentation(ThreadContext context) {
321
319
  // TODO: unclear if this affects a running emitter
322
- return context.runtime.newFixnum(options.getIndent());
320
+ return context.runtime.newFixnum(buildDumpSettings().getIndent());
323
321
  }
324
322
 
325
323
  @JRubyMethod(name = "line_width=")
326
324
  public IRubyObject line_width_set(ThreadContext context, IRubyObject width) {
327
- int newWidth = (int)width.convertToInteger().getLongValue();
325
+ int newWidth = width.convertToInteger().getIntValue();
328
326
  if (newWidth <= 0) newWidth = Integer.MAX_VALUE;
329
- options.setWidth(newWidth);
327
+ dumpSettingsBuilder.setWidth(newWidth);
330
328
  return width;
331
329
  }
332
330
 
333
331
  @JRubyMethod
334
332
  public IRubyObject line_width(ThreadContext context) {
335
- return context.runtime.newFixnum(options.getWidth());
333
+ return context.runtime.newFixnum(buildDumpSettings().getWidth());
336
334
  }
337
335
 
338
336
  private void emit(ThreadContext context, Event event) {
@@ -343,8 +341,6 @@ public class PsychEmitter extends RubyObject {
343
341
 
344
342
  // flush writer after each emit
345
343
  writer.flush();
346
- } catch (IOException ioe) {
347
- throw context.runtime.newIOErrorFromException(ioe);
348
344
  } catch (EmitterException ee) {
349
345
  throw context.runtime.newRuntimeError(ee.toString());
350
346
  }
@@ -356,41 +352,55 @@ public class PsychEmitter extends RubyObject {
356
352
  Encoding encoding = PsychLibrary.YAMLEncoding.values()[(int)_encoding.convertToInteger().getLongValue()].encoding;
357
353
  Charset charset = context.runtime.getEncodingService().charsetForEncoding(encoding);
358
354
 
359
- writer = new OutputStreamWriter(new IOOutputStream(io, encoding), charset);
360
- emitter = new Emitter(writer, options);
355
+ writer = new YamlOutputStreamWriter(new IOOutputStream(io, encoding), charset) {
356
+ @Override
357
+ public void processIOException(IOException ioe) {
358
+ throw context.runtime.newIOErrorFromException(ioe);
359
+ }
360
+ };
361
+ emitter = new Emitter(buildDumpSettings(), writer);
362
+ }
363
+
364
+ private DumpSettings buildDumpSettings() {
365
+ return dumpSettingsBuilder.build();
361
366
  }
362
367
 
363
- private RubyString exportToUTF8(ThreadContext context, IRubyObject tag, RubyClass stringClass) {
364
- RubyString tagStr = null;
365
- if (!tag.isNil()) {
366
- TypeConverter.checkType(context, tag, stringClass);
367
- tagStr = (RubyString) tag;
368
- tagStr = EncodingUtils.strConvEnc(context, tagStr, tagStr.getEncoding(), UTF8Encoding.INSTANCE);
368
+ private String exportToUTF8(ThreadContext context, IRubyObject maybeString, RubyClass stringClass) {
369
+ if (maybeString.isNil()) {
370
+ return null;
369
371
  }
370
- return tagStr;
372
+
373
+ RubyString string;
374
+
375
+ TypeConverter.checkType(context, maybeString, stringClass);
376
+ string = (RubyString) maybeString;
377
+ ByteList bytes = string.getByteList();
378
+
379
+ return RubyEncoding.decodeUTF8(bytes.unsafeBytes(), bytes.begin(), bytes.realSize());
371
380
  }
372
381
 
373
382
  Emitter emitter;
374
- Writer writer;
375
- DumperOptions options = new DumperOptions();
383
+ StreamDataWriter writer;
384
+ final DumpSettingsBuilder dumpSettingsBuilder = DumpSettings.builder();
376
385
  IRubyObject io;
377
386
 
378
- private static final Mark NULL_MARK = new Mark("", 0, 0, 0, new int[0], 0);
387
+ private static final Optional<Mark> NULL_MARK = Optional.empty();
388
+ private static final StreamStartEvent NULL_STREAM_START_EVENT = new StreamStartEvent(NULL_MARK, NULL_MARK);
379
389
 
380
390
  // Map style constants from Psych values (ANY = 0 ... FOLDED = 5)
381
391
  // to SnakeYaml values; see psych/nodes/scalar.rb.
382
- private static final DumperOptions.ScalarStyle[] SCALAR_STYLES = {
383
- DumperOptions.ScalarStyle.PLAIN, // ANY
384
- DumperOptions.ScalarStyle.PLAIN,
385
- DumperOptions.ScalarStyle.SINGLE_QUOTED,
386
- DumperOptions.ScalarStyle.DOUBLE_QUOTED,
387
- DumperOptions.ScalarStyle.LITERAL,
388
- DumperOptions.ScalarStyle.FOLDED
392
+ private static final ScalarStyle[] SCALAR_STYLES = {
393
+ ScalarStyle.PLAIN, // ANY
394
+ ScalarStyle.PLAIN,
395
+ ScalarStyle.SINGLE_QUOTED,
396
+ ScalarStyle.DOUBLE_QUOTED,
397
+ ScalarStyle.LITERAL,
398
+ ScalarStyle.FOLDED
389
399
  };
390
400
 
391
- private static final DumperOptions.FlowStyle[] FLOW_STYLES = {
392
- DumperOptions.FlowStyle.AUTO,
393
- DumperOptions.FlowStyle.BLOCK,
394
- DumperOptions.FlowStyle.FLOW
401
+ private static final FlowStyle[] FLOW_STYLES = {
402
+ FlowStyle.AUTO,
403
+ FlowStyle.BLOCK,
404
+ FlowStyle.FLOW
395
405
  };
396
406
  }
@@ -27,10 +27,6 @@
27
27
  ***** END LICENSE BLOCK *****/
28
28
  package org.jruby.ext.psych;
29
29
 
30
- import java.io.InputStream;
31
- import java.io.IOException;
32
- import java.util.Properties;
33
-
34
30
  import org.jcodings.Encoding;
35
31
  import org.jcodings.specific.UTF16BEEncoding;
36
32
  import org.jcodings.specific.UTF16LEEncoding;
@@ -44,7 +40,10 @@ import org.jruby.runtime.ThreadContext;
44
40
  import org.jruby.runtime.Visibility;
45
41
  import org.jruby.runtime.builtin.IRubyObject;
46
42
  import org.jruby.runtime.load.Library;
47
- import org.yaml.snakeyaml.error.Mark;
43
+
44
+ import java.io.IOException;
45
+ import java.io.InputStream;
46
+ import java.util.Properties;
48
47
 
49
48
  public class PsychLibrary implements Library {
50
49
  private static final String DUMMY_VERSION = "0.0";
@@ -54,7 +53,7 @@ public class PsychLibrary implements Library {
54
53
 
55
54
  // load version from properties packed with the jar
56
55
  Properties props = new Properties();
57
- try( InputStream is = runtime.getJRubyClassLoader().getResourceAsStream("META-INF/maven/org.yaml/snakeyaml/pom.properties") ) {
56
+ try( InputStream is = runtime.getJRubyClassLoader().getResourceAsStream("META-INF/maven/org.snakeyaml/snakeyaml-engine/pom.properties") ) {
58
57
  props.load(is);
59
58
  }
60
59
  catch( IOException e ) {
@@ -66,27 +65,6 @@ public class PsychLibrary implements Library {
66
65
  snakeyamlVersion = snakeyamlVersion.substring(0, snakeyamlVersion.length() - "-SNAPSHOT".length());
67
66
  }
68
67
 
69
- // Try to determine if we have a new enough SnakeYAML.
70
- // Versions before 1.21 removed a Mark constructor that JRuby uses.
71
- // See https://github.com/bundler/bundler/issues/6878
72
- if (snakeyamlVersion.equals(DUMMY_VERSION)) {
73
- try {
74
- // Use reflection to try to confirm we have a new enough version
75
- Mark.class.getConstructor(String.class, int.class, int.class, int.class, int[].class, int.class);
76
- } catch (NoSuchMethodException nsme) {
77
- throw runtime.newLoadError("bad SnakeYAML version, required 1.21 or higher; check your CLASSPATH for a conflicting jar");
78
- }
79
- } else {
80
- // Parse version string to check for 1.21+
81
- String[] majorMinor = snakeyamlVersion.split("\\.");
82
-
83
- if (majorMinor.length < 2 || Integer.parseInt(majorMinor[0]) < 1 || Integer.parseInt(majorMinor[1]) < 21) {
84
- throw runtime.newLoadError(
85
- "bad SnakeYAML version " + snakeyamlVersion +
86
- ", required 1.21 or higher; check your CLASSPATH for a conflicting jar");
87
- }
88
- }
89
-
90
68
  RubyString version = runtime.newString(snakeyamlVersion + ".0");
91
69
  version.setFrozen(true);
92
70
  psych.setConstant("SNAKEYAML_VERSION", version);
@@ -27,15 +27,6 @@
27
27
  ***** END LICENSE BLOCK *****/
28
28
  package org.jruby.ext.psych;
29
29
 
30
- import java.io.ByteArrayInputStream;
31
- import java.io.InputStreamReader;
32
- import java.nio.charset.Charset;
33
- import java.nio.charset.CharsetDecoder;
34
- import java.nio.charset.CodingErrorAction;
35
- import java.nio.charset.MalformedInputException;
36
- import java.util.Arrays;
37
- import java.util.Map;
38
-
39
30
  import org.jcodings.Encoding;
40
31
  import org.jcodings.specific.UTF16BEEncoding;
41
32
  import org.jcodings.specific.UTF16LEEncoding;
@@ -43,6 +34,7 @@ import org.jcodings.specific.UTF8Encoding;
43
34
  import org.jcodings.unicode.UnicodeEncoding;
44
35
  import org.jruby.Ruby;
45
36
  import org.jruby.RubyArray;
37
+ import org.jruby.RubyBoolean;
46
38
  import org.jruby.RubyClass;
47
39
  import org.jruby.RubyEncoding;
48
40
  import org.jruby.RubyFixnum;
@@ -52,48 +44,59 @@ import org.jruby.RubyModule;
52
44
  import org.jruby.RubyObject;
53
45
  import org.jruby.RubyString;
54
46
  import org.jruby.anno.JRubyMethod;
55
- import static org.jruby.ext.psych.PsychLibrary.YAMLEncoding.*;
56
47
  import org.jruby.runtime.Block;
57
48
  import org.jruby.runtime.Helpers;
58
49
  import org.jruby.runtime.ThreadContext;
59
50
  import org.jruby.runtime.builtin.IRubyObject;
60
51
  import org.jruby.runtime.callsite.CachingCallSite;
61
52
  import org.jruby.runtime.callsite.FunctionalCachingCallSite;
53
+ import org.jruby.util.ByteList;
62
54
  import org.jruby.util.IOInputStream;
63
55
  import org.jruby.util.io.EncodingUtils;
64
- import org.yaml.snakeyaml.DumperOptions;
65
- import org.yaml.snakeyaml.error.Mark;
66
- import org.yaml.snakeyaml.error.MarkedYAMLException;
67
- import org.yaml.snakeyaml.error.YAMLException;
68
- import org.yaml.snakeyaml.events.AliasEvent;
69
- import org.yaml.snakeyaml.events.DocumentEndEvent;
70
- import org.yaml.snakeyaml.events.DocumentStartEvent;
71
- import org.yaml.snakeyaml.events.Event;
72
- import org.yaml.snakeyaml.events.Event.ID;
73
- import org.yaml.snakeyaml.events.MappingStartEvent;
74
- import org.yaml.snakeyaml.events.ScalarEvent;
75
- import org.yaml.snakeyaml.events.SequenceStartEvent;
76
- import org.yaml.snakeyaml.parser.Parser;
77
- import org.yaml.snakeyaml.parser.ParserException;
78
- import org.yaml.snakeyaml.parser.ParserImpl;
79
- import org.yaml.snakeyaml.reader.ReaderException;
80
- import org.yaml.snakeyaml.reader.StreamReader;
81
- import org.yaml.snakeyaml.scanner.ScannerException;
56
+ import org.snakeyaml.engine.v2.api.LoadSettings;
57
+ import org.snakeyaml.engine.v2.api.LoadSettingsBuilder;
58
+ import org.snakeyaml.engine.v2.common.Anchor;
59
+ import org.snakeyaml.engine.v2.common.FlowStyle;
60
+ import org.snakeyaml.engine.v2.common.ScalarStyle;
61
+ import org.snakeyaml.engine.v2.common.SpecVersion;
62
+ import org.snakeyaml.engine.v2.events.AliasEvent;
63
+ import org.snakeyaml.engine.v2.events.DocumentEndEvent;
64
+ import org.snakeyaml.engine.v2.events.DocumentStartEvent;
65
+ import org.snakeyaml.engine.v2.events.Event;
66
+ import org.snakeyaml.engine.v2.events.ImplicitTuple;
67
+ import org.snakeyaml.engine.v2.events.MappingStartEvent;
68
+ import org.snakeyaml.engine.v2.events.ScalarEvent;
69
+ import org.snakeyaml.engine.v2.events.SequenceStartEvent;
70
+ import org.snakeyaml.engine.v2.exceptions.Mark;
71
+ import org.snakeyaml.engine.v2.exceptions.MarkedYamlEngineException;
72
+ import org.snakeyaml.engine.v2.exceptions.ParserException;
73
+ import org.snakeyaml.engine.v2.exceptions.ReaderException;
74
+ import org.snakeyaml.engine.v2.exceptions.ScannerException;
75
+ import org.snakeyaml.engine.v2.exceptions.YamlEngineException;
76
+ import org.snakeyaml.engine.v2.parser.Parser;
77
+ import org.snakeyaml.engine.v2.parser.ParserImpl;
78
+ import org.snakeyaml.engine.v2.scanner.ScannerImpl;
79
+ import org.snakeyaml.engine.v2.scanner.StreamReader;
80
+ import org.snakeyaml.engine.v2.schema.CoreSchema;
81
+
82
+ import java.io.ByteArrayInputStream;
83
+ import java.io.InputStreamReader;
84
+ import java.nio.charset.Charset;
85
+ import java.nio.charset.CharsetDecoder;
86
+ import java.nio.charset.CodingErrorAction;
87
+ import java.nio.charset.MalformedInputException;
88
+ import java.util.Arrays;
89
+ import java.util.Map;
90
+ import java.util.Optional;
82
91
 
92
+ import static org.jruby.ext.psych.PsychLibrary.YAMLEncoding.*;
83
93
  import static org.jruby.runtime.Helpers.arrayOf;
84
94
  import static org.jruby.runtime.Helpers.invoke;
85
- import org.jruby.util.ByteList;
86
95
 
87
96
  public class PsychParser extends RubyObject {
88
97
 
89
98
  public static final String JRUBY_CALL_SITES = "_jruby_call_sites";
90
99
 
91
- private enum Call {
92
- path, event_location, start_stream, start_document, end_document, alias, scalar, start_sequence, end_sequence, start_mapping, end_mapping, end_stream
93
- }
94
-
95
- final CachingCallSite[] sites;
96
-
97
100
  public static void initPsychParser(Ruby runtime, RubyModule psych) {
98
101
  RubyClass psychParser = runtime.defineClassUnder("Parser", runtime.getObject(), PsychParser::new, psych);
99
102
 
@@ -115,44 +118,72 @@ public class PsychParser extends RubyObject {
115
118
  public PsychParser(Ruby runtime, RubyClass klass) {
116
119
  super(runtime, klass);
117
120
 
118
- this.sites = (CachingCallSite[]) klass.getInternalVariable(JRUBY_CALL_SITES);
121
+ CachingCallSite[] sites = (CachingCallSite[]) klass.getInternalVariable(JRUBY_CALL_SITES);
122
+ this.path = sites[Call.path.ordinal()];
123
+ this.event_location = sites[Call.event_location.ordinal()];
124
+ this.start_stream = sites[Call.start_stream.ordinal()];
125
+ this.start_document = sites[Call.start_document.ordinal()];
126
+ this.end_document = sites[Call.end_document.ordinal()];
127
+ this.alias = sites[Call.alias.ordinal()];
128
+ this.scalar = sites[Call.scalar.ordinal()];
129
+ this.start_sequence = sites[Call.start_sequence.ordinal()];
130
+ this.end_sequence = sites[Call.end_sequence.ordinal()];
131
+ this.start_mapping = sites[Call.start_mapping.ordinal()];
132
+ this.end_mapping = sites[Call.end_mapping.ordinal()];
133
+ this.end_stream = sites[Call.end_stream.ordinal()];
134
+ this.loadSettingsBuilder = LoadSettings.builder().setSchema(new CoreSchema());
135
+ }
136
+
137
+ private IRubyObject stringOrNilForAnchor(ThreadContext context, Optional<Anchor> value) {
138
+ if (!value.isPresent()) return context.nil;
139
+
140
+ return stringFor(context, value.get().getValue());
119
141
  }
120
142
 
121
- private IRubyObject stringOrNilFor(ThreadContext context, String value) {
122
- if (value == null) return context.nil;
143
+ private IRubyObject stringOrNilFor(ThreadContext context, Optional<String> value) {
144
+ if (!value.isPresent()) return context.nil;
123
145
 
124
- return stringFor(context, value);
146
+ return stringFor(context, value.get());
125
147
  }
126
148
 
127
- private RubyString stringFor(ThreadContext context, String value) {
149
+ private IRubyObject stringFor(ThreadContext context, String value) {
128
150
  Ruby runtime = context.runtime;
129
151
 
152
+ boolean isUTF8 = true;
153
+ Charset charset = RubyEncoding.UTF8;
154
+
130
155
  Encoding encoding = runtime.getDefaultInternalEncoding();
131
156
  if (encoding == null) {
132
157
  encoding = UTF8Encoding.INSTANCE;
158
+ charset = RubyEncoding.UTF8;
159
+ } else {
160
+ Charset encodingCharset = encoding.getCharset();
161
+ if (encodingCharset != null) {
162
+ isUTF8 = encodingCharset == RubyEncoding.UTF8;
163
+ charset = encodingCharset;
164
+ }
133
165
  }
134
166
 
135
- Charset charset = RubyEncoding.UTF8;
136
- if (encoding.getCharset() != null) {
137
- charset = encoding.getCharset();
138
- }
139
-
140
- ByteList bytes = new ByteList(value.getBytes(charset), encoding);
167
+ ByteList bytes = new ByteList(
168
+ isUTF8 ?
169
+ RubyEncoding.encodeUTF8(value) :
170
+ RubyEncoding.encode(value, charset),
171
+ encoding);
141
172
  RubyString string = RubyString.newString(runtime, bytes);
142
173
 
143
174
  return string;
144
175
  }
145
176
 
146
- private StreamReader readerFor(ThreadContext context, IRubyObject yaml) {
177
+ private StreamReader readerFor(ThreadContext context, IRubyObject yaml, LoadSettings loadSettings) {
147
178
  if (yaml instanceof RubyString) {
148
- return readerForString(context, (RubyString) yaml);
179
+ return readerForString(context, (RubyString) yaml, loadSettings);
149
180
  }
150
181
 
151
182
  // fall back on IOInputStream, using default charset
152
- return readerForIO(context, yaml);
183
+ return readerForIO(context, yaml, loadSettings);
153
184
  }
154
185
 
155
- private static StreamReader readerForIO(ThreadContext context, IRubyObject yaml) {
186
+ private static StreamReader readerForIO(ThreadContext context, IRubyObject yaml, LoadSettings loadSettings) {
156
187
  boolean isIO = yaml instanceof RubyIO;
157
188
  if (isIO || yaml.respondsTo("read")) {
158
189
  // default to UTF8 unless RubyIO has UTF16 as encoding
@@ -170,7 +201,7 @@ public class PsychParser extends RubyObject {
170
201
  CharsetDecoder decoder = charset.newDecoder();
171
202
  decoder.onMalformedInput(CodingErrorAction.REPORT);
172
203
 
173
- return new StreamReader(new InputStreamReader(new IOInputStream(yaml), decoder));
204
+ return new StreamReader(loadSettings, new InputStreamReader(new IOInputStream(yaml), decoder));
174
205
  } else {
175
206
  Ruby runtime = context.runtime;
176
207
 
@@ -178,7 +209,7 @@ public class PsychParser extends RubyObject {
178
209
  }
179
210
  }
180
211
 
181
- private static StreamReader readerForString(ThreadContext context, RubyString string) {
212
+ private static StreamReader readerForString(ThreadContext context, RubyString string, LoadSettings loadSettings) {
182
213
  ByteList byteList = string.getByteList();
183
214
  Encoding enc = byteList.getEncoding();
184
215
 
@@ -196,7 +227,7 @@ public class PsychParser extends RubyObject {
196
227
 
197
228
  InputStreamReader isr = new InputStreamReader(bais, charset);
198
229
 
199
- return new StreamReader(isr);
230
+ return new StreamReader(loadSettings, isr);
200
231
  }
201
232
 
202
233
  @JRubyMethod(name = "_native_parse")
@@ -204,52 +235,61 @@ public class PsychParser extends RubyObject {
204
235
  Ruby runtime = context.runtime;
205
236
 
206
237
  try {
207
- parser = new ParserImpl(readerFor(context, yaml));
238
+ LoadSettings loadSettings = loadSettingsBuilder.build();
239
+ parser = new ParserImpl(loadSettings, new ScannerImpl(loadSettings, readerFor(context, yaml, loadSettings)));
208
240
 
209
241
  if (path.isNil() && yaml.respondsTo("path")) {
210
- path = sites[Call.path.ordinal()].call(context, this, yaml);
242
+ path = this.path.call(context, this, yaml);
211
243
  }
212
244
 
213
- while (true) {
214
- event = parser.getEvent();
245
+ while (parser.hasNext()) {
246
+ event = parser.next();
215
247
 
216
- Mark start = event.getStartMark();
248
+ Mark start = event.getStartMark().orElseThrow(RuntimeException::new);
217
249
  IRubyObject start_line = runtime.newFixnum(start.getLine());
218
250
  IRubyObject start_column = runtime.newFixnum(start.getColumn());
219
251
 
220
- Mark end = event.getEndMark();
252
+ Mark end = event.getEndMark().orElseThrow(RuntimeException::new);
221
253
  IRubyObject end_line = runtime.newFixnum(end.getLine());
222
254
  IRubyObject end_column = runtime.newFixnum(end.getColumn());
223
255
 
224
- sites[Call.event_location.ordinal()].call(context, this, handler, start_line, start_column, end_line, end_column);
225
-
226
- // FIXME: Event should expose a getID, so it can be switched
227
- if (event.is(ID.StreamStart)) {
228
- sites[Call.start_stream.ordinal()].call(context, this, handler, runtime.newFixnum(YAML_ANY_ENCODING.ordinal()));
229
- } else if (event.is(ID.DocumentStart)) {
230
- handleDocumentStart(context, (DocumentStartEvent) event, handler);
231
- } else if (event.is(ID.DocumentEnd)) {
232
- IRubyObject notExplicit = runtime.newBoolean(!((DocumentEndEvent) event).getExplicit());
233
-
234
- sites[Call.end_document.ordinal()].call(context, this, handler, notExplicit);
235
- } else if (event.is(ID.Alias)) {
236
- IRubyObject alias = stringOrNilFor(context, ((AliasEvent)event).getAnchor());
237
-
238
- sites[Call.alias.ordinal()].call(context, this, handler, alias);
239
- } else if (event.is(ID.Scalar)) {
240
- handleScalar(context, (ScalarEvent) event, handler);
241
- } else if (event.is(ID.SequenceStart)) {
242
- handleSequenceStart(context, (SequenceStartEvent) event, handler);
243
- } else if (event.is(ID.SequenceEnd)) {
244
- sites[Call.end_sequence.ordinal()].call(context, this, handler);
245
- } else if (event.is(ID.MappingStart)) {
246
- handleMappingStart(context, (MappingStartEvent) event, handler);
247
- } else if (event.is(ID.MappingEnd)) {
248
- sites[Call.end_mapping.ordinal()].call(context, this, handler);
249
- } else if (event.is(ID.StreamEnd)) {
250
- sites[Call.end_stream.ordinal()].call(context, this, handler);
251
-
252
- break;
256
+ event_location.call(context, this, handler, start_line, start_column, end_line, end_column);
257
+
258
+ switch (event.getEventId()) {
259
+ case StreamStart:
260
+ start_stream.call(context, this, handler, runtime.newFixnum(YAML_ANY_ENCODING.ordinal()));
261
+ break;
262
+ case DocumentStart:
263
+ handleDocumentStart(context, (DocumentStartEvent) event, handler);
264
+ break;
265
+ case DocumentEnd:
266
+ IRubyObject notExplicit = runtime.newBoolean(!((DocumentEndEvent) event).isExplicit());
267
+
268
+ end_document.call(context, this, handler, notExplicit);
269
+ break;
270
+ case Alias:
271
+ IRubyObject alias = stringOrNilForAnchor(context, ((AliasEvent) event).getAnchor());
272
+
273
+ this.alias.call(context, this, handler, alias);
274
+ break;
275
+ case Scalar:
276
+ handleScalar(context, (ScalarEvent) event, handler);
277
+ break;
278
+ case SequenceStart:
279
+ handleSequenceStart(context, (SequenceStartEvent) event, handler);
280
+ break;
281
+ case SequenceEnd:
282
+ end_sequence.call(context, this, handler);
283
+ break;
284
+ case MappingStart:
285
+ handleMappingStart(context, (MappingStartEvent) event, handler);
286
+ break;
287
+ case MappingEnd:
288
+ end_mapping.call(context, this, handler);
289
+ break;
290
+ case StreamEnd:
291
+ end_stream.call(context, this, handler);
292
+ break;
253
293
  }
254
294
  }
255
295
  } catch (ParserException pe) {
@@ -268,7 +308,7 @@ public class PsychParser extends RubyObject {
268
308
  parser = null;
269
309
  raiseParserException(context, re, path);
270
310
 
271
- } catch (YAMLException ye) {
311
+ } catch (YamlEngineException ye) {
272
312
  Throwable cause = ye.getCause();
273
313
 
274
314
  if (cause instanceof MalformedInputException) {
@@ -288,92 +328,97 @@ public class PsychParser extends RubyObject {
288
328
 
289
329
  private void handleDocumentStart(ThreadContext context, DocumentStartEvent dse, IRubyObject handler) {
290
330
  Ruby runtime = context.runtime;
291
- DumperOptions.Version _version = dse.getVersion();
292
- IRubyObject version = _version == null ?
293
- RubyArray.newArray(runtime) :
294
- RubyArray.newArray(runtime, runtime.newFixnum(_version.major()), runtime.newFixnum(_version.minor()));
295
-
331
+
332
+ Optional<SpecVersion> specVersion = dse.getSpecVersion();
333
+ IRubyObject version = specVersion.isPresent() ?
334
+ RubyArray.newArray(runtime, runtime.newFixnum(specVersion.get().getMajor()), runtime.newFixnum(specVersion.get().getMinor())) :
335
+ RubyArray.newEmptyArray(runtime);
336
+
296
337
  Map<String, String> tagsMap = dse.getTags();
297
- RubyArray tags = RubyArray.newArray(runtime);
298
- if (tagsMap != null && tagsMap.size() > 0) {
338
+ RubyArray tags;
339
+ int size;
340
+ if (tagsMap != null && (size = tagsMap.size()) > 0) {
341
+ tags = RubyArray.newArray(runtime, size);
299
342
  for (Map.Entry<String, String> tag : tagsMap.entrySet()) {
300
- IRubyObject key = stringFor(context, tag.getKey());
343
+ IRubyObject key = stringFor(context, tag.getKey());
301
344
  IRubyObject value = stringFor(context, tag.getValue());
302
345
 
303
346
  tags.append(RubyArray.newArray(runtime, key, value));
304
347
  }
348
+ } else {
349
+ tags = RubyArray.newEmptyArray(runtime);
305
350
  }
306
- IRubyObject notExplicit = runtime.newBoolean(!dse.getExplicit());
307
351
 
308
- invoke(context, handler, "start_document", version, tags, notExplicit);
352
+ IRubyObject notExplicit = runtime.newBoolean(!dse.isExplicit());
353
+
354
+ start_document.call(context, this, handler, version, tags, notExplicit);
309
355
  }
310
356
 
311
357
  private void handleMappingStart(ThreadContext context, MappingStartEvent mse, IRubyObject handler) {
312
358
  Ruby runtime = context.runtime;
313
- IRubyObject anchor = stringOrNilFor(context, mse.getAnchor());
359
+ IRubyObject anchor = stringOrNilForAnchor(context, mse.getAnchor());
314
360
  IRubyObject tag = stringOrNilFor(context, mse.getTag());
315
- IRubyObject implicit = runtime.newBoolean(mse.getImplicit());
361
+ IRubyObject implicit = runtime.newBoolean(mse.isImplicit());
316
362
  IRubyObject style = runtime.newFixnum(translateFlowStyle(mse.getFlowStyle()));
317
363
 
318
- sites[Call.start_mapping.ordinal()].call(context, this, handler, anchor, tag, implicit, style);
364
+ start_mapping.call(context, this, handler, anchor, tag, implicit, style);
319
365
  }
320
366
 
321
367
  private void handleScalar(ThreadContext context, ScalarEvent se, IRubyObject handler) {
322
368
  Ruby runtime = context.runtime;
323
369
 
324
- IRubyObject anchor = stringOrNilFor(context, se.getAnchor());
370
+ IRubyObject anchor = stringOrNilForAnchor(context, se.getAnchor());
325
371
  IRubyObject tag = stringOrNilFor(context, se.getTag());
326
- IRubyObject plain_implicit = runtime.newBoolean(se.getImplicit().canOmitTagInPlainScalar());
327
- IRubyObject quoted_implicit = runtime.newBoolean(se.getImplicit().canOmitTagInNonPlainScalar());
372
+ ImplicitTuple implicit = se.getImplicit();
373
+ IRubyObject plain_implicit = runtime.newBoolean(implicit.canOmitTagInPlainScalar());
374
+ IRubyObject quoted_implicit = runtime.newBoolean(implicit.canOmitTagInNonPlainScalar());
328
375
  IRubyObject style = runtime.newFixnum(translateStyle(se.getScalarStyle()));
329
376
  IRubyObject val = stringFor(context, se.getValue());
330
377
 
331
- sites[Call.scalar.ordinal()].call(context, this, handler, val, anchor, tag, plain_implicit,
378
+ scalar.call(context, this, handler, val, anchor, tag, plain_implicit,
332
379
  quoted_implicit, style);
333
380
  }
334
381
 
335
382
  private void handleSequenceStart(ThreadContext context, SequenceStartEvent sse, IRubyObject handler) {
336
383
  Ruby runtime = context.runtime;
337
- IRubyObject anchor = stringOrNilFor(context, sse.getAnchor());
384
+ IRubyObject anchor = stringOrNilForAnchor(context, sse.getAnchor());
338
385
  IRubyObject tag = stringOrNilFor(context, sse.getTag());
339
- IRubyObject implicit = runtime.newBoolean(sse.getImplicit());
386
+ IRubyObject implicit = runtime.newBoolean(sse.isImplicit());
340
387
  IRubyObject style = runtime.newFixnum(translateFlowStyle(sse.getFlowStyle()));
341
388
 
342
- sites[Call.start_sequence.ordinal()].call(context, this, handler, anchor, tag, implicit, style);
389
+ start_sequence.call(context, this, handler, anchor, tag, implicit, style);
343
390
  }
344
391
 
345
392
  private static void raiseParserException(ThreadContext context, ReaderException re, IRubyObject rbPath) {
346
- Ruby runtime;
393
+ Ruby runtime = context.runtime;
347
394
  RubyClass se;
348
395
  IRubyObject exception;
349
396
 
350
- runtime = context.runtime;
351
- se = (RubyClass)runtime.getModule("Psych").getConstant("SyntaxError");
397
+ se = (RubyClass) runtime.getModule("Psych").getConstant("SyntaxError");
352
398
 
353
399
  exception = se.newInstance(context,
354
400
  new IRubyObject[] {
355
401
  rbPath,
356
- runtime.newFixnum(0),
357
- runtime.newFixnum(0),
402
+ RubyFixnum.zero(runtime),
403
+ RubyFixnum.zero(runtime),
358
404
  runtime.newFixnum(re.getPosition()),
359
- (null == re.getName() ? runtime.getNil() : runtime.newString(re.getName())),
360
- (null == re.toString() ? runtime.getNil() : runtime.newString(re.toString()))
405
+ (null == re.getName() ? context.nil : runtime.newString(re.getName())),
406
+ (null == re.toString() ? context.nil : runtime.newString(re.toString()))
361
407
  },
362
408
  Block.NULL_BLOCK);
363
409
 
364
410
  RubyKernel.raise(context, runtime.getKernel(), new IRubyObject[] { exception }, Block.NULL_BLOCK);
365
411
  }
366
412
 
367
- private static void raiseParserException(ThreadContext context, MarkedYAMLException mye, IRubyObject rbPath) {
368
- Ruby runtime;
413
+ private static void raiseParserException(ThreadContext context, MarkedYamlEngineException mye, IRubyObject rbPath) {
414
+ Ruby runtime = context.runtime;
369
415
  Mark mark;
370
416
  RubyClass se;
371
417
  IRubyObject exception;
372
418
 
373
- runtime = context.runtime;
374
419
  se = (RubyClass)runtime.getModule("Psych").getConstant("SyntaxError");
375
420
 
376
- mark = mye.getProblemMark();
421
+ mark = mye.getProblemMark().get();
377
422
 
378
423
  exception = se.newInstance(context,
379
424
  new IRubyObject[] {
@@ -381,8 +426,8 @@ public class PsychParser extends RubyObject {
381
426
  runtime.newFixnum(mark.getLine() + 1),
382
427
  runtime.newFixnum(mark.getColumn() + 1),
383
428
  runtime.newFixnum(mark.getIndex()),
384
- (null == mye.getProblem() ? runtime.getNil() : runtime.newString(mye.getProblem())),
385
- (null == mye.getContext() ? runtime.getNil() : runtime.newString(mye.getContext()))
429
+ (null == mye.getProblem() ? context.nil : runtime.newString(mye.getProblem())),
430
+ (null == mye.getContext() ? context.nil : runtime.newString(mye.getContext()))
386
431
  },
387
432
  Block.NULL_BLOCK);
388
433
 
@@ -390,11 +435,10 @@ public class PsychParser extends RubyObject {
390
435
  }
391
436
 
392
437
  private static void raiseParserException(ThreadContext context, MalformedInputException mie, IRubyObject rbPath) {
393
- Ruby runtime;;
438
+ Ruby runtime = context.runtime;
394
439
  RubyClass se;
395
440
  IRubyObject exception;
396
441
 
397
- runtime = context.runtime;
398
442
  se = (RubyClass)runtime.getModule("Psych").getConstant("SyntaxError");
399
443
 
400
444
  mie.getInputLength();
@@ -402,18 +446,18 @@ public class PsychParser extends RubyObject {
402
446
  exception = se.newInstance(context,
403
447
  arrayOf(
404
448
  rbPath,
405
- runtime.newFixnum(-1),
406
- runtime.newFixnum(-1),
449
+ RubyFixnum.minus_one(runtime),
450
+ RubyFixnum.minus_one(runtime),
407
451
  runtime.newFixnum(mie.getInputLength()),
408
- runtime.getNil(),
409
- runtime.getNil()
452
+ context.nil,
453
+ context.nil
410
454
  ),
411
455
  Block.NULL_BLOCK);
412
456
 
413
457
  RubyKernel.raise(context, runtime.getKernel(), new IRubyObject[] { exception }, Block.NULL_BLOCK);
414
458
  }
415
459
 
416
- private static int translateStyle(DumperOptions.ScalarStyle style) {
460
+ private static int translateStyle(ScalarStyle style) {
417
461
  if (style == null) return 0; // any
418
462
 
419
463
  switch (style) {
@@ -426,7 +470,7 @@ public class PsychParser extends RubyObject {
426
470
  }
427
471
  }
428
472
 
429
- private static int translateFlowStyle(DumperOptions.FlowStyle flowStyle) {
473
+ private static int translateFlowStyle(FlowStyle flowStyle) {
430
474
  switch (flowStyle) {
431
475
  case AUTO: return 0;
432
476
  case BLOCK: return 1;
@@ -441,14 +485,17 @@ public class PsychParser extends RubyObject {
441
485
 
442
486
  Event event = null;
443
487
 
488
+ Parser parser = this.parser;
444
489
  if (parser != null) {
445
- event = parser.peekEvent();
446
-
447
- if (event == null) event = this.event;
490
+ if (parser.hasNext()) {
491
+ event = parser.peekEvent();
492
+ } else {
493
+ event = this.event;
494
+ }
448
495
  }
449
496
 
450
497
  if (event == null) {
451
- return ((RubyClass)context.runtime.getClassFromPath("Psych::Parser::Mark")).newInstance(
498
+ return ((RubyClass) runtime.getClassFromPath("Psych::Parser::Mark")).newInstance(
452
499
  context,
453
500
  RubyFixnum.zero(runtime),
454
501
  RubyFixnum.zero(runtime),
@@ -457,9 +504,9 @@ public class PsychParser extends RubyObject {
457
504
  );
458
505
  }
459
506
 
460
- Mark mark = event.getStartMark();
507
+ Mark mark = event.getStartMark().orElseThrow(RuntimeException::new);
461
508
 
462
- return ((RubyClass)context.runtime.getClassFromPath("Psych::Parser::Mark")).newInstance(
509
+ return ((RubyClass) runtime.getClassFromPath("Psych::Parser::Mark")).newInstance(
463
510
  context,
464
511
  RubyFixnum.zero(runtime),
465
512
  runtime.newFixnum(mark.getLine()),
@@ -468,6 +515,65 @@ public class PsychParser extends RubyObject {
468
515
  );
469
516
  }
470
517
 
518
+ @JRubyMethod(name = "max_aliases_for_collections=")
519
+ public IRubyObject max_aliases_for_collections_set(IRubyObject max) {
520
+ loadSettingsBuilder.setMaxAliasesForCollections(max.convertToInteger().getIntValue());
521
+
522
+ return max;
523
+ }
524
+
525
+ @JRubyMethod(name = "max_aliases_for_collections")
526
+ public IRubyObject max_aliases_for_collections(ThreadContext context) {
527
+ return context.runtime.newFixnum(buildSettings().getMaxAliasesForCollections());
528
+ }
529
+
530
+ @JRubyMethod(name = "allow_duplicate_keys=")
531
+ public IRubyObject allow_duplicate_keys_set(IRubyObject allow) {
532
+ loadSettingsBuilder.setAllowDuplicateKeys(allow.isTrue());
533
+
534
+ return allow;
535
+ }
536
+
537
+ @JRubyMethod(name = "allow_duplicate_keys")
538
+ public IRubyObject allow_duplicate_keys(ThreadContext context) {
539
+ return RubyBoolean.newBoolean(context, buildSettings().getAllowDuplicateKeys());
540
+ }
541
+
542
+ @JRubyMethod(name = "allow_recursive_keys=")
543
+ public IRubyObject allow_recursive_keys_set(IRubyObject allow) {
544
+ loadSettingsBuilder.setAllowRecursiveKeys(allow.isTrue());
545
+
546
+ return allow;
547
+ }
548
+
549
+ @JRubyMethod(name = "allow_recursive_keys")
550
+ public IRubyObject allow_recursive_keys(ThreadContext context) {
551
+ return RubyBoolean.newBoolean(context, buildSettings().getAllowRecursiveKeys());
552
+ }
553
+
554
+ @JRubyMethod(name = "code_point_limit=")
555
+ public IRubyObject code_point_limit_set(IRubyObject limit) {
556
+ loadSettingsBuilder.setCodePointLimit(limit.convertToInteger().getIntValue());
557
+
558
+ return limit;
559
+ }
560
+
561
+ @JRubyMethod(name = "code_point_limit")
562
+ public IRubyObject code_point_limit(ThreadContext context) {
563
+ return context.runtime.newFixnum(buildSettings().getCodePointLimit());
564
+ }
565
+
566
+ private LoadSettings buildSettings() {
567
+ return loadSettingsBuilder.build();
568
+ }
569
+
471
570
  private Parser parser;
472
571
  private Event event;
572
+ private final LoadSettingsBuilder loadSettingsBuilder;
573
+
574
+ private enum Call {
575
+ path, event_location, start_stream, start_document, end_document, alias, scalar, start_sequence, end_sequence, start_mapping, end_mapping, end_stream
576
+ }
577
+
578
+ private final CachingCallSite path, event_location, start_stream, start_document, end_document, alias, scalar, start_sequence, end_sequence, start_mapping, end_mapping, end_stream;
473
579
  }
@@ -29,14 +29,15 @@ package org.jruby.ext.psych;
29
29
 
30
30
  import org.jruby.Ruby;
31
31
  import org.jruby.RubyClass;
32
+ import org.jruby.RubyException;
32
33
  import org.jruby.RubyModule;
33
34
  import org.jruby.RubyObject;
34
- import org.jruby.RubyException;
35
35
  import org.jruby.anno.JRubyMethod;
36
36
  import org.jruby.exceptions.RaiseException;
37
37
  import org.jruby.runtime.ThreadContext;
38
38
  import org.jruby.runtime.builtin.IRubyObject;
39
- import static org.jruby.runtime.Visibility.*;
39
+
40
+ import static org.jruby.runtime.Visibility.PRIVATE;
40
41
 
41
42
  public class PsychToRuby {
42
43
  public static void initPsychToRuby(Ruby runtime, RubyModule psych) {
@@ -2,9 +2,9 @@
2
2
 
3
3
  module Psych
4
4
  # The version of Psych you are using
5
- VERSION = '5.0.2'
5
+ VERSION = '5.1.0'
6
6
 
7
7
  if RUBY_ENGINE == 'jruby'
8
- DEFAULT_SNAKEYAML_VERSION = '1.33'.freeze
8
+ DEFAULT_SNAKEYAML_VERSION = '2.6'.freeze
9
9
  end
10
10
  end
@@ -568,7 +568,7 @@ module Psych
568
568
  raise BadAlias, "Tried to dump an aliased object"
569
569
  end
570
570
 
571
- unless @permitted_classes[target.class]
571
+ unless Symbol === target || @permitted_classes[target.class]
572
572
  raise DisallowedClass.new('dump', target.class.name || target.class.inspect)
573
573
  end
574
574
 
@@ -576,7 +576,7 @@ module Psych
576
576
  end
577
577
 
578
578
  def visit_Symbol sym
579
- unless @permitted_symbols[sym]
579
+ unless @permitted_classes[Symbol] || @permitted_symbols[sym]
580
580
  raise DisallowedClass.new('dump', "Symbol(#{sym.inspect})")
581
581
  end
582
582
 
data/lib/psych.jar CHANGED
Binary file
data/lib/psych_jars.rb CHANGED
@@ -2,4 +2,4 @@
2
2
  require 'psych.jar'
3
3
 
4
4
  require 'jar-dependencies'
5
- require_jar('org.yaml', 'snakeyaml', Psych::DEFAULT_SNAKEYAML_VERSION)
5
+ require_jar('org.snakeyaml', 'snakeyaml-engine', Psych::DEFAULT_SNAKEYAML_VERSION)
data/psych.gemspec CHANGED
@@ -55,7 +55,7 @@ DESCRIPTION
55
55
  "lib/psych_jars.rb",
56
56
  "lib/psych.jar"
57
57
  ]
58
- s.requirements = "jar org.yaml:snakeyaml, #{version_module::Psych::DEFAULT_SNAKEYAML_VERSION}"
58
+ s.requirements = "jar org.snakeyaml:snakeyaml-engine, #{version_module::Psych::DEFAULT_SNAKEYAML_VERSION}"
59
59
  s.add_dependency 'jar-dependencies', '>= 0.1.7'
60
60
  else
61
61
  s.extensions = ["ext/psych/extconf.rb"]
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: psych
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.0.2
4
+ version: 5.1.0
5
5
  platform: java
6
6
  authors:
7
7
  - Aaron Patterson
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2023-01-18 00:00:00.000000000 Z
13
+ date: 2023-02-07 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  requirement: !ruby/object:Gem::Requirement
@@ -125,7 +125,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
125
125
  - !ruby/object:Gem::Version
126
126
  version: '0'
127
127
  requirements:
128
- - jar org.yaml:snakeyaml, 1.33
128
+ - jar org.snakeyaml:snakeyaml-engine, 2.6
129
129
  rubygems_version: 3.3.25
130
130
  signing_key:
131
131
  specification_version: 4