1 /*
2 * Copyright (c) 2024, 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
26 package jdk.incubator.code.extern.impl;
27
28 import jdk.incubator.code.extern.ExternalizedTypeElement;
29 import jdk.incubator.code.extern.impl.Tokens.TokenKind;
30
31 import java.util.ArrayList;
32 import java.util.List;
33
34 public final class DescParser {
35 private DescParser() {}
36
37 /**
38 * Parse an externalized type element from its serialized textual form.
39 * @param desc the serialized externalized type element
40 * @return the externalized type element
41 */
42 public static ExternalizedTypeElement parseExTypeElem(String desc) {
43 Scanner s = Scanner.factory().newScanner(desc);
44 s.nextToken();
45 return parseExTypeElem(s);
46 }
47
48 // ExType:
49 // ExTypeName
50 // ExTypeName '<' ExType* '>'
51 //
52 // ExTypeName:
53 // ExIdentPart
54 // ExIdentPart ExIdentSep ExIdentPart
55 //
56 // ExIdentPart:
57 // ident
58 // string
59 //
60 // ExIdentSep:
61 // '.'
62 // ':'
63 public static ExternalizedTypeElement parseExTypeElem(Lexer l) {
64 StringBuilder identifier = new StringBuilder();
65 identifier.append(parseExTypeNamePart(l));
66 while (l.is(TokenKind.DOT) || l.is(TokenKind.COLON)) {
67 identifier.append(l.token().kind.name);
68 l.nextToken();
69 identifier.append(parseExTypeNamePart(l));
70 }
71 List<ExternalizedTypeElement> args = new ArrayList<>();
72 if (l.is(TokenKind.LT)) {
73 l.accept(TokenKind.LT);
74 args.add(parseExTypeElem(l));
75 while (l.is(TokenKind.COMMA)) {
76 l.accept(TokenKind.COMMA);
77 args.add(parseExTypeElem(l));
78 }
79 l.accept(TokenKind.GT);
80 }
81 return new ExternalizedTypeElement(identifier.toString(), args);
82 }
83
84 private static String parseExTypeNamePart(Lexer l) {
85 String namePart = switch (l.token().kind) {
86 case IDENTIFIER -> l.token().name();
87 case STRINGLITERAL -> "\"" + l.token().stringVal() + "\"";
88 default -> throw l.unexpected();
89 };
90 l.nextToken();
91 return namePart;
92 }
93 }