public URI getFullURI(IVariableBinding binding) { SegmentSequence.Builder builder = SegmentSequence.newBuilder(""); URI uri = getFullURI(binding.getDeclaringClass(), builder); builder.append("."); builder.append(binding.getName()); return uri.appendFragment(builder.toString()); }
private static boolean canAddFinal(IBinding binding, ASTNode declNode) { if (!(binding instanceof IVariableBinding)) return false; IVariableBinding varbinding = (IVariableBinding) binding; int modifiers = varbinding.getModifiers(); if (Modifier.isFinal(modifiers) || Modifier.isVolatile(modifiers) || Modifier.isTransient(modifiers)) return false; ASTNode parent = ASTNodes.getParent(declNode, VariableDeclarationExpression.class); if (parent != null && ((VariableDeclarationExpression) parent).fragments().size() > 1) return false; if (varbinding.isField() && !Modifier.isPrivate(modifiers)) return false; if (varbinding.isParameter()) { ASTNode varDecl = declNode.getParent(); if (varDecl instanceof MethodDeclaration) { MethodDeclaration declaration = (MethodDeclaration) varDecl; if (declaration.getBody() == null) return false; } } return true; }
@Override public void endVisit(SuperMethodInvocation node) { Name qualifier = node.getQualifier(); if (qualifier == null) { return; } IMethodBinding method = node.getMethodBinding(); ITypeBinding exprType = node.getTypeBinding(); IVariableBinding var = TreeUtil.getVariableBinding(qualifier); assert var != null : "Expected qualifier to be a variable"; ITypeBinding qualifierType = var.getType(); SuperMethodBindingPair superMethod = new SuperMethodBindingPair(qualifierType, method); superMethods.add(superMethod); FunctionBinding binding = new FunctionBinding(getSuperFunctionName(superMethod), exprType, qualifierType); binding.addParameters(qualifierType, typeEnv.getIdType()); binding.addParameters(method.getParameterTypes()); FunctionInvocation invocation = new FunctionInvocation(binding, exprType); List<Expression> args = invocation.getArguments(); args.add(TreeUtil.remove(qualifier)); String selectorExpr = UnicodeUtils.format("@selector(%s)", nameTable.getMethodSelector(method)); args.add(new NativeExpression(selectorExpr, typeEnv.getIdType())); TreeUtil.copyList(node.getArguments(), args); node.replaceWith(invocation); }
/** @see {@link #fullyQualifiedName(IMethodBinding)}. */ public static Option<String> fullyQualifiedName(IVariableBinding field) { ITypeBinding declaring_class = field.getDeclaringClass(); String fq_type_name = fqTypeName(declaring_class); return fq_type_name == null ? Option.<String>none() : Option.some(removeTypeParam(fq_type_name) + "." + field.getName()); }
/** {@inheritDoc} */ public boolean visit(SingleVariableDeclaration node) { SimpleName name = node.getName(); IBinding binding = name.resolveBinding(); if (!(binding instanceof IVariableBinding)) return false; IVariableBinding varBinding = (IVariableBinding) binding; if (fWrittenVariables.containsKey(varBinding)) return false; if (fAddFinalParameters && fAddFinalLocals) { ModifierChangeOperation op = createAddFinalOperation(name, node); if (op == null) return false; fResult.add(op); return false; } else if (fAddFinalParameters) { if (!varBinding.isParameter()) return false; ModifierChangeOperation op = createAddFinalOperation(name, node); if (op == null) return false; fResult.add(op); return false; } else if (fAddFinalLocals) { if (varBinding.isParameter()) return false; ModifierChangeOperation op = createAddFinalOperation(name, node); if (op == null) return false; fResult.add(op); return false; } return false; }
public static boolean isPrimitiveConstant(IVariableBinding binding) { return isFinal(binding) && binding.getType().isPrimitive() && binding.getConstantValue() != null // Exclude local variables declared final. && binding.getDeclaringClass() != null; }
private ITypeBinding[] computeTypeVariables(ITypeBinding[] bindings) { Selection selection = getSelection(); Set<ITypeBinding> result = new HashSet<>(); // first remove all type variables that come from outside of the method // or are covered by the selection CompilationUnit compilationUnit = (CompilationUnit) fEnclosingBodyDeclaration.getRoot(); for (int i = 0; i < bindings.length; i++) { ASTNode decl = compilationUnit.findDeclaringNode(bindings[i]); if (decl == null || (!selection.covers(decl) && decl.getParent() instanceof MethodDeclaration)) result.add(bindings[i]); } // all all type variables which are needed since a local variable uses it for (int i = 0; i < fArguments.length; i++) { IVariableBinding arg = fArguments[i]; ITypeBinding type = arg.getType(); if (type != null && type.isTypeVariable()) { ASTNode decl = compilationUnit.findDeclaringNode(type); if (decl == null || (!selection.covers(decl) && decl.getParent() instanceof MethodDeclaration)) result.add(type); } } return result.toArray(new ITypeBinding[result.size()]); }
private void printAnnotationValue(AST ast, Object value) { if (value == null) { print("nil"); } else if (value instanceof IVariableBinding) { IVariableBinding var = (IVariableBinding) value; ITypeBinding declaringClass = var.getDeclaringClass(); printf("[%s %s]", NameTable.getFullName(declaringClass), var.getName()); } else if (value instanceof ITypeBinding) { ITypeBinding type = (ITypeBinding) value; printf("[[%s class] getClass]", NameTable.getFullName(type)); } else if (value instanceof String) { StringLiteral node = ast.newStringLiteral(); node.setLiteralValue((String) value); print(StatementGenerator.generateStringLiteral(node)); } else if (value instanceof Number || value instanceof Character || value instanceof Boolean) { print(value.toString()); } else if (value.getClass().isArray()) { print("[IOSObjectArray arrayWithObjects:(id[]) { "); Object[] array = (Object[]) value; for (int i = 0; i < array.length; i++) { if (i > 0) { print(", "); } printAnnotationValue(ast, array[i]); } printf(" } count:%d type:[[NSObject class] getClass]]", array.length); } else { assert false : "unknown annotation value type"; } }
/* * Evaluates possible return expressions. The favourite expression is returned. */ private Expression evaluateReturnExpressions( AST ast, ITypeBinding returnBinding, int returnOffset) { CompilationUnit root = (CompilationUnit) fMethodDecl.getRoot(); Expression result = null; if (returnBinding != null) { ScopeAnalyzer analyzer = new ScopeAnalyzer(root); IBinding[] bindings = analyzer.getDeclarationsInScope( returnOffset, ScopeAnalyzer.VARIABLES | ScopeAnalyzer.CHECK_VISIBILITY); for (int i = 0; i < bindings.length; i++) { IVariableBinding curr = (IVariableBinding) bindings[i]; ITypeBinding type = curr.getType(); if (type != null && type.isAssignmentCompatible(returnBinding) && testModifier(curr)) { if (result == null) { result = ast.newSimpleName(curr.getName()); } addLinkedPositionProposal(RETURN_EXPRESSION_KEY, curr.getName(), null); } } } Expression defaultExpression = ASTNodeFactory.newDefaultExpression( ast, fMethodDecl.getReturnType2(), fMethodDecl.getExtraDimensions()); addLinkedPositionProposal(RETURN_EXPRESSION_KEY, ASTNodes.asString(defaultExpression), null); if (result == null) { return defaultExpression; } return result; }
@Override public boolean visit(SimpleName node) { VariableDeclaration decl = getVariableDeclaration(node); if (decl == null) return super.visit(node); IVariableBinding binding = decl.resolveBinding(); if (binding == null) return super.visit(node); boolean keysEqual = fKey.equals(binding.getKey()); boolean rangeInSet = fRanges.contains(new Region(node.getStartPosition(), node.getLength())); if (keysEqual && !rangeInSet) fProblemNodes.add(node); if (!keysEqual && rangeInSet) fProblemNodes.add(node); /* * if (!keyEquals && !rangeInSet) * ok, different local variable. * * if (keyEquals && rangeInSet) * ok, renamed local variable & has been renamed. */ return super.visit(node); }
public static String getSetterName( IVariableBinding variableType, IJavaProject project, String[] excludedNames, boolean isBoolean) { return getSetterName( project, variableType.getName(), variableType.getModifiers(), isBoolean, excludedNames); }
public static String getGetterName( IVariableBinding variableType, IJavaProject project, String[] excludedNames, boolean isBoolean) { boolean useIs = StubUtility.useIsForBooleanGetters(project) && isBoolean; return getGetterName( project, variableType.getName(), variableType.getModifiers(), useIs, excludedNames); }
private boolean hasAddedStaticImport(SimpleName name) { IBinding binding = name.resolveBinding(); if (binding instanceof IVariableBinding) { IVariableBinding variable = (IVariableBinding) binding; return hasAddedStaticImport( variable.getDeclaringClass().getQualifiedName(), variable.getName(), true); } else if (binding instanceof IMethodBinding) { IMethodBinding method = (IMethodBinding) binding; return hasAddedStaticImport( method.getDeclaringClass().getQualifiedName(), method.getName(), false); } return false; }
@Override public boolean visit(SimpleName node) { List<IVariableBinding> path = OuterReferenceResolver.getPath(node); if (path != null) { if (path.size() == 1 && path.get(0).getConstantValue() != null) { IVariableBinding var = path.get(0); node.replaceWith(TreeUtil.newLiteral(var.getConstantValue())); } else { node.replaceWith(Name.newName(fixPath(path))); } } return true; }
/* * Must be one of: * <ul> * <li>[indexBinding]++</li> * <li>++[indexBinding]</li> * <li>[indexBinding]+= 1</li> * <li>[indexBinding]= [indexBinding] + 1</li> * <li>[indexBinding]= 1 + [indexBinding]</li> * <ul> */ private boolean validateUpdaters(ForStatement statement) { List<Expression> updaters = statement.updaters(); if (updaters.size() != 1) return false; Expression updater = updaters.get(0); if (updater instanceof PostfixExpression) { PostfixExpression postfix = (PostfixExpression) updater; if (!PostfixExpression.Operator.INCREMENT.equals(postfix.getOperator())) return false; IBinding binding = getBinding(postfix.getOperand()); if (!fIndexBinding.equals(binding)) return false; return true; } else if (updater instanceof PrefixExpression) { PrefixExpression prefix = (PrefixExpression) updater; if (!PrefixExpression.Operator.INCREMENT.equals(prefix.getOperator())) return false; IBinding binding = getBinding(prefix.getOperand()); if (!fIndexBinding.equals(binding)) return false; return true; } else if (updater instanceof Assignment) { Assignment assignment = (Assignment) updater; Expression left = assignment.getLeftHandSide(); IBinding binding = getBinding(left); if (!fIndexBinding.equals(binding)) return false; if (Assignment.Operator.PLUS_ASSIGN.equals(assignment.getOperator())) { return isOneLiteral(assignment.getRightHandSide()); } else if (Assignment.Operator.ASSIGN.equals(assignment.getOperator())) { Expression right = assignment.getRightHandSide(); if (!(right instanceof InfixExpression)) return false; InfixExpression infixExpression = (InfixExpression) right; Expression leftOperand = infixExpression.getLeftOperand(); IBinding leftBinding = getBinding(leftOperand); Expression rightOperand = infixExpression.getRightOperand(); IBinding rightBinding = getBinding(rightOperand); if (fIndexBinding.equals(leftBinding)) { return isOneLiteral(rightOperand); } else if (fIndexBinding.equals(rightBinding)) { return isOneLiteral(leftOperand); } } } return false; }
@Override public boolean visit(MethodDeclaration node) { IMethodBinding binding = node.getMethodBinding(); if (binding.isConstructor()) { List<SingleVariableDeclaration> params = node.getParameters(); if (params.size() > 0) { IVariableBinding firstParam = params.get(0).getVariableBinding(); if (firstParam.getName().equals("outer$")) { outerParam = firstParam; } } } return true; }
private ITypeBinding getDeclaredType(Expression expr) { IVariableBinding var = TreeUtil.getVariableBinding(expr); if (var != null) { return var.getVariableDeclaration().getType(); } switch (expr.getKind()) { case CLASS_INSTANCE_CREATION: return typeEnv.resolveIOSType("id"); case FUNCTION_INVOCATION: { ITypeBinding returnType = ((FunctionInvocation) expr).getFunctionBinding().getReturnType(); if (returnType.isTypeVariable()) { return typeEnv.resolveIOSType("id"); } return returnType; } case METHOD_INVOCATION: { MethodInvocation invocation = (MethodInvocation) expr; IMethodBinding method = invocation.getMethodBinding(); // Object receiving the message, or null if it's a method in this class. Expression receiver = invocation.getExpression(); ITypeBinding receiverType = receiver != null ? receiver.getTypeBinding() : method.getDeclaringClass(); return getDeclaredReturnType(method, receiverType); } case PARENTHESIZED_EXPRESSION: return getDeclaredType(((ParenthesizedExpression) expr).getExpression()); case SUPER_METHOD_INVOCATION: { SuperMethodInvocation invocation = (SuperMethodInvocation) expr; IMethodBinding method = invocation.getMethodBinding(); if (invocation.getQualifier() != null) { // For a qualified super invocation, the statement generator will look // up the IMP using instanceMethodForSelector. if (!method.getReturnType().isPrimitive()) { return typeEnv.resolveIOSType("id"); } else { return null; } } return getDeclaredReturnType( method, TreeUtil.getOwningType(invocation).getTypeBinding().getSuperclass()); } default: return null; } }
/** * Returns true if the specified binding is of an annotation that has a runtime retention policy. */ public static boolean isRuntimeAnnotation(ITypeBinding binding) { if (binding != null && binding.isAnnotation()) { for (IAnnotationBinding ann : binding.getAnnotations()) { if (ann.getName().equals("Retention")) { IVariableBinding retentionBinding = (IVariableBinding) ann.getDeclaredMemberValuePairs()[0].getValue(); return retentionBinding.getName().equals(RetentionPolicy.RUNTIME.name()); } } if (binding.isNested()) { return BindingUtil.isRuntimeAnnotation(binding.getDeclaringClass()); } } return false; }
public void applyRemoves(ImportRewrite importRewrite) { IBinding[] bindings = getImportsToRemove(); for (int i = 0; i < bindings.length; i++) { if (bindings[i] instanceof ITypeBinding) { ITypeBinding typeBinding = (ITypeBinding) bindings[i]; importRewrite.removeImport(typeBinding.getTypeDeclaration().getQualifiedName()); } else if (bindings[i] instanceof IMethodBinding) { IMethodBinding binding = (IMethodBinding) bindings[i]; importRewrite.removeStaticImport( binding.getDeclaringClass().getQualifiedName() + '.' + binding.getName()); } else if (bindings[i] instanceof IVariableBinding) { IVariableBinding binding = (IVariableBinding) bindings[i]; importRewrite.removeStaticImport( binding.getDeclaringClass().getQualifiedName() + '.' + binding.getName()); } } }
private void possibleStaticImportFound(Name name) { if (fStaticImports == null || fASTRoot == null) { return; } while (name.isQualifiedName()) { name = ((QualifiedName) name).getQualifier(); } if (!isAffected(name)) { return; } IBinding binding = name.resolveBinding(); SimpleName simpleName = (SimpleName) name; if (binding == null || binding instanceof ITypeBinding || !Modifier.isStatic(binding.getModifiers()) || simpleName.isDeclaration()) { return; } if (binding instanceof IVariableBinding) { IVariableBinding varBinding = (IVariableBinding) binding; if (varBinding.isField()) { varBinding = varBinding.getVariableDeclaration(); ITypeBinding declaringClass = varBinding.getDeclaringClass(); if (declaringClass != null && !declaringClass.isLocal()) { if (new ScopeAnalyzer(fASTRoot) .isDeclaredInScope( varBinding, simpleName, ScopeAnalyzer.VARIABLES | ScopeAnalyzer.CHECK_VISIBILITY)) return; fStaticImports.add(simpleName); } } } else if (binding instanceof IMethodBinding) { IMethodBinding methodBinding = ((IMethodBinding) binding).getMethodDeclaration(); ITypeBinding declaringClass = methodBinding.getDeclaringClass(); if (declaringClass != null && !declaringClass.isLocal()) { if (new ScopeAnalyzer(fASTRoot) .isDeclaredInScope( methodBinding, simpleName, ScopeAnalyzer.METHODS | ScopeAnalyzer.CHECK_VISIBILITY)) return; fStaticImports.add(simpleName); } } }
private List<Statement> getFieldAdjustments(TypeDeclaration node) { List<Statement> adjustments = Lists.newArrayList(); for (VariableDeclarationFragment decl : TreeUtil.getAllFields(node)) { IVariableBinding var = decl.getVariableBinding(); if (BindingUtil.isStatic(var) || var.getType().isPrimitive()) { continue; } boolean isWeak = BindingUtil.isWeakReference(var); boolean isVolatile = BindingUtil.isVolatile(var); if (isWeak && !isVolatile) { adjustments.add(createReleaseStatement(var)); } else if (!isWeak && isVolatile) { adjustments.add(createVolatileRetainStatement(var)); } } return adjustments; }
@Override public void endVisit(SimpleName node) { IBinding binding = node.resolveBinding(); if (binding instanceof IVariableBinding) { IVariableBinding vbinding = (IVariableBinding) binding; IJavaElement element = vbinding.getJavaElement(); IVariable variable = null; if (element instanceof ILocalVariable) { variable = new LocalVariable((ILocalVariable) element); } else if (element instanceof IField) { variable = new FieldVariable((IField) element); } if (variable != null) { VMVariableReference variableReference = new VMVariableReference(variable); expressions.push(variableReference); } } }
private boolean testModifier(IVariableBinding curr) { int modifiers = curr.getModifiers(); int staticFinal = Modifier.STATIC | Modifier.FINAL; if ((modifiers & staticFinal) == staticFinal) { return false; } if (Modifier.isStatic(modifiers) && !Modifier.isStatic(fMethodDecl.getModifiers())) { return false; } return true; }
@Override public boolean visit(ClassInstanceCreation node) { ITypeBinding newType = node.getTypeBinding().getTypeDeclaration(); ITypeBinding declaringClass = newType.getDeclaringClass(); if (Modifier.isStatic(newType.getModifiers()) || declaringClass == null) { return true; } GeneratedMethodBinding binding = new GeneratedMethodBinding(node.getMethodBinding().getMethodDeclaration()); node.setMethodBinding(binding); addOuterArg(node, binding, declaringClass); for (IVariableBinding capturedVar : getCapturedVariables(node)) { node.getArguments().add(new SimpleName(capturedVar)); binding.addParameter(capturedVar.getType()); } assert binding.isVarargs() || node.getArguments().size() == binding.getParameterTypes().length; return true; }
private Statement createVolatileRetainStatement(IVariableBinding var) { ITypeBinding idType = typeEnv.resolveIOSType("id"); FunctionInvocation invocation = new FunctionInvocation("JreRetainVolatile", idType, idType, null); invocation .getArguments() .add( new PrefixExpression( typeEnv.getPointerType(var.getType()), PrefixExpression.Operator.ADDRESS_OF, new SimpleName(var))); return new ExpressionStatement(invocation); }
/** List has a toArray() method that uses array types. */ public void testAbstractMethodsAddedWithArrayType() { String source = "import java.util.List; public abstract class Test implements List<Object> { " + "public boolean isEmpty() { return true; } }"; CompilationUnit unit = translateType("Test", source); List<AbstractTypeDeclaration> types = unit.getTypes(); assertEquals(1, types.size()); assertTrue(types.get(0) instanceof TypeDeclaration); TypeDeclaration testType = (TypeDeclaration) types.get(0); List<MethodDeclaration> methods = TreeUtil.getMethodDeclarationsList(testType); assertEquals(26, methods.size()); // verify added methods are abstract, and that existing method wasn't changed for (MethodDeclaration m : methods) { int modifiers = m.getModifiers(); String name = m.getName().getIdentifier(); if (name.equals("isEmpty")) { assertFalse(Modifier.isAbstract(modifiers)); } else if (name.equals(NameTable.FINALIZE_METHOD) || name.equals(NameTable.DEALLOC_METHOD) || name.equals(NameTable.INIT_NAME)) { // it's ok. } else { // it's an added method assertTrue(Modifier.isAbstract(modifiers)); ITypeBinding returnType = m.getReturnType().getTypeBinding(); if (name.equals("toArray")) { assertEquals("IOSObjectArray", returnType.getName()); if (!m.getParameters().isEmpty()) { assertEquals(1, m.getParameters().size()); SingleVariableDeclaration param = m.getParameters().get(0); IVariableBinding paramBinding = param.getVariableBinding(); assertTrue(paramBinding.getType().isArray()); } } } } }
private void handleFieldChecks(Name node, IVariableBinding binding) { // add field access check checks.add(new FieldAccessCheck(file, jdtTypingProvider, bridge(node), binding)); // add assignment check for final fields if (Modifier.isFinal((binding).getModifiers())) { ITypeBinding declClass = binding.getDeclaringClass(); if (declClass != null && declClass.isFromSource()) checks.add(new FieldAssignmentCheck(file, jdtTypingProvider, bridge(node), binding)); } }
// We generate the runtime debug method +memDebugStaticReferences. // This method will return an array of NSNumber containing pointers (casted into unsigned long) // to the objects referenced by a class variable with a strong reference. // It will be useful for debug purpose. // // Arrays returned by -memDebugStaticReferences and -memDebugStaticReferencesNames (see below) // must be the same size. // // In case of a Java enum, valuesVarNameis the name of the array of enum values. private void printStaticReferencesMethod(List<FieldDeclaration> fields, String valuesVarName) { if (Options.memoryDebug()) { if (!Options.useReferenceCounting()) { println("+ (NSArray *)memDebugStaticReferences {"); println(" return nil;"); println("}"); return; } println("+ (NSArray *)memDebugStaticReferences {"); println(" NSMutableArray *result = [NSMutableArray array];"); for (FieldDeclaration f : fields) { if (Modifier.isStatic(f.getModifiers())) { for (VariableDeclarationFragment var : ASTUtil.getFragments(f)) { IVariableBinding binding = Types.getVariableBinding(var); // All non-primitive static variables are strong references. if (!binding.getType().isPrimitive()) { String name = NameTable.getStaticVarQualifiedName(binding); println( String.format( " [result addObject:[JreMemDebugStrongReference " + "strongReferenceWithObject:%s name:@\"%s\"]];", name, name)); } } } } if (valuesVarName != null) { println( String.format( " [result addObject:[JreMemDebugStrongReference " + "strongReferenceWithObject:%s name:@\"enumValues\"]];", valuesVarName)); } println(" return result;"); println("}\n"); } }
private boolean handleFragments(List list, ASTNode declaration) { List toChange = new ArrayList(); for (Iterator iter = list.iterator(); iter.hasNext(); ) { VariableDeclarationFragment fragment = (VariableDeclarationFragment) iter.next(); SimpleName name = fragment.getName(); IBinding resolveBinding = name.resolveBinding(); if (canAddFinal(resolveBinding, declaration)) { IVariableBinding varbinding = (IVariableBinding) resolveBinding; if (varbinding.isField()) { if (fieldCanBeFinal(fragment, varbinding)) toChange.add(fragment); } else { if (!fWrittenVariables.containsKey(resolveBinding)) toChange.add(fragment); } } } if (toChange.size() == 0) return false; ModifierChangeOperation op = new ModifierChangeOperation(declaration, toChange, Modifier.FINAL, Modifier.NONE); fResult.add(op); return false; }
private void printStaticVars(List<FieldDeclaration> fields, boolean isInterface) { boolean hadStaticVar = false; for (FieldDeclaration f : fields) { if (Modifier.isStatic(f.getModifiers()) || isInterface) { for (VariableDeclarationFragment var : ASTUtil.getFragments(f)) { IVariableBinding binding = Types.getVariableBinding(var); if (!BindingUtil.isPrimitiveConstant(binding)) { String name = NameTable.getStaticVarQualifiedName(binding); String objcType = NameTable.getObjCType(binding.getType()); Expression initializer = var.getInitializer(); if (initializer != null) { printf("static %s %s = %s;\n", objcType, name, generateExpression(initializer)); } else { printf("static %s %s;\n", objcType, name); } hadStaticVar = true; } } } } if (hadStaticVar) { newline(); } }