/******************************************************************************* * Copyright (c) 2000, 2008 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ package org.eclipse.che.ide.ext.java.jdt.internal.corext.util; import org.eclipse.che.ide.ext.java.jdt.core.Flags; import org.eclipse.che.ide.ext.java.jdt.core.dom.AnnotationTypeDeclaration; import org.eclipse.che.ide.ext.java.jdt.core.dom.BodyDeclaration; import org.eclipse.che.ide.ext.java.jdt.core.dom.IBinding; import org.eclipse.che.ide.ext.java.jdt.core.dom.IMethodBinding; import org.eclipse.che.ide.ext.java.jdt.core.dom.ITypeBinding; import org.eclipse.che.ide.ext.java.jdt.core.dom.IVariableBinding; import org.eclipse.che.ide.ext.java.jdt.core.dom.Modifier; import org.eclipse.che.ide.ext.java.jdt.core.dom.TypeDeclaration; import org.eclipse.che.ide.runtime.Assert; /** * The methods of this utility class are implemented from a Java language model * point of view. They do not only take the declared flags from the source into account * but also the implicit properties as defined in the Java Language Specification, version 3 (JLS3). */ public class JdtFlags { private JdtFlags() { } public static final String VISIBILITY_STRING_PRIVATE = "private"; //$NON-NLS-1$ public static final String VISIBILITY_STRING_PACKAGE = ""; //$NON-NLS-1$ public static final String VISIBILITY_STRING_PROTECTED = "protected"; //$NON-NLS-1$ public static final String VISIBILITY_STRING_PUBLIC = "public"; //$NON-NLS-1$ public static final int VISIBILITY_CODE_INVALID = -1; public static boolean isAbstract(IMethodBinding member) { if (isInterfaceOrAnnotationMember(member)) return true; return Modifier.isAbstract(member.getModifiers()); } public static boolean isEnum(IBinding member) { return Flags.isEnum(member.getModifiers()); } public static boolean isPackageVisible(BodyDeclaration bodyDeclaration) { return (!isPrivate(bodyDeclaration) && !isProtected(bodyDeclaration) && !isPublic(bodyDeclaration)); } public static boolean isPackageVisible(IBinding binding) { return (!isPrivate(binding) && !isProtected(binding) && !isPublic(binding)); } public static boolean isPrivate(BodyDeclaration bodyDeclaration) { return Modifier.isPrivate(bodyDeclaration.getModifiers()); } public static boolean isPrivate(IBinding binding) { return Modifier.isPrivate(binding.getModifiers()); } public static boolean isProtected(BodyDeclaration bodyDeclaration) { return Modifier.isProtected(bodyDeclaration.getModifiers()); } public static boolean isProtected(IBinding binding) { return Modifier.isProtected(binding.getModifiers()); } public static boolean isPublic(IBinding binding) { if (isInterfaceOrAnnotationMember(binding)) return true; return Modifier.isPublic(binding.getModifiers()); } public static boolean isFinal(IBinding member) { if (isInterfaceOrAnnotationField(member)) return true; if (isAnonymousType(member)) return true; if (isEnumConstant(member)) return true; return Flags.isFinal(member.getModifiers()); } private static boolean isInterfaceOrAnnotationField(IBinding member) { return member.getKind() == IBinding.VARIABLE && isInterfaceOrAnnotationMember(member); } private static boolean isAnonymousType(IBinding member) { return member.getKind() == IBinding.TYPE && ((ITypeBinding)member).isAnonymous(); } private static boolean isEnumConstant(IBinding member) { return member.getKind() == IBinding.VARIABLE && isEnum(member); } public static boolean isPublic(BodyDeclaration bodyDeclaration) { if (isInterfaceOrAnnotationMember(bodyDeclaration)) return true; return Modifier.isPublic(bodyDeclaration.getModifiers()); } public static boolean isStatic(IMethodBinding methodBinding) { return Modifier.isStatic(methodBinding.getModifiers()); } public static boolean isStatic(IVariableBinding variableBinding) { if (isInterfaceOrAnnotationMember(variableBinding)) return true; return Modifier.isStatic(variableBinding.getModifiers()); } private static boolean isInterfaceOrAnnotationMember(IBinding binding) { ITypeBinding declaringType = null; if (binding instanceof IVariableBinding) { declaringType = ((IVariableBinding)binding).getDeclaringClass(); } else if (binding instanceof IMethodBinding) { declaringType = ((IMethodBinding)binding).getDeclaringClass(); } else if (binding instanceof ITypeBinding) { declaringType = ((ITypeBinding)binding).getDeclaringClass(); } return declaringType != null && (declaringType.isInterface() || declaringType.isAnnotation()); } private static boolean isInterfaceOrAnnotationMember(BodyDeclaration bodyDeclaration) { boolean isInterface = (bodyDeclaration.getParent() instanceof TypeDeclaration) && ((TypeDeclaration)bodyDeclaration.getParent()).isInterface(); boolean isAnnotation = bodyDeclaration.getParent() instanceof AnnotationTypeDeclaration; return isInterface || isAnnotation; } public static int getVisibilityCode(BodyDeclaration bodyDeclaration) { if (isPublic(bodyDeclaration)) return Modifier.PUBLIC; else if (isProtected(bodyDeclaration)) return Modifier.PROTECTED; else if (isPackageVisible(bodyDeclaration)) return Modifier.NONE; else if (isPrivate(bodyDeclaration)) return Modifier.PRIVATE; Assert.isTrue(false); return VISIBILITY_CODE_INVALID; } public static int getVisibilityCode(IBinding binding) { if (isPublic(binding)) return Modifier.PUBLIC; else if (isProtected(binding)) return Modifier.PROTECTED; else if (isPackageVisible(binding)) return Modifier.NONE; else if (isPrivate(binding)) return Modifier.PRIVATE; Assert.isTrue(false); return VISIBILITY_CODE_INVALID; } public static String getVisibilityString(int visibilityCode) { if (Modifier.isPublic(visibilityCode)) return VISIBILITY_STRING_PUBLIC; if (Modifier.isProtected(visibilityCode)) return VISIBILITY_STRING_PROTECTED; if (Modifier.isPrivate(visibilityCode)) return VISIBILITY_STRING_PRIVATE; return VISIBILITY_STRING_PACKAGE; } public static int getVisibilityCode(String visibilityString) { Assert.isNotNull(visibilityString); if (VISIBILITY_STRING_PACKAGE.equals(visibilityString)) return 0; else if (VISIBILITY_STRING_PRIVATE.equals(visibilityString)) return Modifier.PRIVATE; else if (VISIBILITY_STRING_PROTECTED.equals(visibilityString)) return Modifier.PROTECTED; else if (VISIBILITY_STRING_PUBLIC.equals(visibilityString)) return Modifier.PUBLIC; return VISIBILITY_CODE_INVALID; } public static void assertVisibility(int visibility) { Assert.isTrue(visibility == Modifier.PUBLIC || visibility == Modifier.PROTECTED || visibility == Modifier.NONE || visibility == Modifier.PRIVATE); } /** * Compares two visibilities. * * @param newVisibility * the 'new' visibility * @param oldVisibility * the 'old' visibility * @return <code>true</code> iff the 'new' visibility is strictly higher than the old visibility * @see Modifier#PUBLIC * @see Modifier#PROTECTED * @see Modifier#NONE * @see Modifier#PRIVATE */ public static boolean isHigherVisibility(int newVisibility, int oldVisibility) { assertVisibility(oldVisibility); assertVisibility(newVisibility); switch (oldVisibility) { case Modifier.PRIVATE: return newVisibility == Modifier.NONE || newVisibility == Modifier.PUBLIC || newVisibility == Modifier.PROTECTED; case Modifier.NONE: return newVisibility == Modifier.PUBLIC || newVisibility == Modifier.PROTECTED; case Modifier.PROTECTED: return newVisibility == Modifier.PUBLIC; case Modifier.PUBLIC: return false; default: Assert.isTrue(false); return false; } } public static int getLowerVisibility(int visibility1, int visibility2) { if (isHigherVisibility(visibility1, visibility2)) return visibility2; else return visibility1; } public static int clearAccessModifiers(int flags) { return clearFlag(Modifier.PROTECTED | Modifier.PUBLIC | Modifier.PRIVATE, flags); } public static int clearFlag(int flag, int flags) { return flags & ~flag; } }