1040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato/* 2040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato * Copyright (C) 2011 Google Inc. 3040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato * 4040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato * Licensed under the Apache License, Version 2.0 (the "License"); 5040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato * you may not use this file except in compliance with the License. 6040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato * You may obtain a copy of the License at 7040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato * 8040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato * http://www.apache.org/licenses/LICENSE-2.0 9040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato * 10040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato * Unless required by applicable law or agreed to in writing, software 11040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato * distributed under the License is distributed on an "AS IS" BASIS, 12040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato * See the License for the specific language governing permissions and 14040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato * limitations under the License. 15040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato */ 16040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato 17040992567205c3b6e4ee01bfb2893bceb915357cJoe Onoratopackage com.google.doclava.apicheck; 18040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato 19040992567205c3b6e4ee01bfb2893bceb915357cJoe Onoratoimport com.google.doclava.AnnotationInstanceInfo; 20040992567205c3b6e4ee01bfb2893bceb915357cJoe Onoratoimport com.google.doclava.ClassInfo; 21040992567205c3b6e4ee01bfb2893bceb915357cJoe Onoratoimport com.google.doclava.Converter; 22040992567205c3b6e4ee01bfb2893bceb915357cJoe Onoratoimport com.google.doclava.FieldInfo; 23040992567205c3b6e4ee01bfb2893bceb915357cJoe Onoratoimport com.google.doclava.MethodInfo; 24040992567205c3b6e4ee01bfb2893bceb915357cJoe Onoratoimport com.google.doclava.PackageInfo; 25040992567205c3b6e4ee01bfb2893bceb915357cJoe Onoratoimport com.google.doclava.ParameterInfo; 26040992567205c3b6e4ee01bfb2893bceb915357cJoe Onoratoimport com.google.doclava.SourcePositionInfo; 27040992567205c3b6e4ee01bfb2893bceb915357cJoe Onoratoimport com.google.doclava.TypeInfo; 28040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato 29d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sappersteinimport java.io.IOException; 30d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sappersteinimport java.io.InputStream; 31d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sappersteinimport java.util.ArrayList; 32d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sappersteinimport java.util.LinkedList; 33d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein 34040992567205c3b6e4ee01bfb2893bceb915357cJoe Onoratoclass ApiFile { 35040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato 36040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato public static ApiInfo parseApi(String filename, InputStream stream) throws ApiParseException { 37040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato final int CHUNK = 1024*1024; 38040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato int hint = 0; 39040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato try { 40040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato hint = stream.available() + CHUNK; 41040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } catch (IOException ex) { 42040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 43040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato if (hint < CHUNK) { 44040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato hint = CHUNK; 45040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 46040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato byte[] buf = new byte[hint]; 47040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato int size = 0; 48040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato 49040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato try { 50040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato while (true) { 51040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato if (size == buf.length) { 52040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato byte[] tmp = new byte[buf.length+CHUNK]; 53040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato System.arraycopy(buf, 0, tmp, 0, buf.length); 54040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato buf = tmp; 55040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 56040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato int amt = stream.read(buf, size, (buf.length-size)); 57040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato if (amt < 0) { 58040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato break; 59040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } else { 60040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato size += amt; 61040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 62040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 63040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } catch (IOException ex) { 64040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato throw new ApiParseException("Error reading API file", ex); 65040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 66040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato 67040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato final Tokenizer tokenizer = new Tokenizer(filename, (new String(buf, 0, size)).toCharArray()); 68040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato final ApiInfo api = new ApiInfo(); 69040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato 70040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato while (true) { 71040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato String token = tokenizer.getToken(); 72040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato if (token == null) { 73040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato break; 74040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 75040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato if ("package".equals(token)) { 76040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato parsePackage(api, tokenizer); 77040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } else { 78040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato throw new ApiParseException("expected package got " + token, tokenizer.getLine()); 79040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 80040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 81040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato 82040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato api.resolveSuperclasses(); 83040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato api.resolveInterfaces(); 84040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato 85040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato return api; 86040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 87040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato 88040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato private static void parsePackage(ApiInfo api, Tokenizer tokenizer) 89040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato throws ApiParseException { 90040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato String token; 91040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato String name; 92040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato PackageInfo pkg; 93040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato 94040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato token = tokenizer.requireToken(); 95040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato assertIdent(tokenizer, token); 96040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato name = token; 97040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato pkg = new PackageInfo(name, tokenizer.pos()); 98040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato token = tokenizer.requireToken(); 99040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato if (!"{".equals(token)) { 100040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato throw new ApiParseException("expected '{' got " + token, tokenizer.getLine()); 101040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 102040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato while (true) { 103040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato token = tokenizer.requireToken(); 104040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato if ("}".equals(token)) { 105040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato break; 106040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } else { 107040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato parseClass(api, pkg, tokenizer, token); 108040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 109040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 110040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato api.addPackage(pkg); 111040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 112040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato 113040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato private static void parseClass(ApiInfo api, PackageInfo pkg, Tokenizer tokenizer, String token) 114040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato throws ApiParseException { 115040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato boolean pub = false; 116040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato boolean prot = false; 117040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato boolean pkgpriv = false; 118040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato boolean stat = false; 119040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato boolean fin = false; 120040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato boolean abs = false; 121040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato boolean dep = false; 122040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato boolean iface; 123040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato String name; 124040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato String qname; 125040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato String ext = null; 126040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato ClassInfo cl; 127040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato 128040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato if ("public".equals(token)) { 129040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato pub = true; 130040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato token = tokenizer.requireToken(); 131040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } else if ("protected".equals(token)) { 132040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato prot = true; 133040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato token = tokenizer.requireToken(); 134040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } else { 135040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato pkgpriv = true; 136040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 137040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato if ("static".equals(token)) { 138040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato stat = true; 139040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato token = tokenizer.requireToken(); 140040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 141040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato if ("final".equals(token)) { 142040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato fin = true; 143040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato token = tokenizer.requireToken(); 144040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 145040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato if ("abstract".equals(token)) { 146040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato abs = true; 147040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato token = tokenizer.requireToken(); 148040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 149040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato if ("deprecated".equals(token)) { 150040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato dep = true; 151040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato token = tokenizer.requireToken(); 152040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 153040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato if ("class".equals(token)) { 154040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato iface = false; 155040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato token = tokenizer.requireToken(); 156040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } else if ("interface".equals(token)) { 157040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato iface = true; 158040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato token = tokenizer.requireToken(); 159040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } else { 160040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato throw new ApiParseException("missing class or interface. got: " + token, tokenizer.getLine()); 161040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 162040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato assertIdent(tokenizer, token); 163040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato name = token; 164040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato token = tokenizer.requireToken(); 165040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato qname = qualifiedName(pkg.name(), name, null); 166040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato cl = new ClassInfo(null/*classDoc*/, ""/*rawCommentText*/, tokenizer.pos(), pub, prot, 167040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato pkgpriv, false/*isPrivate*/, stat, iface, abs, true/*isOrdinaryClass*/, 168040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato false/*isException*/, false/*isError*/, false/*isEnum*/, false/*isAnnotation*/, 169040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato fin, false/*isIncluded*/, name, qname, null/*qualifiedTypeName*/, false/*isPrimitive*/); 170040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato cl.setDeprecated(dep); 171040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato if ("extends".equals(token)) { 172040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato token = tokenizer.requireToken(); 173040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato assertIdent(tokenizer, token); 174040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato ext = token; 175040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato token = tokenizer.requireToken(); 176040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 177040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato // Resolve superclass after done parsing 178040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato api.mapClassToSuper(cl, ext); 179040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato final TypeInfo typeInfo = Converter.obtainTypeFromString(qname) ; 180040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato cl.setTypeInfo(typeInfo); 181d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein cl.setAnnotations(new ArrayList<AnnotationInstanceInfo>()); 182040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato if ("implements".equals(token)) { 183040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato while (true) { 184040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato token = tokenizer.requireToken(); 185040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato if ("{".equals(token)) { 186040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato break; 187040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } else { 188040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato /// TODO 189040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato if (!",".equals(token)) { 190040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato api.mapClassToInterface(cl, token); 191040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 192040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 193040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 194040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 195040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato if (!"{".equals(token)) { 196040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato throw new ApiParseException("expected {", tokenizer.getLine()); 197040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 198040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato token = tokenizer.requireToken(); 199040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato while (true) { 200040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato if ("}".equals(token)) { 201040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato break; 202040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } else if ("ctor".equals(token)) { 203040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato token = tokenizer.requireToken(); 204040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato parseConstructor(tokenizer, cl, token); 205040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } else if ("method".equals(token)) { 206040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato token = tokenizer.requireToken(); 207040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato parseMethod(tokenizer, cl, token); 208040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } else if ("field".equals(token)) { 209040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato token = tokenizer.requireToken(); 210132afe44b3b7963e47d4c32948b2667ddc00062cJoe Onorato parseField(tokenizer, cl, token, false); 211132afe44b3b7963e47d4c32948b2667ddc00062cJoe Onorato } else if ("enum_constant".equals(token)) { 212132afe44b3b7963e47d4c32948b2667ddc00062cJoe Onorato token = tokenizer.requireToken(); 213132afe44b3b7963e47d4c32948b2667ddc00062cJoe Onorato parseField(tokenizer, cl, token, true); 214040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } else { 215132afe44b3b7963e47d4c32948b2667ddc00062cJoe Onorato throw new ApiParseException("expected ctor, enum_constant, field or method", tokenizer.getLine()); 216040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 217040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato token = tokenizer.requireToken(); 218040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 219040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato pkg.addClass(cl); 220040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 221040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato 222040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato private static void parseConstructor(Tokenizer tokenizer, ClassInfo cl, String token) 223040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato throws ApiParseException { 224040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato boolean pub = false; 225040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato boolean prot = false; 226040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato boolean pkgpriv = false; 227040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato boolean dep = false; 228040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato String name; 229040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato MethodInfo method; 230040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato 231040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato if ("public".equals(token)) { 232040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato pub = true; 233040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato token = tokenizer.requireToken(); 234040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } else if ("protected".equals(token)) { 235040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato prot = true; 236040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato token = tokenizer.requireToken(); 237040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } else { 238040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato pkgpriv = true; 239040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 240040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato if ("deprecated".equals(token)) { 241040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato dep = true; 242040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato token = tokenizer.requireToken(); 243040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 244040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato assertIdent(tokenizer, token); 245040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato name = token; 246040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato token = tokenizer.requireToken(); 247040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato if (!"(".equals(token)) { 248040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato throw new ApiParseException("expected (", tokenizer.getLine()); 249040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 250040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato //method = new MethodInfo(name, cl.qualifiedName(), false/*static*/, false/*final*/, dep, 251040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato // pub ? "public" : "protected", tokenizer.pos(), cl); 252d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein method = new MethodInfo(""/*rawCommentText*/, new ArrayList<TypeInfo>()/*typeParameters*/, 253040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato name, null/*signature*/, cl, cl, pub, prot, pkgpriv, false/*isPrivate*/, false/*isFinal*/, 254040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato false/*isStatic*/, false/*isSynthetic*/, false/*isAbstract*/, false/*isSynthetic*/, 255040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato false/*isNative*/, 256040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato false /*isAnnotationElement*/, "constructor", null/*flatSignature*/, 257d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein null/*overriddenMethod*/, cl.asTypeInfo(), new ArrayList<ParameterInfo>(), 258d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein new ArrayList<ClassInfo>()/*thrownExceptions*/, tokenizer.pos(), 259d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein new ArrayList<AnnotationInstanceInfo>()/*annotations*/); 260040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato method.setDeprecated(dep); 261040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato token = tokenizer.requireToken(); 262040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato parseParameterList(tokenizer, method, token); 263040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato token = tokenizer.requireToken(); 264040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato if ("throws".equals(token)) { 265040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato token = parseThrows(tokenizer, method); 266040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 267040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato if (!";".equals(token)) { 268040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato throw new ApiParseException("expected ; found " + token, tokenizer.getLine()); 269040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 270040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato cl.addConstructor(method); 271040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 272040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato 273040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato private static void parseMethod(Tokenizer tokenizer, ClassInfo cl, String token) 274040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato throws ApiParseException { 275040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato boolean pub = false; 276040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato boolean prot = false; 277040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato boolean pkgpriv = false; 278040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato boolean stat = false; 279040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato boolean fin = false; 280040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato boolean abs = false; 281040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato boolean dep = false; 282040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato boolean syn = false; 283040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato String type; 284040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato String name; 285040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato String ext = null; 286040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato MethodInfo method; 287040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato 288040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato if ("public".equals(token)) { 289040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato pub = true; 290040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato token = tokenizer.requireToken(); 291040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } else if ("protected".equals(token)) { 292040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato prot = true; 293040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato token = tokenizer.requireToken(); 294040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } else { 295040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato pkgpriv = true; 296040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 297040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato if ("static".equals(token)) { 298040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato stat = true; 299040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato token = tokenizer.requireToken(); 300040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 301040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato if ("final".equals(token)) { 302040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato fin = true; 303040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato token = tokenizer.requireToken(); 304040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 305040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato if ("abstract".equals(token)) { 306040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato abs = true; 307040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato token = tokenizer.requireToken(); 308040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 309040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato if ("deprecated".equals(token)) { 310040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato dep = true; 311040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato token = tokenizer.requireToken(); 312040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 313040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato if ("synchronized".equals(token)) { 314040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato syn = true; 315040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato token = tokenizer.requireToken(); 316040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 317040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato assertIdent(tokenizer, token); 318040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato type = token; 319040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato token = tokenizer.requireToken(); 320040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato assertIdent(tokenizer, token); 321040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato name = token; 322d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein method = new MethodInfo(""/*rawCommentText*/, new ArrayList<TypeInfo>()/*typeParameters*/, 323040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato name, null/*signature*/, cl, cl, pub, prot, pkgpriv, false/*isPrivate*/, fin, 324040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato stat, false/*isSynthetic*/, abs/*isAbstract*/, syn, false/*isNative*/, 325040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato false /*isAnnotationElement*/, "method", null/*flatSignature*/, null/*overriddenMethod*/, 326d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein Converter.obtainTypeFromString(type), new ArrayList<ParameterInfo>(), 327d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein new ArrayList<ClassInfo>()/*thrownExceptions*/, tokenizer.pos(), 328d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein new ArrayList<AnnotationInstanceInfo>()/*annotations*/); 329040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato method.setDeprecated(dep); 330040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato token = tokenizer.requireToken(); 331040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato if (!"(".equals(token)) { 332040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato throw new ApiParseException("expected (", tokenizer.getLine()); 333040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 334040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato token = tokenizer.requireToken(); 335040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato parseParameterList(tokenizer, method, token); 336040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato token = tokenizer.requireToken(); 337040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato if ("throws".equals(token)) { 338040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato token = parseThrows(tokenizer, method); 339040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 340040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato if (!";".equals(token)) { 341040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato throw new ApiParseException("expected ; found " + token, tokenizer.getLine()); 342040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 343040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato cl.addMethod(method); 344040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 345040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato 346132afe44b3b7963e47d4c32948b2667ddc00062cJoe Onorato private static void parseField(Tokenizer tokenizer, ClassInfo cl, String token, boolean isEnum) 347040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato throws ApiParseException { 348040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato boolean pub = false; 349040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato boolean prot = false; 350040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato boolean pkgpriv = false; 351040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato boolean stat = false; 352040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato boolean fin = false; 353040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato boolean dep = false; 354040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato boolean trans = false; 355040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato boolean vol = false; 356040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato String type; 357040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato String name; 358040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato String val = null; 359040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato Object v; 360040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato FieldInfo field; 361040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato 362040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato if ("public".equals(token)) { 363040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato pub = true; 364040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato token = tokenizer.requireToken(); 365040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } else if ("protected".equals(token)) { 366040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato prot = true; 367040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato token = tokenizer.requireToken(); 368040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } else { 369040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato pkgpriv = true; 370040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 371040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato if ("static".equals(token)) { 372040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato stat = true; 373040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato token = tokenizer.requireToken(); 374040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 375040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato if ("final".equals(token)) { 376040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato fin = true; 377040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato token = tokenizer.requireToken(); 378040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 379040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato if ("deprecated".equals(token)) { 380040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato dep = true; 381040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato token = tokenizer.requireToken(); 382040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 383040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato if ("transient".equals(token)) { 384040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato trans = true; 385040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato token = tokenizer.requireToken(); 386040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 387040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato if ("volatile".equals(token)) { 388040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato vol = true; 389040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato token = tokenizer.requireToken(); 390040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 391040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato assertIdent(tokenizer, token); 392040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato type = token; 393040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato token = tokenizer.requireToken(); 394040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato assertIdent(tokenizer, token); 395040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato name = token; 396040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato token = tokenizer.requireToken(); 397040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato if ("=".equals(token)) { 398040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato token = tokenizer.requireToken(false); 399040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato val = token; 400040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato token = tokenizer.requireToken(); 401040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 402040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato if (!";".equals(token)) { 403040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato throw new ApiParseException("expected ; found " + token, tokenizer.getLine()); 404040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 405040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato try { 406040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato v = parseValue(type, val); 407040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } catch (ApiParseException ex) { 408040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato ex.line = tokenizer.getLine(); 409040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato throw ex; 410040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 411040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato field = new FieldInfo(name, cl, cl, pub, prot, pkgpriv, false/*isPrivate*/, fin, stat, 412040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato trans, vol, false, Converter.obtainTypeFromString(type), "", v, tokenizer.pos(), 413d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein new ArrayList<AnnotationInstanceInfo>()); 414040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato field.setDeprecated(dep); 415132afe44b3b7963e47d4c32948b2667ddc00062cJoe Onorato if (isEnum) { 416132afe44b3b7963e47d4c32948b2667ddc00062cJoe Onorato cl.addEnumConstant(field); 417132afe44b3b7963e47d4c32948b2667ddc00062cJoe Onorato } else { 418132afe44b3b7963e47d4c32948b2667ddc00062cJoe Onorato cl.addField(field); 419132afe44b3b7963e47d4c32948b2667ddc00062cJoe Onorato } 420040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 421040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato 422040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato public static Object parseValue(String type, String val) throws ApiParseException { 423040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato if (val != null) { 424040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato if ("boolean".equals(type)) { 425040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato return "true".equals(val) ? Boolean.TRUE : Boolean.FALSE; 426040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } else if ("byte".equals(type)) { 427040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato return Integer.valueOf(val); 428040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } else if ("short".equals(type)) { 429040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato return Integer.valueOf(val); 430040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } else if ("int".equals(type)) { 431040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato return Integer.valueOf(val); 432040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } else if ("long".equals(type)) { 433040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato return Long.valueOf(val.substring(0, val.length()-1)); 434040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } else if ("float".equals(type)) { 4351e0d370c6a4c165cb8c74f53cb035e5521e0cd87Jeff Hamilton if ("(1.0f/0.0f)".equals(val) || "(1.0f / 0.0f)".equals(val)) { 436040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato return Float.POSITIVE_INFINITY; 4371e0d370c6a4c165cb8c74f53cb035e5521e0cd87Jeff Hamilton } else if ("(-1.0f/0.0f)".equals(val) || "(-1.0f / 0.0f)".equals(val)) { 438040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato return Float.NEGATIVE_INFINITY; 4391e0d370c6a4c165cb8c74f53cb035e5521e0cd87Jeff Hamilton } else if ("(0.0f/0.0f)".equals(val) || "(0.0f / 0.0f)".equals(val)) { 440040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato return Float.NaN; 441040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } else { 442040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato return Float.valueOf(val); 443040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 444040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } else if ("double".equals(type)) { 4451e0d370c6a4c165cb8c74f53cb035e5521e0cd87Jeff Hamilton if ("(1.0/0.0)".equals(val) || "(1.0 / 0.0)".equals(val)) { 446040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato return Double.POSITIVE_INFINITY; 4471e0d370c6a4c165cb8c74f53cb035e5521e0cd87Jeff Hamilton } else if ("(-1.0/0.0)".equals(val) || "(-1.0 / 0.0)".equals(val)) { 448040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato return Double.NEGATIVE_INFINITY; 4491e0d370c6a4c165cb8c74f53cb035e5521e0cd87Jeff Hamilton } else if ("(0.0/0.0)".equals(val) || "(0.0 / 0.0)".equals(val)) { 450040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato return Double.NaN; 451040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } else { 452040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato return Double.valueOf(val); 453040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 454040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } else if ("char".equals(type)) { 455040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato return new Integer((char)Integer.parseInt(val)); 456040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } else if ("java.lang.String".equals(type)) { 457040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato if ("null".equals(val)) { 458040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato return null; 459040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } else { 460040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato return FieldInfo.javaUnescapeString(val.substring(1, val.length()-1)); 461040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 462040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 463040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 464040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato if ("null".equals(val)) { 465040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato return null; 466040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } else { 467040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato return val; 468040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 469040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 470040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato 471040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato private static void parseParameterList(Tokenizer tokenizer, AbstractMethodInfo method, 472040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato String token) throws ApiParseException { 473040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato while (true) { 474040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato if (")".equals(token)) { 475040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato return; 476040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 477040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato 478040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato String type = token; 479040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato String name = null; 480040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato token = tokenizer.requireToken(); 481040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato if (isIdent(token)) { 482040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato name = token; 483040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato token = tokenizer.requireToken(); 484040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 485040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato if (",".equals(token)) { 486040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato token = tokenizer.requireToken(); 487040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } else if (")".equals(token)) { 488040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } else { 489040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato throw new ApiParseException("expected , found " + token, tokenizer.getLine()); 490040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 491040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato method.addParameter(new ParameterInfo(name, type, 492040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato Converter.obtainTypeFromString(type), 493040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato type.endsWith("..."), 494040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato tokenizer.pos())); 495040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato if (type.endsWith("...")) { 496040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato method.setVarargs(true); 497040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 498040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 499040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 500040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato 501040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato private static String parseThrows(Tokenizer tokenizer, AbstractMethodInfo method) 502040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato throws ApiParseException { 503040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato String token = tokenizer.requireToken(); 504040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato boolean comma = true; 505040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato while (true) { 506040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato if (";".equals(token)) { 507040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato return token; 508040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } else if (",".equals(token)) { 509040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato if (comma) { 510040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato throw new ApiParseException("Expected exception, got ','", tokenizer.getLine()); 511040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 512040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato comma = true; 513040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } else { 514040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato if (!comma) { 515040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato throw new ApiParseException("Expected ',' or ';' got " + token, tokenizer.getLine()); 516040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 517040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato comma = false; 518040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato method.addException(token); 519040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 520040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato token = tokenizer.requireToken(); 521040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 522040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 523040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato 524040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato private static String qualifiedName(String pkg, String className, ClassInfo parent) { 525040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato String parentQName = (parent != null) ? (parent.qualifiedName() + ".") : ""; 526040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato return pkg + "." + parentQName + className; 527040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 528040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato 529040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato public static boolean isIdent(String token) { 530040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato return isident(token.charAt(0)); 531040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 532040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato 533040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato public static void assertIdent(Tokenizer tokenizer, String token) throws ApiParseException { 534040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato if (!isident(token.charAt(0))) { 535040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato throw new ApiParseException("Expected identifier: " + token, tokenizer.getLine()); 536040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 537040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 538040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato 539040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato static class Tokenizer { 540040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato char[] mBuf; 541040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato String mFilename; 542040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato int mPos; 543040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato int mLine = 1; 544040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato Tokenizer(String filename, char[] buf) { 545040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato mFilename = filename; 546040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato mBuf = buf; 547040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 548040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato 549040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato public SourcePositionInfo pos() { 550040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato return new SourcePositionInfo(mFilename, mLine, 0); 551040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 552040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato 553040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato public int getLine() { 554040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato return mLine; 555040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 556040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato 557040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato boolean eatWhitespace() { 558040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato boolean ate = false; 559040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato while (mPos < mBuf.length && isspace(mBuf[mPos])) { 560040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato if (mBuf[mPos] == '\n') { 561040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato mLine++; 562040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 563040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato mPos++; 564040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato ate = true; 565040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 566040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato return ate; 567040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 568040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato 569040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato boolean eatComment() { 570040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato if (mPos+1 < mBuf.length) { 571040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato if (mBuf[mPos] == '/' && mBuf[mPos+1] == '/') { 572040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato mPos += 2; 573040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato while (mPos < mBuf.length && !isnewline(mBuf[mPos])) { 574040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato mPos++; 575040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 576040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato return true; 577040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 578040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 579040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato return false; 580040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 581040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato 582040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato void eatWhitespaceAndComments() { 583040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato while (eatWhitespace() || eatComment()) { 584040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 585040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 586040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato 587040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato public String requireToken() throws ApiParseException { 588040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato return requireToken(true); 589040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 590040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato 591040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato public String requireToken(boolean parenIsSep) throws ApiParseException { 592040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato final String token = getToken(parenIsSep); 593040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato if (token != null) { 594040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato return token; 595040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } else { 596040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato throw new ApiParseException("Unexpected end of file", mLine); 597040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 598040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 599040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato 600040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato public String getToken() throws ApiParseException { 601040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato return getToken(true); 602040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 603040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato 604040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato public String getToken(boolean parenIsSep) throws ApiParseException { 605040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato eatWhitespaceAndComments(); 606040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato if (mPos >= mBuf.length) { 607040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato return null; 608040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 609040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato final int line = mLine; 610040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato final char c = mBuf[mPos]; 611040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato final int start = mPos; 612040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato mPos++; 613040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato if (c == '"') { 614040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato final int STATE_BEGIN = 0; 615040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato final int STATE_ESCAPE = 1; 616040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato int state = STATE_BEGIN; 617040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato while (true) { 618040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato if (mPos >= mBuf.length) { 619040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato throw new ApiParseException("Unexpected end of file for \" starting at " + line, mLine); 620040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 621040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato final char k = mBuf[mPos]; 622040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato if (k == '\n' || k == '\r') { 623040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato throw new ApiParseException("Unexpected newline for \" starting at " + line, mLine); 624040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 625040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato mPos++; 626040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato switch (state) { 627040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato case STATE_BEGIN: 628040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato switch (k) { 629040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato case '\\': 630040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato state = STATE_ESCAPE; 631040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato mPos++; 632040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato break; 633040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato case '"': 634040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato return new String(mBuf, start, mPos-start); 635040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 636040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato case STATE_ESCAPE: 637040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato state = STATE_BEGIN; 638040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato break; 639040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 640040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 641040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } else if (issep(c, parenIsSep)) { 642040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato return "" + c; 643040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } else { 644040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato int genericDepth = 0; 645040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato do { 646040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato while (mPos < mBuf.length && !isspace(mBuf[mPos]) && !issep(mBuf[mPos], parenIsSep)) { 647040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato mPos++; 648040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 649040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato if (mPos < mBuf.length) { 650040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato if (mBuf[mPos] == '<') { 651040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato genericDepth++; 652040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato mPos++; 653040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } else if (mBuf[mPos] == '>') { 654040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato genericDepth--; 655040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato mPos++; 656040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } else if (genericDepth != 0) { 657040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato mPos++; 658040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 659040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 660040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } while (mPos < mBuf.length 661040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato && ((!isspace(mBuf[mPos]) && !issep(mBuf[mPos], parenIsSep)) || genericDepth != 0)); 662040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato if (mPos >= mBuf.length) { 663040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato throw new ApiParseException("Unexpected end of file for \" starting at " + line, mLine); 664040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 665040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato return new String(mBuf, start, mPos-start); 666040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 667040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 668040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 669040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato 670040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato static boolean isspace(char c) { 671040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato return c == ' ' || c == '\t' || c == '\n' || c == '\r'; 672040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 673040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato 674040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato static boolean isnewline(char c) { 675040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato return c == '\n' || c == '\r'; 676040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 677040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato 678040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato static boolean issep(char c, boolean parenIsSep) { 679040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato if (parenIsSep) { 680040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato if (c == '(' || c == ')') { 681040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato return true; 682040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 683040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 684040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato return c == '{' || c == '}' || c == ',' || c == ';' || c == '<' || c == '>'; 685040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 686040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato 687040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato static boolean isident(char c) { 688040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato if (c == '"' || issep(c, true)) { 689040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato return false; 690040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 691040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato return true; 692040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 693040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato} 694040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato 695