public static boolean isFloatingPoint(ITypeBinding type) { if (!type.isPrimitive()) { return false; } char binaryName = type.getBinaryName().charAt(0); return binaryName == 'F' || binaryName == 'D'; }
public TypeName(ITypeBinding binding, boolean varargs) { this.varargs = varargs; ITypeBinding inner = binding; if (varargs) { dimensions = 1; } else { int dims = 0; while (inner.isArray()) { inner = inner.getComponentType(); dims += 1; } dimensions = dims; } if (inner.isParameterizedType()) { inner = inner.getErasure(); } ITypeBinding parent = inner; int nesting = 0; while (parent.isNested()) { nesting++; parent = parent.getDeclaringClass(); } nestingLevel = nesting; primitive = inner.isPrimitive(); baseQualifiedName = adaptQualifiedName(inner.getQualifiedName()); baseBinaryName = inner.getBinaryName(); shortName = buildShortName(); qualifiedName = buildQualifiedName(); binaryName = buildBinaryName(); }
private static void appendParameterSignature(ITypeBinding parameter, StringBuilder sb) { if (!parameter.isPrimitive() && !parameter.isArray()) { sb.append('L'); } sb.append(parameter.getBinaryName().replace('.', '/')); if (!parameter.isPrimitive() && !parameter.isArray()) { sb.append(';'); } }
public static String bestNameableType(ITypeBinding type) { { String result_ = fqTypeName(type); if (result_ != null) return removeTypeParam(result_); } if (type.isCapture() || type.isWildcardType() || type.isTypeVariable()) { return bestNameableType(type.getErasure()); } // Find an interface or superclass being implemented. // For anonymous class, there can only be one. BUT for // local class, things are super f-ed up... if (type.isAnonymous()) { // any interfaces? if (type.getInterfaces().length > 0) { String result = fqTypeName(type.getInterfaces()[0]); assert (result != null); return removeTypeParam(result); } else { String result = fqTypeName(type.getSuperclass()); assert (result != null); return removeTypeParam(result); } } if (type.isLocal()) { // We can only make sense of this is there is just one // superclass+inferface. if (type.getInterfaces().length == 0) { // EASY! String result = fqTypeName(type.getSuperclass()); assert (result != null); return removeTypeParam(result); } else { // Well, maybe superclass is object? if (type.getSuperclass().getQualifiedName().equals(Object.class.getName())) { String result = fqTypeName(type.getInterfaces()[0]); assert (result != null); return removeTypeParam(result); } else { // Otherwise, return the superclass, I guess, but print a warning: String result = fqTypeName(type.getSuperclass()); assert (result != null); System.err.println("Local class has multiple supertypes..." + type.getBinaryName()); return removeTypeParam(result); } } } return Utilities.impossible(); }
/** * 中断接受节点 * * @param node : 函数调用 */ public void interruptAcceptNodeHandle(MethodInvocation node) { int lineNumber = compilationUnit.getLineNumber(node.getStartPosition()); Node interruptedNode = new Node(filePath, lineNumber); String threadKey; Expression expression = node.getExpression(); ITypeBinding iTypeBinding = castHelper.getResolveTypeBinding(expression); if (expression == null || iTypeBinding == null) { System.out.println(filePath); System.out.println(compilationUnit.getLineNumber(node.getStartPosition())); System.out.println("interrupt iTypeBinding error!"); return; } // 普通变量 if (expression instanceof SimpleName && ((SimpleName) expression).resolveBinding() != null) { SimpleName simpleName = (SimpleName) expression; if (castHelper.getDecNode(simpleName) == null) { return; } int decLineNumber = compilationUnit.getLineNumber(castHelper.getDecNode(simpleName).getStartPosition()); String varKey = filePath + "_" + decLineNumber + "_" + iTypeBinding.getName() + "_" + simpleName.getIdentifier(); System.out.println(varKey); if (threadVarHashMap.containsKey(varKey)) { threadKey = threadVarHashMap.get(varKey).getThreadInfoKey(); if (threadInfo.get(threadKey).getInterruptNodes() != null) { threadInfo.get(threadKey).getInterruptNodes().add(interruptedNode); } } else { System.out.println("ERROR: didn't contains the varKey"); } } // 其它调用 else if (((SimpleName) expression).resolveBinding() != null) { threadKey = iTypeBinding.getBinaryName(); if (threadInfo.get(threadKey).getInterruptNodes() != null) { threadInfo.get(threadKey).getInterruptNodes().add(interruptedNode); } } }
@Override public void endVisit(CastExpression node) { ITypeBinding type = node.getType().getTypeBinding(); Expression expr = node.getExpression(); ITypeBinding exprType = expr.getTypeBinding(); // TODO(kirbs): Implement correct conversion of Java 8 intersection types to Objective-C. if (node.getType().isIntersectionType() && !Options.isJava8Translator()) { // Technically we can't currently get here, but as we add support and change flags in the // future this should alert us to implement intersection types. assert false : "not implemented yet"; } if (BindingUtil.isFloatingPoint(exprType)) { assert type.isPrimitive(); // Java wouldn't allow a cast from primitive to non-primitive. switch (type.getBinaryName().charAt(0)) { case 'J': node.replaceWith(rewriteFloatToIntegralCast(type, expr, "JreFpToLong", type)); return; case 'C': node.replaceWith(rewriteFloatToIntegralCast(type, expr, "JreFpToChar", type)); return; case 'B': case 'S': case 'I': node.replaceWith( rewriteFloatToIntegralCast(type, expr, "JreFpToInt", typeEnv.resolveJavaType("int"))); return; } // else fall-through. } // Lean on Java's type-checking. if (!type.isPrimitive() && exprType.isAssignmentCompatible(type.getErasure())) { node.replaceWith(TreeUtil.remove(expr)); return; } FunctionInvocation castCheck = createCastCheck(type, expr); if (castCheck != null) { node.setExpression(castCheck); } }
/** * 中断通知节点 * * @param node :函数调用 * @param threadInterruptNode :中断节点类 */ public void interruptNotifyNodeHandle( MethodInvocation node, ThreadInterruptNode threadInterruptNode) { String threadKey; Expression expression = node.getExpression(); ITypeBinding iTypeBinding = castHelper.getResolveTypeBinding(expression); if (expression == null || iTypeBinding == null) { System.out.println(filePath); System.out.println(compilationUnit.getLineNumber(node.getStartPosition())); System.out.println("interrupt iTypeBinding error!"); return; } // 普通变量,从变量集中获取线程key if (expression instanceof SimpleName && ((SimpleName) expression).resolveBinding() != null) { SimpleName simpleName = (SimpleName) expression; int lineNumber = compilationUnit.getLineNumber(castHelper.getDecNode(simpleName).getStartPosition()); String varKey = filePath + "_" + lineNumber + "_" + iTypeBinding.getName() + "_" + simpleName.getIdentifier(); System.out.println(varKey); if (threadVarHashMap.containsKey(varKey)) { threadKey = threadVarHashMap.get(varKey).getThreadInfoKey(); threadInterruptNode.getThreadKeyList().add(threadKey); // 添加至中断通知节点集合 threadInterruptNodes.add(threadInterruptNode); } else { System.out.println("ERROR: didn't contains the varKey"); } } // 其它调用(函数返回值等):直接从返回值类型推断具体线程key else { threadKey = iTypeBinding.getBinaryName(); threadInterruptNode.getThreadKeyList().add(threadKey); } }
public static boolean isBoolean(ITypeBinding type) { return type.isPrimitive() && type.getBinaryName().charAt(0) == 'Z'; }
@Override public boolean visit(MethodInvocation node) { String methodKey = castHelper.methodKey(node); String methodName = node.getName().toString(); int lineNumber = compilationUnit.getLineNumber(node.getStartPosition()); // 函数调用在线程调用到的函数中(单个函数可能牵扯到多个线程) if (threadMethodMapTable.containsKey(methodKey) && node.resolveMethodBinding() != null) { IMethodBinding iMethodBinding = node.resolveMethodBinding(); // 1.中断判断函数(中断接受节点) if ((methodName.equals("interrupted") || methodName.equals("isInterrupted"))) { if (iMethodBinding.getDeclaringClass() != null && iMethodBinding.getDeclaringClass().getBinaryName().equals("java.lang.Thread")) { System.out.println(node); System.out.println("interrupted judge"); HashSet<String> threads = threadMethodMapTable.get(methodKey); // (1)添加到每个线程的中断接受节点集合 for (String thread : threads) { ThreadInformation threadInformation = threadInfo.get(thread); Node interruptedNode = new Node(filePath, lineNumber); threadInformation.getInterruptNodes().add(interruptedNode); } // (2)变量自身判断(根据自己所绑定的线程类型而添加中断接受节点) interruptAcceptNodeHandle(node); } } // 2.引发中断的函数调用(中断通知节点) else if (methodName.equals("interrupt")) { ThreadInterruptNode threadInterruptNode = new ThreadInterruptNode(filePath, lineNumber); // (1)自中断 if (node.getExpression() instanceof MethodInvocation && ((MethodInvocation) node.getExpression()) .getName() .getIdentifier() .equals("currentThread")) { // 对有可能调用该自中断的线程添加到中断通知节点中 HashSet<String> threads = threadMethodMapTable.get(methodKey); for (String thread : threads) { threadInterruptNode.getThreadKeyList().add(thread); } threadInterruptNodes.add(threadInterruptNode); } // (2)调用中断,通过变量来定位threadKey else if (iMethodBinding.getDeclaringClass() != null && iMethodBinding.getDeclaringClass().getBinaryName().equals("java.lang.Thread")) { interruptNotifyNodeHandle(node, threadInterruptNode); } } // 3.会抛出中断异常的函数(中断接受节点) else { ITypeBinding[] typeBindings = node.resolveMethodBinding().getExceptionTypes(); for (ITypeBinding iTypeBinding : typeBindings) { if (iTypeBinding.getBinaryName().equals("java.lang.InterruptedException")) { System.out.println(node); System.out.println("interrupted exception"); HashSet<String> threads = threadMethodMapTable.get(methodKey); // (1)添加到每个线程的中断接受节点集合 for (String thread : threads) { ThreadInformation threadInformation = threadInfo.get(thread); Node interruptedNode = new Node(filePath, lineNumber); threadInformation.getInterruptNodes().add(interruptedNode); } // (2)变量自身判断(根据自己所绑定的线程类型而添加中断接受节点) interruptAcceptNodeHandle(node); } } } } return super.visit(node); }
/** * Create an instance based on a JDT type. * * <p>The location, context and warnings parameters are used for raising warnings when the type * bindings cannot be resolved. */ public TypeName( Type t, boolean varargs, String location, String context, Set<DocumentationWarning> warnings) { this.varargs = varargs; // Try to resolve the binding. ITypeBinding binding = t.resolveBinding(); // If binding was resolved, then use it to extract the names. if (binding != null) { ITypeBinding inner = binding; if (varargs) { dimensions = 1; } else { int dims = 0; while (inner.isArray()) { inner = inner.getComponentType(); dims += 1; } dimensions = dims; } if (inner.isParameterizedType()) { inner = inner.getErasure(); } ITypeBinding parent = inner; int nesting = 0; while (parent.isNested()) { nesting++; parent = parent.getDeclaringClass(); } nestingLevel = nesting; primitive = inner.isPrimitive(); baseQualifiedName = adaptQualifiedName(inner.getQualifiedName()); baseBinaryName = inner.getBinaryName(); } // If the binding was not resolved, then use the type name anyway. // This may not be accurate, but is better than nothing. // Also raise a warning in this case. else { String rawName = t.toString(); int idx = rawName.indexOf("["); if (idx >= 0) { baseQualifiedName = rawName.substring(0, idx); String dimPart = rawName.substring(idx); dimensions = dimPart.length() / 2; } else { baseQualifiedName = rawName; dimensions = 0; } nestingLevel = 0; baseBinaryName = baseQualifiedName; primitive = t.isPrimitiveType(); DocumentationWarning dw = new DocumentationWarning( WarningType.UnresolvedBinding, location, "Cannot resolve binding for " + context + " type: '" + baseQualifiedName + "'."); warnings.add(dw); } shortName = buildShortName(); qualifiedName = buildQualifiedName(); binaryName = buildBinaryName(); }