/** * Method to post process returned flags from the {@link * org.eclipse.pde.api.tools.internal.JavadocTagManager} * * @param tag the tag to process * @param element the {@link IJavaElement} the tag will appear on * @return true if the tag should be included in completion proposals, false otherwise */ private boolean acceptTag(IApiJavadocTag tag, IJavaElement element) throws JavaModelException { if (fExistingTags != null) { Boolean fragments = fExistingTags.get(tag.getTagName()); // if the tag has a fragment don't overwrite / propose again if (fragments != null && Boolean.FALSE.equals(fragments)) { return false; } } switch (element.getElementType()) { case IJavaElement.TYPE: { IType type = (IType) element; int flags = type.getFlags(); String tagname = tag.getTagName(); if (Flags.isAbstract(flags)) { return !tagname.equals(JavadocTagManager.TAG_NOINSTANTIATE); } if (Flags.isFinal(flags)) { return !tagname.equals(JavadocTagManager.TAG_NOEXTEND); } break; } case IJavaElement.METHOD: { IMethod method = (IMethod) element; if (Flags.isFinal(method.getFlags()) || Flags.isStatic(method.getFlags())) { return !tag.getTagName().equals(JavadocTagManager.TAG_NOOVERRIDE); } IType type = method.getDeclaringType(); if (type != null && Flags.isFinal(type.getFlags())) { return !tag.getTagName().equals(JavadocTagManager.TAG_NOOVERRIDE); } break; } default: break; } return true; }
/* * (non-Javadoc) * @see * org.eclipse.pde.api.tools.internal.search.AbstractTypeLeakDetector#isProblem * (org.eclipse.pde.api.tools.internal.provisional.model.IReference) */ @Override public boolean isProblem(IReference reference) { if (super.isProblem(reference)) { // check the use restrictions on the API type (can be extended or // not) IApiType type = (IApiType) reference.getMember(); IApiComponent component = type.getApiComponent(); try { if (type.isClass()) { int modifiers = 0; IApiAnnotations annotations = component.getApiDescription().resolveAnnotations(type.getHandle()); if (annotations != null) { // if annotations are null, the reference should not // have been retained // as it indicates a reference from a top level non // public type if (RestrictionModifiers.isExtendRestriction(annotations.getRestrictions())) { // The no extend restriction means only public // members can be seen modifiers = Flags.AccPublic; } else { if (Flags.isFinal(type.getModifiers())) { // if final then only public members can be seen modifiers = Flags.AccPublic; } else { // public and protected members can be seen modifiers = Flags.AccPublic | Flags.AccProtected; } } IApiType nonApiSuper = type.getSuperclass(); // collect all visible methods in non-API types Set<MethodKey> methods = new HashSet<MethodKey>(); while (!isAPIType(nonApiSuper)) { if (hasVisibleField(nonApiSuper, modifiers)) { // a visible field in a non-API type is a // definite leak return true; } gatherVisibleMethods(nonApiSuper, methods, modifiers); nonApiSuper = nonApiSuper.getSuperclass(); } if (methods.size() > 0) { // check if the visible members are part of an API // interface/class List<IApiType> apiTypes = new LinkedList<IApiType>(); apiTypes.add(type); gatherAPISuperTypes(apiTypes, type); for (IApiType t2 : apiTypes) { Set<MethodKey> apiMembers = new HashSet<MethodKey>(); gatherVisibleMethods(t2, apiMembers, modifiers); methods.removeAll(apiMembers); if (methods.size() == 0) { // there are no visible methods left that // are not part of an API type/interface return false; } } if (methods.size() > 0) { // there are visible members that are not part // of an API type/interface return true; } } } } else { // don't process interfaces, enums, annotations return true; } } catch (CoreException ce) { if (ApiPlugin.DEBUG_PROBLEM_DETECTOR) { ApiPlugin.log(ce); } return true; } } return false; }
/** * Method to post process returned flags from the {@link Javadoc} node of the element * * @param tags the tags to process * @param element the {@link ASTNode} the tag appears on * @return the list of valid tags to process restrictions for */ private List pruneTags(final List tags, ASTNode node) { ArrayList pruned = new ArrayList(tags.size()); TagElement tag = null; switch (node.getNodeType()) { case ASTNode.TYPE_DECLARATION: { TypeDeclaration type = (TypeDeclaration) node; int flags = type.getModifiers(); for (Iterator iterator = tags.iterator(); iterator.hasNext(); ) { tag = (TagElement) iterator.next(); String tagname = tag.getTagName(); if (type.isInterface() && ("@noextend".equals(tagname) || //$NON-NLS-1$ "@noimplement".equals(tagname))) { // $NON-NLS-1$ pruned.add(tag); } else { if ("@noextend".equals(tagname)) { // $NON-NLS-1$ if (!Flags.isFinal(flags)) { pruned.add(tag); continue; } } if ("@noinstantiate".equals(tagname)) { // $NON-NLS-1$ if (!Flags.isAbstract(flags)) { pruned.add(tag); continue; } } } } break; } case ASTNode.METHOD_DECLARATION: { MethodDeclaration method = (MethodDeclaration) node; int flags = method.getModifiers(); for (Iterator iterator = tags.iterator(); iterator.hasNext(); ) { tag = (TagElement) iterator.next(); if ("@noreference".equals(tag.getTagName())) { // $NON-NLS-1$ pruned.add(tag); continue; } if ("@nooverride".equals(tag.getTagName())) { // $NON-NLS-1$ ASTNode parent = method.getParent(); int pflags = 0; if (parent instanceof BodyDeclaration) { pflags = ((BodyDeclaration) parent).getModifiers(); } if (!Flags.isFinal(flags) && !Flags.isStatic(flags) && !Flags.isFinal(pflags)) { pruned.add(tag); continue; } } } break; } case ASTNode.FIELD_DECLARATION: { FieldDeclaration field = (FieldDeclaration) node; for (Iterator iterator = tags.iterator(); iterator.hasNext(); ) { tag = (TagElement) iterator.next(); boolean isfinal = Flags.isFinal(field.getModifiers()); if (isfinal || (isfinal && Flags.isStatic(field.getModifiers()))) { break; } if ("@noreference".equals(tag.getTagName())) { // $NON-NLS-1$ pruned.add(tag); break; } } break; } } return pruned; }
/** * Create a stub for a getter of the given field using getter/setter templates. The resulting code * has to be formatted and indented. * * @param field The field to create a getter for * @param getterName The chosen name for the getter * @param addComments If <code>true</code>, comments will be added. * @param flags The flags signaling visibility, if static, synchronized or final * @return Returns the generated stub. * @throws CoreException when stub creation failed */ public static String getGetterStub( IField field, String getterName, boolean addComments, int flags) throws CoreException { String fieldName = field.getElementName(); IType parentType = field.getDeclaringType(); boolean isStatic = Flags.isStatic(flags); boolean isSync = Flags.isSynchronized(flags); boolean isFinal = Flags.isFinal(flags); String typeName = Signature.toString(field.getTypeSignature()); String accessorName = StubUtility.getBaseName(field); String lineDelim = "\n"; // Use default line delimiter, as generated stub has to be formatted anyway // //$NON-NLS-1$ StringBuffer buf = new StringBuffer(); if (addComments) { String comment = CodeGeneration.getGetterComment( field.getCompilationUnit(), parentType.getTypeQualifiedName('.'), getterName, field.getElementName(), typeName, accessorName, lineDelim); if (comment != null) { buf.append(comment); buf.append(lineDelim); } } buf.append(JdtFlags.getVisibilityString(flags)); buf.append(' '); if (isStatic) buf.append("static "); // $NON-NLS-1$ if (isSync) buf.append("synchronized "); // $NON-NLS-1$ if (isFinal) buf.append("final "); // $NON-NLS-1$ buf.append(typeName); buf.append(' '); buf.append(getterName); buf.append("() {"); // $NON-NLS-1$ buf.append(lineDelim); boolean useThis = StubUtility.useThisForFieldAccess(field.getJavaProject()); if (useThis && !isStatic) { fieldName = "this." + fieldName; // $NON-NLS-1$ } String body = CodeGeneration.getGetterMethodBodyContent( field.getCompilationUnit(), parentType.getTypeQualifiedName('.'), getterName, fieldName, lineDelim); if (body != null) { buf.append(body); } buf.append("}"); // $NON-NLS-1$ buf.append(lineDelim); return buf.toString(); }
private boolean isCacheableLHS(IType type, String qualifiedName) throws JavaModelException { return !Flags.isFinal(type.getFlags()) && !UNCACHEABLE.contains(qualifiedName); }