psych 2.1.0-java → 2.1.1-java
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +14 -0
- data/Gemfile +3 -0
- data/Mavenfile +7 -0
- data/bin/console +7 -0
- data/bin/setup +6 -0
- data/ext/java/PsychEmitter.java +345 -0
- data/ext/java/PsychLibrary.java +93 -0
- data/ext/java/PsychParser.java +399 -0
- data/ext/java/PsychToRuby.java +79 -0
- data/ext/java/PsychYamlTree.java +55 -0
- data/ext/psych/.gitignore +11 -0
- data/lib/psych.rb +2 -2
- data/lib/psych/visitors/to_ruby.rb +2 -2
- data/psych.gemspec +39 -0
- metadata +19 -53
- data/test/psych/handlers/test_recorder.rb +0 -26
- data/test/psych/helper.rb +0 -122
- data/test/psych/json/test_stream.rb +0 -110
- data/test/psych/nodes/test_enumerable.rb +0 -44
- data/test/psych/test_alias_and_anchor.rb +0 -97
- data/test/psych/test_array.rb +0 -58
- data/test/psych/test_boolean.rb +0 -37
- data/test/psych/test_class.rb +0 -37
- data/test/psych/test_coder.rb +0 -207
- data/test/psych/test_date_time.rb +0 -39
- data/test/psych/test_deprecated.rb +0 -215
- data/test/psych/test_document.rb +0 -47
- data/test/psych/test_emitter.rb +0 -112
- data/test/psych/test_encoding.rb +0 -269
- data/test/psych/test_exception.rb +0 -158
- data/test/psych/test_hash.rb +0 -95
- data/test/psych/test_json_tree.rb +0 -66
- data/test/psych/test_merge_keys.rb +0 -181
- data/test/psych/test_nil.rb +0 -19
- data/test/psych/test_null.rb +0 -20
- data/test/psych/test_numeric.rb +0 -46
- data/test/psych/test_object.rb +0 -45
- data/test/psych/test_object_references.rb +0 -72
- data/test/psych/test_omap.rb +0 -76
- data/test/psych/test_parser.rb +0 -340
- data/test/psych/test_psych.rb +0 -184
- data/test/psych/test_safe_load.rb +0 -98
- data/test/psych/test_scalar.rb +0 -12
- data/test/psych/test_scalar_scanner.rb +0 -111
- data/test/psych/test_serialize_subclasses.rb +0 -39
- data/test/psych/test_set.rb +0 -50
- data/test/psych/test_stream.rb +0 -94
- data/test/psych/test_string.rb +0 -231
- data/test/psych/test_struct.rb +0 -50
- data/test/psych/test_symbol.rb +0 -26
- data/test/psych/test_tainted.rb +0 -131
- data/test/psych/test_to_yaml_properties.rb +0 -64
- data/test/psych/test_tree_builder.rb +0 -80
- data/test/psych/test_yaml.rb +0 -1293
- data/test/psych/test_yamldbm.rb +0 -193
- data/test/psych/test_yamlstore.rb +0 -86
- data/test/psych/visitors/test_depth_first.rb +0 -50
- data/test/psych/visitors/test_emitter.rb +0 -145
- data/test/psych/visitors/test_to_ruby.rb +0 -332
- data/test/psych/visitors/test_yaml_tree.rb +0 -180
@@ -0,0 +1,399 @@
|
|
1
|
+
/***** BEGIN LICENSE BLOCK *****
|
2
|
+
* Version: EPL 1.0/GPL 2.0/LGPL 2.1
|
3
|
+
*
|
4
|
+
* The contents of this file are subject to the Eclipse Public
|
5
|
+
* License Version 1.0 (the "License"); you may not use this file
|
6
|
+
* except in compliance with the License. You may obtain a copy of
|
7
|
+
* the License at http://www.eclipse.org/legal/epl-v10.html
|
8
|
+
*
|
9
|
+
* Software distributed under the License is distributed on an "AS
|
10
|
+
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
11
|
+
* implied. See the License for the specific language governing
|
12
|
+
* rights and limitations under the License.
|
13
|
+
*
|
14
|
+
* Copyright (C) 2010 Charles O Nutter <headius@headius.com>
|
15
|
+
*
|
16
|
+
* Alternatively, the contents of this file may be used under the terms of
|
17
|
+
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
18
|
+
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
19
|
+
* in which case the provisions of the GPL or the LGPL are applicable instead
|
20
|
+
* of those above. If you wish to allow use of your version of this file only
|
21
|
+
* under the terms of either the GPL or the LGPL, and not to allow others to
|
22
|
+
* use your version of this file under the terms of the EPL, indicate your
|
23
|
+
* decision by deleting the provisions above and replace them with the notice
|
24
|
+
* and other provisions required by the GPL or the LGPL. If you do not delete
|
25
|
+
* the provisions above, a recipient may use your version of this file under
|
26
|
+
* the terms of any one of the EPL, the GPL or the LGPL.
|
27
|
+
***** END LICENSE BLOCK *****/
|
28
|
+
package org.jruby.ext.psych;
|
29
|
+
|
30
|
+
import java.io.ByteArrayInputStream;
|
31
|
+
import java.io.InputStreamReader;
|
32
|
+
import java.nio.charset.Charset;
|
33
|
+
import java.util.Map;
|
34
|
+
|
35
|
+
import org.jcodings.Encoding;
|
36
|
+
import org.jcodings.specific.UTF8Encoding;
|
37
|
+
import org.jcodings.unicode.UnicodeEncoding;
|
38
|
+
import org.jruby.Ruby;
|
39
|
+
import org.jruby.RubyArray;
|
40
|
+
import org.jruby.RubyClass;
|
41
|
+
import org.jruby.RubyEncoding;
|
42
|
+
import org.jruby.RubyIO;
|
43
|
+
import org.jruby.RubyKernel;
|
44
|
+
import org.jruby.RubyModule;
|
45
|
+
import org.jruby.RubyObject;
|
46
|
+
import org.jruby.RubyString;
|
47
|
+
import org.jruby.anno.JRubyMethod;
|
48
|
+
import static org.jruby.ext.psych.PsychLibrary.YAMLEncoding.*;
|
49
|
+
import org.jruby.runtime.Block;
|
50
|
+
import org.jruby.runtime.Helpers;
|
51
|
+
import org.jruby.runtime.ObjectAllocator;
|
52
|
+
import org.jruby.runtime.ThreadContext;
|
53
|
+
import org.jruby.runtime.builtin.IRubyObject;
|
54
|
+
import org.jruby.util.IOInputStream;
|
55
|
+
import org.jruby.util.io.EncodingUtils;
|
56
|
+
import org.jruby.util.log.Logger;
|
57
|
+
import org.jruby.util.log.LoggerFactory;
|
58
|
+
import org.yaml.snakeyaml.DumperOptions;
|
59
|
+
import org.yaml.snakeyaml.error.Mark;
|
60
|
+
import org.yaml.snakeyaml.error.MarkedYAMLException;
|
61
|
+
import org.yaml.snakeyaml.events.AliasEvent;
|
62
|
+
import org.yaml.snakeyaml.events.DocumentEndEvent;
|
63
|
+
import org.yaml.snakeyaml.events.DocumentStartEvent;
|
64
|
+
import org.yaml.snakeyaml.events.Event;
|
65
|
+
import org.yaml.snakeyaml.events.Event.ID;
|
66
|
+
import org.yaml.snakeyaml.events.MappingStartEvent;
|
67
|
+
import org.yaml.snakeyaml.events.ScalarEvent;
|
68
|
+
import org.yaml.snakeyaml.events.SequenceStartEvent;
|
69
|
+
import org.yaml.snakeyaml.parser.Parser;
|
70
|
+
import org.yaml.snakeyaml.parser.ParserException;
|
71
|
+
import org.yaml.snakeyaml.parser.ParserImpl;
|
72
|
+
import org.yaml.snakeyaml.reader.ReaderException;
|
73
|
+
import org.yaml.snakeyaml.reader.StreamReader;
|
74
|
+
import org.yaml.snakeyaml.scanner.ScannerException;
|
75
|
+
import static org.jruby.runtime.Helpers.invoke;
|
76
|
+
import org.jruby.util.ByteList;
|
77
|
+
|
78
|
+
public class PsychParser extends RubyObject {
|
79
|
+
|
80
|
+
private static final Logger LOG = LoggerFactory.getLogger("PsychParser");
|
81
|
+
|
82
|
+
public static void initPsychParser(Ruby runtime, RubyModule psych) {
|
83
|
+
RubyClass psychParser = runtime.defineClassUnder("Parser", runtime.getObject(), new ObjectAllocator() {
|
84
|
+
public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
|
85
|
+
return new PsychParser(runtime, klazz);
|
86
|
+
}
|
87
|
+
}, psych);
|
88
|
+
|
89
|
+
RubyKernel.require(runtime.getNil(),
|
90
|
+
runtime.newString("psych/syntax_error"), Block.NULL_BLOCK);
|
91
|
+
psychParser.defineConstant("ANY", runtime.newFixnum(YAML_ANY_ENCODING.ordinal()));
|
92
|
+
psychParser.defineConstant("UTF8", runtime.newFixnum(YAML_UTF8_ENCODING.ordinal()));
|
93
|
+
psychParser.defineConstant("UTF16LE", runtime.newFixnum(YAML_UTF16LE_ENCODING.ordinal()));
|
94
|
+
psychParser.defineConstant("UTF16BE", runtime.newFixnum(YAML_UTF16BE_ENCODING.ordinal()));
|
95
|
+
|
96
|
+
psychParser.defineAnnotatedMethods(PsychParser.class);
|
97
|
+
}
|
98
|
+
|
99
|
+
public PsychParser(Ruby runtime, RubyClass klass) {
|
100
|
+
super(runtime, klass);
|
101
|
+
}
|
102
|
+
|
103
|
+
@JRubyMethod
|
104
|
+
public IRubyObject parse(ThreadContext context, IRubyObject yaml) {
|
105
|
+
Ruby runtime = context.runtime;
|
106
|
+
|
107
|
+
return parse(context, yaml, runtime.getNil());
|
108
|
+
}
|
109
|
+
|
110
|
+
private IRubyObject stringOrNilFor(Ruby runtime, String value, boolean tainted) {
|
111
|
+
if (value == null) return runtime.getNil(); // No need to taint nil
|
112
|
+
|
113
|
+
return stringFor(runtime, value, tainted);
|
114
|
+
}
|
115
|
+
|
116
|
+
private RubyString stringFor(Ruby runtime, String value, boolean tainted) {
|
117
|
+
Encoding encoding = runtime.getDefaultInternalEncoding();
|
118
|
+
if (encoding == null) {
|
119
|
+
encoding = UTF8Encoding.INSTANCE;
|
120
|
+
}
|
121
|
+
|
122
|
+
Charset charset = RubyEncoding.UTF8;
|
123
|
+
if (encoding.getCharset() != null) {
|
124
|
+
charset = encoding.getCharset();
|
125
|
+
}
|
126
|
+
|
127
|
+
ByteList bytes = new ByteList(value.getBytes(charset), encoding);
|
128
|
+
RubyString string = RubyString.newString(runtime, bytes);
|
129
|
+
|
130
|
+
string.setTaint(tainted);
|
131
|
+
|
132
|
+
return string;
|
133
|
+
}
|
134
|
+
|
135
|
+
private StreamReader readerFor(ThreadContext context, IRubyObject yaml) {
|
136
|
+
Ruby runtime = context.runtime;
|
137
|
+
|
138
|
+
if (yaml instanceof RubyString) {
|
139
|
+
ByteList byteList = ((RubyString)yaml).getByteList();
|
140
|
+
Encoding enc = byteList.getEncoding();
|
141
|
+
|
142
|
+
// if not unicode, transcode to UTF8
|
143
|
+
if (!(enc instanceof UnicodeEncoding)) {
|
144
|
+
byteList = EncodingUtils.strConvEnc(context, byteList, enc, UTF8Encoding.INSTANCE);
|
145
|
+
enc = UTF8Encoding.INSTANCE;
|
146
|
+
}
|
147
|
+
|
148
|
+
ByteArrayInputStream bais = new ByteArrayInputStream(byteList.getUnsafeBytes(), byteList.getBegin(), byteList.getRealSize());
|
149
|
+
|
150
|
+
Charset charset = enc.getCharset();
|
151
|
+
|
152
|
+
assert charset != null : "charset for encoding " + enc + " should not be null";
|
153
|
+
|
154
|
+
InputStreamReader isr = new InputStreamReader(bais, charset);
|
155
|
+
|
156
|
+
return new StreamReader(isr);
|
157
|
+
}
|
158
|
+
|
159
|
+
// fall back on IOInputStream, using default charset
|
160
|
+
if (yaml.respondsTo("read")) {
|
161
|
+
Encoding enc = (yaml instanceof RubyIO)
|
162
|
+
? ((RubyIO)yaml).getReadEncoding()
|
163
|
+
: UTF8Encoding.INSTANCE;
|
164
|
+
Charset charset = enc.getCharset();
|
165
|
+
return new StreamReader(new InputStreamReader(new IOInputStream(yaml), charset));
|
166
|
+
} else {
|
167
|
+
throw runtime.newTypeError(yaml, runtime.getIO());
|
168
|
+
}
|
169
|
+
}
|
170
|
+
|
171
|
+
@JRubyMethod
|
172
|
+
public IRubyObject parse(ThreadContext context, IRubyObject yaml, IRubyObject path) {
|
173
|
+
Ruby runtime = context.runtime;
|
174
|
+
boolean tainted = yaml.isTaint() || yaml instanceof RubyIO;
|
175
|
+
|
176
|
+
try {
|
177
|
+
parser = new ParserImpl(readerFor(context, yaml));
|
178
|
+
|
179
|
+
if (path.isNil() && yaml.respondsTo("path")) {
|
180
|
+
path = yaml.callMethod(context, "path");
|
181
|
+
}
|
182
|
+
|
183
|
+
IRubyObject handler = getInstanceVariable("@handler");
|
184
|
+
|
185
|
+
while (true) {
|
186
|
+
event = parser.getEvent();
|
187
|
+
|
188
|
+
// FIXME: Event should expose a getID, so it can be switched
|
189
|
+
if (event.is(ID.StreamStart)) {
|
190
|
+
invoke(context, handler, "start_stream", runtime.newFixnum(YAML_ANY_ENCODING.ordinal()));
|
191
|
+
} else if (event.is(ID.DocumentStart)) {
|
192
|
+
handleDocumentStart(context, (DocumentStartEvent) event, tainted, handler);
|
193
|
+
} else if (event.is(ID.DocumentEnd)) {
|
194
|
+
IRubyObject notExplicit = runtime.newBoolean(!((DocumentEndEvent) event).getExplicit());
|
195
|
+
|
196
|
+
invoke(context, handler, "end_document", notExplicit);
|
197
|
+
} else if (event.is(ID.Alias)) {
|
198
|
+
IRubyObject alias = stringOrNilFor(runtime, ((AliasEvent)event).getAnchor(), tainted);
|
199
|
+
|
200
|
+
invoke(context, handler, "alias", alias);
|
201
|
+
} else if (event.is(ID.Scalar)) {
|
202
|
+
handleScalar(context, (ScalarEvent) event, tainted, handler);
|
203
|
+
} else if (event.is(ID.SequenceStart)) {
|
204
|
+
handleSequenceStart(context,(SequenceStartEvent) event, tainted, handler);
|
205
|
+
} else if (event.is(ID.SequenceEnd)) {
|
206
|
+
invoke(context, handler, "end_sequence");
|
207
|
+
} else if (event.is(ID.MappingStart)) {
|
208
|
+
handleMappingStart(context, (MappingStartEvent) event, tainted, handler);
|
209
|
+
} else if (event.is(ID.MappingEnd)) {
|
210
|
+
invoke(context, handler, "end_mapping");
|
211
|
+
} else if (event.is(ID.StreamEnd)) {
|
212
|
+
invoke(context, handler, "end_stream");
|
213
|
+
|
214
|
+
break;
|
215
|
+
}
|
216
|
+
}
|
217
|
+
} catch (ParserException pe) {
|
218
|
+
parser = null;
|
219
|
+
raiseParserException(context, yaml, pe, path);
|
220
|
+
|
221
|
+
} catch (ScannerException se) {
|
222
|
+
parser = null;
|
223
|
+
StringBuilder message = new StringBuilder("syntax error");
|
224
|
+
if (se.getProblemMark() != null) {
|
225
|
+
message.append(se.getProblemMark().toString());
|
226
|
+
}
|
227
|
+
raiseParserException(context, yaml, se, path);
|
228
|
+
|
229
|
+
} catch (ReaderException re) {
|
230
|
+
parser = null;
|
231
|
+
raiseParserException(context, yaml, re, path);
|
232
|
+
|
233
|
+
} catch (Throwable t) {
|
234
|
+
Helpers.throwException(t);
|
235
|
+
return this;
|
236
|
+
}
|
237
|
+
|
238
|
+
return this;
|
239
|
+
}
|
240
|
+
|
241
|
+
private void handleDocumentStart(ThreadContext context, DocumentStartEvent dse, boolean tainted, IRubyObject handler) {
|
242
|
+
Ruby runtime = context.runtime;
|
243
|
+
DumperOptions.Version _version = dse.getVersion();
|
244
|
+
Integer[] versionInts = _version == null ? null : _version.getArray();
|
245
|
+
IRubyObject version = versionInts == null ?
|
246
|
+
RubyArray.newArray(runtime) :
|
247
|
+
RubyArray.newArray(runtime, runtime.newFixnum(versionInts[0]), runtime.newFixnum(versionInts[1]));
|
248
|
+
|
249
|
+
Map<String, String> tagsMap = dse.getTags();
|
250
|
+
RubyArray tags = RubyArray.newArray(runtime);
|
251
|
+
if (tagsMap != null && tagsMap.size() > 0) {
|
252
|
+
for (Map.Entry<String, String> tag : tagsMap.entrySet()) {
|
253
|
+
IRubyObject key = stringFor(runtime, tag.getKey(), tainted);
|
254
|
+
IRubyObject value = stringFor(runtime, tag.getValue(), tainted);
|
255
|
+
|
256
|
+
tags.append(RubyArray.newArray(runtime, key, value));
|
257
|
+
}
|
258
|
+
}
|
259
|
+
IRubyObject notExplicit = runtime.newBoolean(!dse.getExplicit());
|
260
|
+
|
261
|
+
invoke(context, handler, "start_document", version, tags, notExplicit);
|
262
|
+
}
|
263
|
+
|
264
|
+
private void handleMappingStart(ThreadContext context, MappingStartEvent mse, boolean tainted, IRubyObject handler) {
|
265
|
+
Ruby runtime = context.runtime;
|
266
|
+
IRubyObject anchor = stringOrNilFor(runtime, mse.getAnchor(), tainted);
|
267
|
+
IRubyObject tag = stringOrNilFor(runtime, mse.getTag(), tainted);
|
268
|
+
IRubyObject implicit = runtime.newBoolean(mse.getImplicit());
|
269
|
+
IRubyObject style = runtime.newFixnum(translateFlowStyle(mse.getFlowStyle()));
|
270
|
+
|
271
|
+
invoke(context, handler, "start_mapping", anchor, tag, implicit, style);
|
272
|
+
}
|
273
|
+
|
274
|
+
private void handleScalar(ThreadContext context, ScalarEvent se, boolean tainted, IRubyObject handler) {
|
275
|
+
Ruby runtime = context.runtime;
|
276
|
+
IRubyObject anchor = stringOrNilFor(runtime, se.getAnchor(), tainted);
|
277
|
+
IRubyObject tag = stringOrNilFor(runtime, se.getTag(), tainted);
|
278
|
+
IRubyObject plain_implicit = runtime.newBoolean(se.getImplicit().canOmitTagInPlainScalar());
|
279
|
+
IRubyObject quoted_implicit = runtime.newBoolean(se.getImplicit().canOmitTagInNonPlainScalar());
|
280
|
+
IRubyObject style = runtime.newFixnum(translateStyle(se.getStyle()));
|
281
|
+
IRubyObject val = stringFor(runtime, se.getValue(), tainted);
|
282
|
+
|
283
|
+
invoke(context, handler, "scalar", val, anchor, tag, plain_implicit,
|
284
|
+
quoted_implicit, style);
|
285
|
+
}
|
286
|
+
|
287
|
+
private void handleSequenceStart(ThreadContext context, SequenceStartEvent sse, boolean tainted, IRubyObject handler) {
|
288
|
+
Ruby runtime = context.runtime;
|
289
|
+
IRubyObject anchor = stringOrNilFor(runtime, sse.getAnchor(), tainted);
|
290
|
+
IRubyObject tag = stringOrNilFor(runtime, sse.getTag(), tainted);
|
291
|
+
IRubyObject implicit = runtime.newBoolean(sse.getImplicit());
|
292
|
+
IRubyObject style = runtime.newFixnum(translateFlowStyle(sse.getFlowStyle()));
|
293
|
+
|
294
|
+
invoke(context, handler, "start_sequence", anchor, tag, implicit, style);
|
295
|
+
}
|
296
|
+
|
297
|
+
private static void raiseParserException(ThreadContext context, IRubyObject yaml, ReaderException re, IRubyObject rbPath) {
|
298
|
+
Ruby runtime;
|
299
|
+
RubyClass se;
|
300
|
+
IRubyObject exception;
|
301
|
+
|
302
|
+
runtime = context.runtime;
|
303
|
+
se = (RubyClass)runtime.getModule("Psych").getConstant("SyntaxError");
|
304
|
+
|
305
|
+
exception = se.newInstance(context,
|
306
|
+
new IRubyObject[] {
|
307
|
+
rbPath,
|
308
|
+
runtime.newFixnum(0),
|
309
|
+
runtime.newFixnum(0),
|
310
|
+
runtime.newFixnum(re.getPosition()),
|
311
|
+
(null == re.getName() ? runtime.getNil() : runtime.newString(re.getName())),
|
312
|
+
(null == re.toString() ? runtime.getNil() : runtime.newString(re.toString()))
|
313
|
+
},
|
314
|
+
Block.NULL_BLOCK);
|
315
|
+
|
316
|
+
RubyKernel.raise(context, runtime.getKernel(), new IRubyObject[] { exception }, Block.NULL_BLOCK);
|
317
|
+
}
|
318
|
+
|
319
|
+
private static void raiseParserException(ThreadContext context, IRubyObject yaml, MarkedYAMLException mye, IRubyObject rbPath) {
|
320
|
+
Ruby runtime;
|
321
|
+
Mark mark;
|
322
|
+
RubyClass se;
|
323
|
+
IRubyObject exception;
|
324
|
+
|
325
|
+
runtime = context.runtime;
|
326
|
+
se = (RubyClass)runtime.getModule("Psych").getConstant("SyntaxError");
|
327
|
+
|
328
|
+
mark = mye.getProblemMark();
|
329
|
+
|
330
|
+
exception = se.newInstance(context,
|
331
|
+
new IRubyObject[] {
|
332
|
+
rbPath,
|
333
|
+
runtime.newFixnum(mark.getLine() + 1),
|
334
|
+
runtime.newFixnum(mark.getColumn() + 1),
|
335
|
+
runtime.newFixnum(mark.getIndex()),
|
336
|
+
(null == mye.getProblem() ? runtime.getNil() : runtime.newString(mye.getProblem())),
|
337
|
+
(null == mye.getContext() ? runtime.getNil() : runtime.newString(mye.getContext()))
|
338
|
+
},
|
339
|
+
Block.NULL_BLOCK);
|
340
|
+
|
341
|
+
RubyKernel.raise(context, runtime.getKernel(), new IRubyObject[] { exception }, Block.NULL_BLOCK);
|
342
|
+
}
|
343
|
+
|
344
|
+
private static int translateStyle(Character style) {
|
345
|
+
if (style == null) return 0; // any
|
346
|
+
|
347
|
+
switch (style) {
|
348
|
+
case 0: return 1; // plain
|
349
|
+
case '\'': return 2; // single-quoted
|
350
|
+
case '"': return 3; // double-quoted
|
351
|
+
case '|': return 4; // literal
|
352
|
+
case '>': return 5; // folded
|
353
|
+
default: return 0; // any
|
354
|
+
}
|
355
|
+
}
|
356
|
+
|
357
|
+
private static int translateFlowStyle(Boolean flowStyle) {
|
358
|
+
if (flowStyle == null) return 0; // any
|
359
|
+
|
360
|
+
if (flowStyle) return 2;
|
361
|
+
return 1;
|
362
|
+
}
|
363
|
+
|
364
|
+
@JRubyMethod
|
365
|
+
public IRubyObject mark(ThreadContext context) {
|
366
|
+
Ruby runtime = context.runtime;
|
367
|
+
|
368
|
+
Event event = null;
|
369
|
+
|
370
|
+
if (parser != null) {
|
371
|
+
event = parser.peekEvent();
|
372
|
+
|
373
|
+
if (event == null) event = this.event;
|
374
|
+
}
|
375
|
+
|
376
|
+
if (event == null) {
|
377
|
+
return ((RubyClass)context.runtime.getClassFromPath("Psych::Parser::Mark")).newInstance(
|
378
|
+
context,
|
379
|
+
runtime.newFixnum(0),
|
380
|
+
runtime.newFixnum(0),
|
381
|
+
runtime.newFixnum(0),
|
382
|
+
Block.NULL_BLOCK
|
383
|
+
);
|
384
|
+
}
|
385
|
+
|
386
|
+
Mark mark = event.getStartMark();
|
387
|
+
|
388
|
+
return ((RubyClass)context.runtime.getClassFromPath("Psych::Parser::Mark")).newInstance(
|
389
|
+
context,
|
390
|
+
runtime.newFixnum(mark.getIndex()),
|
391
|
+
runtime.newFixnum(mark.getLine()),
|
392
|
+
runtime.newFixnum(mark.getColumn()),
|
393
|
+
Block.NULL_BLOCK
|
394
|
+
);
|
395
|
+
}
|
396
|
+
|
397
|
+
private Parser parser;
|
398
|
+
private Event event;
|
399
|
+
}
|
@@ -0,0 +1,79 @@
|
|
1
|
+
/***** BEGIN LICENSE BLOCK *****
|
2
|
+
* Version: EPL 1.0/GPL 2.0/LGPL 2.1
|
3
|
+
*
|
4
|
+
* The contents of this file are subject to the Eclipse Public
|
5
|
+
* License Version 1.0 (the "License"); you may not use this file
|
6
|
+
* except in compliance with the License. You may obtain a copy of
|
7
|
+
* the License at http://www.eclipse.org/legal/epl-v10.html
|
8
|
+
*
|
9
|
+
* Software distributed under the License is distributed on an "AS
|
10
|
+
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
11
|
+
* implied. See the License for the specific language governing
|
12
|
+
* rights and limitations under the License.
|
13
|
+
*
|
14
|
+
* Copyright (C) 2010 Charles O Nutter <headius@headius.com>
|
15
|
+
*
|
16
|
+
* Alternatively, the contents of this file may be used under the terms of
|
17
|
+
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
18
|
+
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
19
|
+
* in which case the provisions of the GPL or the LGPL are applicable instead
|
20
|
+
* of those above. If you wish to allow use of your version of this file only
|
21
|
+
* under the terms of either the GPL or the LGPL, and not to allow others to
|
22
|
+
* use your version of this file under the terms of the EPL, indicate your
|
23
|
+
* decision by deleting the provisions above and replace them with the notice
|
24
|
+
* and other provisions required by the GPL or the LGPL. If you do not delete
|
25
|
+
* the provisions above, a recipient may use your version of this file under
|
26
|
+
* the terms of any one of the EPL, the GPL or the LGPL.
|
27
|
+
***** END LICENSE BLOCK *****/
|
28
|
+
package org.jruby.ext.psych;
|
29
|
+
|
30
|
+
import org.jruby.Ruby;
|
31
|
+
import org.jruby.RubyClass;
|
32
|
+
import org.jruby.RubyModule;
|
33
|
+
import org.jruby.RubyObject;
|
34
|
+
import org.jruby.RubyException;
|
35
|
+
import org.jruby.anno.JRubyMethod;
|
36
|
+
import org.jruby.exceptions.RaiseException;
|
37
|
+
import org.jruby.runtime.ThreadContext;
|
38
|
+
import org.jruby.runtime.builtin.IRubyObject;
|
39
|
+
import static org.jruby.runtime.Visibility.*;
|
40
|
+
|
41
|
+
public class PsychToRuby {
|
42
|
+
public static void initPsychToRuby(Ruby runtime, RubyModule psych) {
|
43
|
+
RubyClass classLoader = runtime.defineClassUnder("ClassLoader", runtime.getObject(), RubyObject.OBJECT_ALLOCATOR, psych);
|
44
|
+
|
45
|
+
RubyModule visitors = runtime.defineModuleUnder("Visitors", psych);
|
46
|
+
RubyClass visitor = runtime.defineClassUnder("Visitor", runtime.getObject(), runtime.getObject().getAllocator(), visitors);
|
47
|
+
RubyClass psychToRuby = runtime.defineClassUnder("ToRuby", visitor, RubyObject.OBJECT_ALLOCATOR, visitors);
|
48
|
+
|
49
|
+
psychToRuby.defineAnnotatedMethods(ToRuby.class);
|
50
|
+
classLoader.defineAnnotatedMethods(ClassLoader.class);
|
51
|
+
}
|
52
|
+
|
53
|
+
public static class ToRuby {
|
54
|
+
@JRubyMethod(visibility = PRIVATE)
|
55
|
+
public static IRubyObject build_exception(ThreadContext context, IRubyObject self, IRubyObject klass, IRubyObject message) {
|
56
|
+
if (klass instanceof RubyClass) {
|
57
|
+
IRubyObject exception = ((RubyClass)klass).allocate();
|
58
|
+
((RubyException)exception).message = message;
|
59
|
+
return exception;
|
60
|
+
} else {
|
61
|
+
throw context.runtime.newTypeError(klass, context.runtime.getClassClass());
|
62
|
+
}
|
63
|
+
}
|
64
|
+
}
|
65
|
+
|
66
|
+
public static class ClassLoader {
|
67
|
+
@JRubyMethod(visibility = PRIVATE)
|
68
|
+
public static IRubyObject path2class(ThreadContext context, IRubyObject self, IRubyObject path) {
|
69
|
+
try {
|
70
|
+
return context.runtime.getClassFromPath(path.asJavaString());
|
71
|
+
} catch (RaiseException re) {
|
72
|
+
if (re.getException().getMetaClass() == context.runtime.getNameError()) {
|
73
|
+
throw context.runtime.newArgumentError("undefined class/module " + path);
|
74
|
+
}
|
75
|
+
throw re;
|
76
|
+
}
|
77
|
+
}
|
78
|
+
}
|
79
|
+
}
|