comparison truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/utilities/JSONHelper.java @ 21951:9c8c0937da41

Moving all sources into truffle subdirectory
author Jaroslav Tulach <jaroslav.tulach@oracle.com>
date Wed, 17 Jun 2015 10:58:08 +0200
parents graal/com.oracle.truffle.api/src/com/oracle/truffle/api/utilities/JSONHelper.java@c88ab4f1f04a
children dc83cc1f94f2
comparison
equal deleted inserted replaced
21950:2a5011c7e641 21951:9c8c0937da41
1 /*
2 * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25 package com.oracle.truffle.api.utilities;
26
27 import java.util.*;
28
29 import com.oracle.truffle.api.nodes.*;
30 import com.oracle.truffle.api.source.*;
31
32 /**
33 * Helper function that allows to dump the AST during creation to a JSON format.
34 */
35 public class JSONHelper {
36
37 private static StringBuilder AstJsonDumpBuilder = new StringBuilder();
38
39 public static void dumpNewChild(Node parentNode, Node childNode) {
40 if (AstJsonDumpBuilder != null) {
41 AstJsonDumpBuilder.append("{ \"action\": \"insertNode\", \"parentId\": \"" + getID(parentNode) + "\", \"newId\": \"" + getID(childNode) + "\" },\n");
42 }
43 }
44
45 public static void dumpReplaceChild(Node oldNode, Node newNode, CharSequence reason) {
46 if (AstJsonDumpBuilder != null) {
47 AstJsonDumpBuilder.append("{ \"action\": \"replaceNode\", \"oldId\": \"" + getID(oldNode) + "\", \"newId\": \"" + getID(newNode) + "\", \"reason\": " + quote(reason) + " },\n");
48 }
49 }
50
51 public static void dumpNewNode(Node newNode) {
52 if (AstJsonDumpBuilder != null) {
53 AstJsonDumpBuilder.append("{ \"action\": \"createNode\", \"newId\": \"" + getID(newNode) + "\", \"type\": \"" + getType(newNode) + "\", \"description\": \"" + newNode.getDescription() +
54 "\", \"language\": \"" + newNode.getLanguage() + "\"" + getSourceSectionInfo(newNode) + " },\n");
55 }
56 }
57
58 private static String getSourceSectionInfo(Node newNode) {
59 SourceSection sourceSection = newNode.getSourceSection();
60 if (sourceSection != null) {
61 return ", \"identifier\": \"" + sourceSection.getIdentifier() + "\" ";
62 } else {
63 return "";
64 }
65 }
66
67 public static String getResult() {
68 return AstJsonDumpBuilder.toString();
69 }
70
71 private static String getID(Node newChild) {
72 return String.valueOf(newChild.hashCode());
73 }
74
75 private static String getType(Node node) {
76 return node.getClass().getSimpleName();
77 }
78
79 private static String quote(CharSequence value) {
80 StringBuilder builder = new StringBuilder(value.length() + 2);
81 builder.append('"');
82 for (int i = 0; i < value.length(); i++) {
83 char c = value.charAt(i);
84 switch (c) {
85 case '"':
86 builder.append("\\\"");
87 break;
88 case '\\':
89 builder.append("\\\\");
90 break;
91 case '\b':
92 builder.append("\\b");
93 break;
94 case '\f':
95 builder.append("\\f");
96 break;
97 case '\n':
98 builder.append("\\n");
99 break;
100 case '\r':
101 builder.append("\\r");
102 break;
103 case '\t':
104 builder.append("\\t");
105 break;
106 default: {
107 if (c < ' ') {
108 builder.append("\\u00");
109 builder.append(Character.forDigit((c >> 4) & 0xF, 16));
110 builder.append(Character.forDigit(c & 0xF, 16));
111 } else {
112 builder.append(c);
113 }
114 }
115 }
116 }
117 builder.append('"');
118 return builder.toString();
119 }
120
121 public static void restart() {
122 AstJsonDumpBuilder = new StringBuilder();
123 }
124
125 public static JSONObjectBuilder object() {
126 return new JSONObjectBuilder();
127 }
128
129 public static JSONArrayBuilder array() {
130 return new JSONArrayBuilder();
131 }
132
133 public abstract static class JSONStringBuilder {
134 @Override
135 public final String toString() {
136 StringBuilder sb = new StringBuilder();
137 appendTo(sb);
138 return sb.toString();
139 }
140
141 protected abstract void appendTo(StringBuilder sb);
142
143 protected static void appendValue(StringBuilder sb, Object value) {
144 if (value instanceof JSONStringBuilder) {
145 ((JSONStringBuilder) value).appendTo(sb);
146 } else if (value instanceof Integer || value instanceof Boolean || value == null) {
147 sb.append(value);
148 } else {
149 sb.append(quote(String.valueOf(value)));
150 }
151 }
152 }
153
154 public static final class JSONObjectBuilder extends JSONStringBuilder {
155 private final Map<String, Object> contents = new LinkedHashMap<>();
156
157 private JSONObjectBuilder() {
158 }
159
160 public JSONObjectBuilder add(String key, String value) {
161 contents.put(key, value);
162 return this;
163 }
164
165 public JSONObjectBuilder add(String key, Number value) {
166 contents.put(key, value);
167 return this;
168 }
169
170 public JSONObjectBuilder add(String key, Boolean value) {
171 contents.put(key, value);
172 return this;
173 }
174
175 public JSONObjectBuilder add(String key, JSONStringBuilder value) {
176 contents.put(key, value);
177 return this;
178 }
179
180 @Override
181 protected void appendTo(StringBuilder sb) {
182 sb.append("{");
183 boolean comma = false;
184 for (Map.Entry<String, Object> entry : contents.entrySet()) {
185 if (comma) {
186 sb.append(", ");
187 }
188 sb.append(quote(entry.getKey()));
189 sb.append(": ");
190 appendValue(sb, entry.getValue());
191 comma = true;
192 }
193 sb.append("}");
194 }
195 }
196
197 public static final class JSONArrayBuilder extends JSONStringBuilder {
198 private final List<Object> contents = new ArrayList<>();
199
200 private JSONArrayBuilder() {
201 }
202
203 public JSONArrayBuilder add(String value) {
204 contents.add(value);
205 return this;
206 }
207
208 public JSONArrayBuilder add(Number value) {
209 contents.add(value);
210 return this;
211 }
212
213 public JSONArrayBuilder add(Boolean value) {
214 contents.add(value);
215 return this;
216 }
217
218 public JSONArrayBuilder add(JSONStringBuilder value) {
219 contents.add(value);
220 return this;
221 }
222
223 @Override
224 protected void appendTo(StringBuilder sb) {
225 sb.append("[");
226 boolean comma = false;
227 for (Object value : contents) {
228 if (comma) {
229 sb.append(", ");
230 }
231 appendValue(sb, value);
232 comma = true;
233 }
234 sb.append("]");
235 }
236 }
237 }