jaroslav@717: /** jaroslav@717: * Back 2 Browser Bytecode Translator jaroslav@717: * Copyright (C) 2012 Jaroslav Tulach jaroslav@717: * jaroslav@717: * This program is free software: you can redistribute it and/or modify jaroslav@717: * it under the terms of the GNU General Public License as published by jaroslav@717: * the Free Software Foundation, version 2 of the License. jaroslav@717: * jaroslav@717: * This program is distributed in the hope that it will be useful, jaroslav@717: * but WITHOUT ANY WARRANTY; without even the implied warranty of jaroslav@717: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the jaroslav@717: * GNU General Public License for more details. jaroslav@717: * jaroslav@717: * You should have received a copy of the GNU General Public License jaroslav@717: * along with this program. Look for COPYING file in the top folder. jaroslav@717: * If not, see http://opensource.org/licenses/GPL-2.0. jaroslav@717: */ jaroslav@717: package org.apidesign.bck2brwsr.ide.editor; jaroslav@717: jaroslav@717: import java.util.regex.Matcher; jaroslav@717: import java.util.regex.Pattern; jaroslav@717: jaroslav@717: public class JsniCommentTokenizer { jaroslav@717: jaroslav@717: /** jaroslav@717: * Tokenize the contents of JSNI comment into the provided {@linkplain Sink}. jaroslav@717: * @param in the contents of JSNI comment jaroslav@717: * @param out the sink that consumes parsed tokens jaroslav@717: */ jaroslav@717: public void process(final String in, final Sink out) { jaroslav@717: final Matcher member = Pattern.compile("@([^:]+)::([a-zA-Z_$][a-zA-Z\\d_$]*)").matcher(in); jaroslav@717: final Matcher signature = Pattern.compile("\\(([^\\)]*)\\)").matcher(in); jaroslav@717: jaroslav@717: int i = 0; jaroslav@717: while (true) { jaroslav@717: if (member.find(i)) { jaroslav@717: final int memberStart = member.start(); jaroslav@717: final int memberEnd = member.end(); jaroslav@717: if (memberStart > i) out.javascript(in.substring(i, memberStart)); jaroslav@717: jaroslav@717: final String clazz = member.group(1); jaroslav@717: final String name = member.group(2); jaroslav@717: jaroslav@717: if (in.charAt(memberEnd) == '(') { jaroslav@717: if (!signature.find(memberEnd)) { jaroslav@717: throw new IllegalStateException("Expected method signature"); jaroslav@717: } jaroslav@717: assert signature.start() == memberEnd; jaroslav@717: out.method(clazz, name, signature.group(1)); jaroslav@717: i = signature.end(); jaroslav@717: } else { jaroslav@717: out.field(clazz, name); jaroslav@717: i = memberEnd; jaroslav@717: } jaroslav@717: } else { jaroslav@717: out.javascript(in.substring(i, in.length())); jaroslav@717: break; jaroslav@717: } jaroslav@717: } jaroslav@717: } jaroslav@717: jaroslav@717: jaroslav@717: public static interface Sink { jaroslav@717: void javascript(String s); jaroslav@717: jaroslav@717: void method(String clazz, String method, String signature); jaroslav@717: jaroslav@717: void field(String clazz, String field); jaroslav@717: } jaroslav@717: }