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 }