public String resolveFile(Element e) { String file = null; while (e != null && (file = e.getElementFile()) == null) { e = e.getParentElement(); } return file; }
public Object findParentOfTypes(Class<?>... types) { Element e = this; for (; ; ) { e = e.getParentElement(); if (e == null) return null; for (Class<?> type : types) if (type.isAssignableFrom(e.getClass())) return type.cast(e); } }
String getFileCommentContent(Element e) { if (e == null || result.config.limitComments) return null; String f = Element.getFileOfAscendency(e); if (f == null && e != null && e.getElementLine() >= 0) return "<i>native declaration : line " + e.getElementLine() + "</i>"; return f == null ? null : getFileCommentContent(new File(f), e); }
public static String getFileOfAscendency(Element decl) { Element e = decl; String file = null; Set<Integer> visitedIds = new TreeSet<Integer>(); while (e != null && (file = e.getElementFile()) == null && visitedIds.add(e.getId())) { e = e.getParentElement(); } return file; }
@SuppressWarnings("unchecked") public boolean insertChild(Element existingChild, Element childToInsert, boolean before) { if (elementListGettersAndSetters == null) { elementListGettersAndSetters = new ArrayList<GetterAndSetterInfo>(); GettersAndSettersHelper gettersAndSetters = getGettersAndSetters(); for (Map.Entry<String, GetterAndSetterInfo> e : gettersAndSetters.gettersAndSetters.entrySet()) { GetterAndSetterInfo p = e.getValue(); if (!p.isFull()) continue; Type returnType = p.getter.getGenericReturnType(); if (returnType instanceof ParameterizedType) { ParameterizedType paramReturnType = (ParameterizedType) returnType; Type rawType = paramReturnType.getRawType(); Type[] typeArguments = paramReturnType.getActualTypeArguments(); Type typeArgument = typeArguments.length == 1 ? typeArguments[0] : null; if (typeArgument != null && typeArgument instanceof Class && rawType instanceof Class) { Class<?> typeClass = (Class<?>) typeArgument; Class<?> rawClass = (Class<?>) rawType; if (Element.class.isAssignableFrom(typeClass) && List.class.isAssignableFrom(rawClass)) { p.elementType = (Class<Element>) typeClass; elementListGettersAndSetters.add( p); // new ListGetterAndSetterInfo(e.getKey(), (Class<Element>)typeClass, // p.getter, p.setter)); } } } } } Class<?> t = existingChild.getClass(), t2 = childToInsert.getClass(); for (GetterAndSetterInfo info : elementListGettersAndSetters) { if (!info.elementType.isAssignableFrom(t) || !info.elementType.isAssignableFrom(t2)) continue; try { List<Element> list = (List<Element>) info.getter.invoke(this); if (list instanceof SemiUnmodifiableList) list = ((SemiUnmodifiableList<Element>) list).getList(); int i = indexOfInstance(existingChild, list); if (i < 0) continue; list.add(before ? i : i + 1, childToInsert); childToInsert.setParentElement(this); return true; } catch (Exception e) { throw new RuntimeException("Implementation bug in " + Element.class + ".insertChild !", e); } } return false; }
@Override public boolean replaceChild(Element child, Element by) { if (child == getTarget()) { setTarget((Expression) by); return true; } if (child == getFunction()) { setFunction((Expression) by); return true; } // return replaceChild(arguments, Expression.class, this, child, by); int i = indexOf(child, arguments); if (i >= 0) { Expression old; if (by == null) old = arguments.remove(i).getValue(); else old = arguments.get(i).setValue((Expression) by); if (old != by) { if (old != null) old.setParentElement(null); if (by != null) by.setParentElement(this); } return true; } return super.replaceChild(child, by); }
protected void outputNSString( String name, String value, DeclarationsHolder out, Signatures signatures, Element... elementsToTakeCommentsFrom) { if (!signatures.addVariable(name)) return; TypeRef tr = typeRef(String.class); VariablesDeclaration vd = new VariablesDeclaration(tr, new DirectDeclarator(name, expr(value))); if (!result.config.noComments) for (Element e : elementsToTakeCommentsFrom) { vd.addToCommentBefore(e.getCommentBefore()); vd.addToCommentBefore(e.getCommentAfter()); } vd.addModifiers(ModifierType.Public); out.addDeclaration(vd); }
public void computeVariablesDependencies(Element e, final Set<Identifier> names) { e.accept( new Scanner() { @Override public void visitVariableRef(VariableRef variableRef) { names.add(variableRef.getName()); } }); }
protected Scanner visit(Element e) { if (e != null) { try { e.accept(this); } catch (StackOverflowError err) { throw new RuntimeException("Overflow while visiting :\n" + e, err); } } return this; }
public boolean accept(Element value) { String s = Element.getFileOfAscendency(value); if (s == null) return false; File f = new File(s); try { f = f.getCanonicalFile(); } catch (IOException e) { e.printStackTrace(); } return libraryByFile.containsKey(f); }
public EmptyDeclaration skipDeclaration(Element e, String... preMessages) { if (result.config.limitComments) return null; List<String> mess = new ArrayList<String>(); if (preMessages != null) mess.addAll(Arrays.asList(preMessages)); mess.addAll( Arrays.asList( "SKIPPED:", new Printer(null).formatComments(e, true, true, false).toString(), getFileCommentContent(e), e.toString().replace("*/", "* /"))); return new EmptyDeclaration(mess.toArray(new String[0])); }
String getLibrary(Element decl) { String file = resolveFile(decl); String library = config.getLibrary(file); if (library == null) { SourceFile f = decl.findParentOfType(SourceFile.class); if (f != null) { // library = config.getLibrary(f.getElementFile()); // if (library == null) { library = guessFramework(file); if (library == null) library = f.getLibrary(); // } } } return library; }
public Struct convertCallback( FunctionSignature functionSignature, Signatures signatures, Identifier callerLibraryName) { Identifier name = result.typeConverter.inferCallBackName(functionSignature, true, false, callerLibraryName); if (name == null) return null; name = result.typeConverter.getValidJavaArgumentName(name); Function function = functionSignature.getFunction(); int i = 1; Identifier chosenName = name; while (!(signatures.addClass(chosenName))) { chosenName = ident(name.toString() + (++i)); } Element parent = functionSignature.getParentElement(); Element comel = parent != null && parent instanceof TypeDef ? parent : functionSignature; Struct callbackStruct = new Struct(); configureCallbackStruct(callbackStruct); // callbackStruct.setParents(Arrays.asList(getCallbackType(functionSignature, chosenName))); callbackStruct.setTag(ident(chosenName)); if (!result.config.noComments) callbackStruct.addToCommentBefore( comel.getCommentBefore(), comel.getCommentAfter(), getFileCommentContent(comel)); convertFunction(function, new Signatures(), true, callbackStruct, callerLibraryName, -1); for (Declaration d : callbackStruct.getDeclarations()) { if (d instanceof Function) { callbackStruct.addAnnotations(callbackStruct.getAnnotations()); callbackStruct.setAnnotations(null); break; } } return callbackStruct; }
String getFileCommentContent(File file, Element e) { if (file != null) { String path = result.config.relativizeFileForSourceComments(file.getAbsolutePath()); String inCategoryStr = ""; if (e instanceof Function) { Function fc = (Function) e; Struct parent; if (fc.getType() == Type.ObjCMethod && ((parent = as(fc.getParentElement(), Struct.class)) != null) && (parent.getCategoryName() != null)) { inCategoryStr = "from " + parent.getCategoryName() + " "; } } return "<i>" + inCategoryStr + "native declaration : " + path + (e == null || e.getElementLine() < 0 ? "" : ":" + e.getElementLine()) + "</i>"; } else if (e != null && e.getElementLine() >= 0) { return "<i>native declaration : <input>:" + e.getElementLine() + "</i>"; } return null; }
protected void collectParamComments(Function f) { for (Arg arg : f.getArgs()) { arg.moveAllCommentsBefore(); TypeRef argType = arg.getValueType(); if (argType != null) { if (!result.config.noComments) { argType.moveAllCommentsBefore(); arg.addToCommentBefore(argType.getCommentBefore()); } argType.stripDetails(); } if (arg.getCommentBefore() != null) { if (!result.config.noComments) f.addToCommentBefore( "@param " + arg.getName() + " " + Element.cleanComment(arg.getCommentBefore())); arg.stripDetails(); } } }
@SuppressWarnings("unchecked") public static <T extends Element> boolean replaceChild( List<T> list, Class<T> type, Element parent, Element child, Element by) { int i = indexOfInstance(child, list); if (i >= 0) { T old; if (by == null) old = list.remove(i); else old = list.set(i, type == null ? (T) by : type.cast(by)); if (old != by) { if (old != null) old.setParentElement(null); if (by != null) by.setParentElement(parent); } return true; } return false; }
protected Scanner visit(List<? extends Element> list) { if (list != null) for (Element e : copy(list)) if (e != null) e.accept(this); return this; }
public Element importDetails(Element from, boolean move) { if (from == null) return this; if (!from.getNameSpace().isEmpty()) setNameSpace(from.getNameSpace()); if (from.getElementFile() != null) setElementFile(from.getElementFile()); if (from.getElementLine() >= 0) setElementLine(from.getElementLine()); if (from.getCommentBefore() != null) addToCommentBefore(from.getCommentBefore()); if (from.getCommentAfter() != null) setCommentAfter(from.getCommentAfter()); if (move) from.stripDetails(); return this; }
public Element getPreviousSibling() { Element pe = getParentElement(); if (pe != null) return pe.getPreviousChild(this); return null; }
public boolean insertSibling(Element siblingToInsert, boolean before) { Element parent = getParentElement(); if (parent == null) return false; return parent.insertChild(this, siblingToInsert, before); }
public boolean replaceBy(Element element) { Element pe = getParentElement(); if (pe != null) return pe.replaceChild(this, element); return false; }
public boolean replaceByAndVisit(Element element, Visitor visitor) { if (!replaceBy(element)) return false; element.accept(visitor); return true; }
public void convertConstants( String library, List<Define> defines, Element sourcesRoot, final Signatures signatures, final DeclarationsHolder out, final Identifier libraryClassName) { // final List<Define> defines = new ArrayList<Define>(); final Map<String, String> constants = Result.getMap(result.stringConstants, library); // sourcesRoot.accept( new Scanner() { // @Override // public void visitDefine(Define define) { // super.visitDefine(define); // if (elementsFilter.accept(define)) // defines.add(define); // } @Override public void visitVariablesDeclaration(VariablesDeclaration v) { super.visitVariablesDeclaration(v); // if (!elementsFilter.accept(v)) // return; if (v.findParentOfType(Struct.class) != null) return; if (v.getValueType() instanceof FunctionSignature) return; for (Declarator decl : v.getDeclarators()) { if (!(decl instanceof DirectDeclarator)) continue; // TODO provide a mapping of exported values TypeRef mutatedType = (TypeRef) decl.mutateTypeKeepingParent(v.getValueType()); if (mutatedType == null || !mutatedType.getModifiers().contains(ModifierType.Const) || mutatedType.getModifiers().contains(ModifierType.Extern) || decl.getDefaultValue() == null) continue; // TypeRef type = v.getValueType(); String name = decl.resolveName(); JavaPrim prim = result.typeConverter.getPrimitive(mutatedType, libraryClassName); if (prim == null) { if (mutatedType.toString().contains("NSString")) { String value = constants.get(name); if (value != null) outputNSString(name, value, out, signatures, v, decl); } continue; } try { // DirectDeclarator dd = (DirectDeclarator)decl; Pair<Expression, TypeRef> val = result.typeConverter.convertExpressionToJava( decl.getDefaultValue(), libraryClassName, true); if (!signatures.addVariable(name)) continue; // TODO TypeRef tr = prim == JavaPrim.NativeLong || prim == JavaPrim.NativeSize ? typeRef("long") : primRef(prim) // result.typeConverter.convertTypeToJNA(mutatedType, // TypeConversion.TypeConversionMode.FieldType, libraryClassName) ; VariablesDeclaration vd = new VariablesDeclaration(tr, new DirectDeclarator(name, val.getFirst())); if (!result.config.noComments) { vd.setCommentBefore(v.getCommentBefore()); vd.addToCommentBefore(decl.getCommentBefore()); vd.addToCommentBefore(decl.getCommentAfter()); vd.addToCommentBefore(v.getCommentAfter()); } // if (result.config.runtime == // JNAeratorConfig.Runtime.BridJ) vd.addModifiers(ModifierType.Public, ModifierType.Static, ModifierType.Final); out.addDeclaration(vd); } catch (UnsupportedConversionException e) { out.addDeclaration(skipDeclaration(v, e.toString())); } } } }); if (defines != null) { for (Define define : reorderDefines(defines)) { if (define.getValue() == null) continue; try { // System.out.println("Define " + define.getName() + " = " + define.getValue()); out.addDeclaration( outputConstant( define.getName(), define.getValue(), signatures, define.getValue(), "define", libraryClassName, true, false, false)); } catch (UnsupportedConversionException ex) { out.addDeclaration(skipDeclaration(define, ex.toString())); } } } for (Map.Entry<String, String> e : constants.entrySet()) { outputNSString(e.getKey(), e.getValue(), out, signatures); } }
public EnumSet<Language> resolvePossibleLanguages() { if (possibleLanguages != null) return possibleLanguages; Element parent = getParentElement(); if (parent != null) return parent.resolvePossibleLanguages(); return null; }